static void send_with_socket(RADIUS_PACKET *request) { request->sockfd = sockfd; if (fr_dhcp_send(request) < 0) { fprintf(stderr, "dhcpclient: failed sending: %s\n", fr_syserror(errno)); fr_exit_now(1); } if (!reply_expected) return; reply = fr_dhcp_recv(sockfd); if (!reply) { fprintf(stderr, "dhcpclient: Error receiving reply: %s\n", fr_strerror()); fr_exit_now(1); } if (fr_debug_lvl) print_hex(reply); if (fr_dhcp_decode(reply) < 0) { fprintf(stderr, "dhcpclient: failed decoding\n"); fr_exit_now(1); } }
int main(int argc, char **argv) { char *p; int c; char const *radius_dir = RADDBDIR; char const *filename = NULL; fr_debug_flag = 0; while ((c = getopt(argc, argv, "d:f:hr:t:vx")) != EOF) switch(c) { case 'd': radius_dir = optarg; break; case 'f': filename = optarg; break; case 'r': if (!isdigit((int) *optarg)) usage(); retries = atoi(optarg); if ((retries == 0) || (retries > 1000)) usage(); break; case 't': if (!isdigit((int) *optarg)) usage(); timeout = atof(optarg); break; case 'v': printf("%s\n", dhcpclient_version); exit(0); break; case 'x': fr_debug_flag++; fr_log_fp = stdout; break; case 'h': default: usage(); break; } argc -= (optind - 1); argv += (optind - 1); if (argc < 2) usage(); if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) { fr_perror("dhcpclient"); return 1; } /* * Resolve hostname. */ server_ipaddr.af = AF_INET; if (strcmp(argv[1], "-") != 0) { char const *hostname = argv[1]; char const *portname = argv[1]; char buffer[256]; if (*argv[1] == '[') { /* IPv6 URL encoded */ p = strchr(argv[1], ']'); if ((size_t) (p - argv[1]) >= sizeof(buffer)) { usage(); } memcpy(buffer, argv[1] + 1, p - argv[1] - 1); buffer[p - argv[1] - 1] = '\0'; hostname = buffer; portname = p + 1; } p = strchr(portname, ':'); if (p && (strchr(p + 1, ':') == NULL)) { *p = '\0'; portname = p + 1; } else { portname = NULL; } if (ip_hton(hostname, AF_INET, &server_ipaddr) < 0) { fprintf(stderr, "dhcpclient: Failed to find IP address for host %s: %s\n", hostname, fr_syserror(errno)); exit(1); } /* * Strip port from hostname if needed. */ if (portname) server_port = atoi(portname); } /* * See what kind of request we want to send. */ if (strcmp(argv[2], "discover") == 0) { if (server_port == 0) server_port = 67; packet_code = PW_DHCP_DISCOVER; } else if (strcmp(argv[2], "request") == 0) { if (server_port == 0) server_port = 67; packet_code = PW_DHCP_REQUEST; } else if (strcmp(argv[2], "offer") == 0) { if (server_port == 0) server_port = 67; packet_code = PW_DHCP_OFFER; } else if (isdigit((int) argv[2][0])) { if (server_port == 0) server_port = 67; packet_code = atoi(argv[2]); } else { fprintf(stderr, "Unknown packet type %s\n", argv[2]); usage(); } request_init(filename); /* * No data read. Die. */ if (!request || !request->vps) { fprintf(stderr, "dhcpclient: Nothing to send.\n"); exit(1); } request->code = packet_code; /* * Bind to the first specified IP address and port. * This means we ignore later ones. */ if (request->src_ipaddr.af == AF_UNSPEC) { memset(&client_ipaddr, 0, sizeof(client_ipaddr)); client_ipaddr.af = server_ipaddr.af; client_port = 0; } else { client_ipaddr = request->src_ipaddr; client_port = request->src_port; } sockfd = fr_socket(&client_ipaddr, client_port); if (sockfd < 0) { fprintf(stderr, "dhcpclient: socket: %s\n", fr_strerror()); exit(1); } request->sockfd = sockfd; if (request->src_ipaddr.af == AF_UNSPEC) { request->src_ipaddr = client_ipaddr; request->src_port = client_port; } if (request->dst_ipaddr.af == AF_UNSPEC) { request->dst_ipaddr = server_ipaddr; request->dst_port = server_port; } /* * Encode the packet */ if (fr_dhcp_encode(request) < 0) { fprintf(stderr, "dhcpclient: failed encoding: %s\n", fr_strerror()); exit(1); } if (fr_debug_flag) print_hex(request); if (fr_dhcp_send(request) < 0) { fprintf(stderr, "dhcpclient: failed sending: %s\n", fr_syserror(errno)); exit(1); } reply = fr_dhcp_recv(sockfd); if (!reply) { fprintf(stderr, "dhcpclient: no reply\n"); exit(1); } if (fr_debug_flag) print_hex(reply); if (fr_dhcp_decode(reply) < 0) { fprintf(stderr, "dhcpclient: failed decoding\n"); return 1; } dict_free(); if (success) return 0; return 1; }