summaryrefslogtreecommitdiffstats
path: root/plugins-root/check_dhcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins-root/check_dhcp.c')
-rw-r--r--plugins-root/check_dhcp.c258
1 files changed, 163 insertions, 95 deletions
diff --git a/plugins-root/check_dhcp.c b/plugins-root/check_dhcp.c
index daed9cb0..9a96547f 100644
--- a/plugins-root/check_dhcp.c
+++ b/plugins-root/check_dhcp.c
@@ -127,17 +127,17 @@ static long mac_addr_dlpi(const char *, int, u_char *);
127#define MAX_DHCP_OPTIONS_LENGTH 312 127#define MAX_DHCP_OPTIONS_LENGTH 312
128 128
129typedef struct dhcp_packet_struct { 129typedef struct dhcp_packet_struct {
130 uint8_t op; /* packet type */ 130 uint8_t op; /* packet type */
131 uint8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ 131 uint8_t htype; /* type of hardware address for this machine (Ethernet, etc) */
132 uint8_t hlen; /* length of hardware address (of this machine) */ 132 uint8_t hlen; /* length of hardware address (of this machine) */
133 uint8_t hops; /* hops */ 133 uint8_t hops; /* hops */
134 uint32_t xid; /* random transaction id number - chosen by this machine */ 134 uint32_t xid; /* random transaction id number - chosen by this machine */
135 uint16_t secs; /* seconds used in timing */ 135 uint16_t secs; /* seconds used in timing */
136 uint16_t flags; /* flags */ 136 uint16_t flags; /* flags */
137 struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ 137 struct in_addr ciaddr; /* IP address of this machine (if we already have one) */
138 struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ 138 struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */
139 struct in_addr siaddr; /* IP address of next server */ 139 struct in_addr siaddr; /* IP address of next server */
140 struct in_addr giaddr; /* IP address of DHCP relay */ 140 struct in_addr giaddr; /* IP address of DHCP relay */
141 unsigned char chaddr[MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ 141 unsigned char chaddr[MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */
142 char sname[MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ 142 char sname[MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */
143 char file[MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ 143 char file[MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */
@@ -199,7 +199,8 @@ static void print_help(void);
199static void resolve_host(const char * /*in*/, struct in_addr * /*out*/); 199static void resolve_host(const char * /*in*/, struct in_addr * /*out*/);
200static unsigned char *mac_aton(const char * /*string*/); 200static unsigned char *mac_aton(const char * /*string*/);
201static void print_hardware_address(const unsigned char * /*address*/); 201static void print_hardware_address(const unsigned char * /*address*/);
202static int get_hardware_address(int /*sock*/, char * /*interface_name*/, unsigned char *client_hardware_address); 202static int get_hardware_address(int /*sock*/, char * /*interface_name*/,
203 unsigned char *client_hardware_address);
203 204
204typedef struct get_ip_address_wrapper { 205typedef struct get_ip_address_wrapper {
205 int error; 206 int error;
@@ -211,32 +212,40 @@ typedef struct send_dhcp_discover_wrapper {
211 int error; 212 int error;
212 uint32_t packet_xid; 213 uint32_t packet_xid;
213} send_dhcp_discover_wrapper; 214} send_dhcp_discover_wrapper;
214static send_dhcp_discover_wrapper send_dhcp_discover(int socket, bool unicast, struct in_addr dhcp_ip, struct in_addr requested_address, 215static send_dhcp_discover_wrapper
215 bool request_specific_address, struct in_addr my_ip, 216send_dhcp_discover(int socket, bool unicast, struct in_addr dhcp_ip,
216 unsigned char *client_hardware_address); 217 struct in_addr requested_address, bool request_specific_address,
218 struct in_addr my_ip, unsigned char *client_hardware_address);
217typedef struct get_dhcp_offer_wrapper { 219typedef struct get_dhcp_offer_wrapper {
218 int error; 220 int error;
219 int valid_responses; 221 int valid_responses;
220 dhcp_offer *dhcp_offer_list; 222 dhcp_offer *dhcp_offer_list;
221} get_dhcp_offer_wrapper; 223} get_dhcp_offer_wrapper;
222static get_dhcp_offer_wrapper get_dhcp_offer(int /*sock*/, int dhcpoffer_timeout, uint32_t packet_xid, dhcp_offer *dhcp_offer_list, 224static get_dhcp_offer_wrapper get_dhcp_offer(int /*sock*/, int dhcpoffer_timeout,
225 uint32_t packet_xid, dhcp_offer *dhcp_offer_list,
223 const unsigned char *client_hardware_address); 226 const unsigned char *client_hardware_address);
224 227
225static mp_subcheck get_results(bool exclusive, int requested_servers, struct in_addr requested_address, bool request_specific_address, 228static mp_subcheck get_results(bool exclusive, int requested_servers,
226 requested_server *requested_server_list, int valid_responses, dhcp_offer *dhcp_offer_list); 229 struct in_addr requested_address, bool request_specific_address,
230 requested_server *requested_server_list, int valid_responses,
231 dhcp_offer *dhcp_offer_list);
227 232
228typedef struct add_dhcp_offer_wrapper { 233typedef struct add_dhcp_offer_wrapper {
229 int error; 234 int error;
230 dhcp_offer *dhcp_offer_list; 235 dhcp_offer *dhcp_offer_list;
231} add_dhcp_offer_wrapper; 236} add_dhcp_offer_wrapper;
232static add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr /*source*/, dhcp_packet * /*offer_packet*/, dhcp_offer *dhcp_offer_list); 237static add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr /*source*/,
238 dhcp_packet * /*offer_packet*/,
239 dhcp_offer *dhcp_offer_list);
233static int free_dhcp_offer_list(dhcp_offer *dhcp_offer_list); 240static int free_dhcp_offer_list(dhcp_offer *dhcp_offer_list);
234static int free_requested_server_list(requested_server *requested_server_list); 241static int free_requested_server_list(requested_server *requested_server_list);
235 242
236static int create_dhcp_socket(bool /*unicast*/, char *network_interface_name); 243static int create_dhcp_socket(bool /*unicast*/, char *network_interface_name);
237static int close_dhcp_socket(int /*sock*/); 244static int close_dhcp_socket(int /*sock*/);
238static int send_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/, struct sockaddr_in * /*dest*/); 245static int send_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/,
239static int receive_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/, int /*timeout*/, struct sockaddr_in * /*address*/); 246 struct sockaddr_in * /*dest*/);
247static int receive_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/,
248 int /*timeout*/, struct sockaddr_in * /*address*/);
240 249
241int main(int argc, char **argv) { 250int main(int argc, char **argv) {
242 setlocale(LC_ALL, ""); 251 setlocale(LC_ALL, "");
@@ -271,7 +280,8 @@ int main(int argc, char **argv) {
271 struct in_addr my_ip = {0}; 280 struct in_addr my_ip = {0};
272 281
273 if (config.unicast_mode) { /* get IP address of client machine */ 282 if (config.unicast_mode) { /* get IP address of client machine */
274 get_ip_address_wrapper tmp_get_ip = get_ip_address(dhcp_socket, config.network_interface_name); 283 get_ip_address_wrapper tmp_get_ip =
284 get_ip_address(dhcp_socket, config.network_interface_name);
275 if (tmp_get_ip.error == OK) { 285 if (tmp_get_ip.error == OK) {
276 my_ip = tmp_get_ip.my_ip; 286 my_ip = tmp_get_ip.my_ip;
277 } else { 287 } else {
@@ -281,8 +291,9 @@ int main(int argc, char **argv) {
281 } 291 }
282 292
283 /* send DHCPDISCOVER packet */ 293 /* send DHCPDISCOVER packet */
284 send_dhcp_discover_wrapper disco_res = send_dhcp_discover(dhcp_socket, config.unicast_mode, config.dhcp_ip, config.requested_address, 294 send_dhcp_discover_wrapper disco_res = send_dhcp_discover(
285 config.request_specific_address, my_ip, client_hardware_address); 295 dhcp_socket, config.unicast_mode, config.dhcp_ip, config.requested_address,
296 config.request_specific_address, my_ip, client_hardware_address);
286 297
287 if (disco_res.error != OK) { 298 if (disco_res.error != OK) {
288 // DO something? 299 // DO something?
@@ -290,8 +301,8 @@ int main(int argc, char **argv) {
290 } 301 }
291 302
292 /* wait for a DHCPOFFER packet */ 303 /* wait for a DHCPOFFER packet */
293 get_dhcp_offer_wrapper offer_res = 304 get_dhcp_offer_wrapper offer_res = get_dhcp_offer(
294 get_dhcp_offer(dhcp_socket, config.dhcpoffer_timeout, disco_res.packet_xid, NULL, client_hardware_address); 305 dhcp_socket, config.dhcpoffer_timeout, disco_res.packet_xid, NULL, client_hardware_address);
295 306
296 int valid_responses = 0; 307 int valid_responses = 0;
297 dhcp_offer *dhcp_offer_list = NULL; 308 dhcp_offer *dhcp_offer_list = NULL;
@@ -308,8 +319,10 @@ int main(int argc, char **argv) {
308 mp_check overall = mp_check_init(); 319 mp_check overall = mp_check_init();
309 320
310 /* determine state/plugin output to return */ 321 /* determine state/plugin output to return */
311 mp_subcheck sc_res = get_results(config.exclusive_mode, config.num_of_requested_servers, config.requested_address, 322 mp_subcheck sc_res =
312 config.request_specific_address, config.requested_server_list, valid_responses, dhcp_offer_list); 323 get_results(config.exclusive_mode, config.num_of_requested_servers,
324 config.requested_address, config.request_specific_address,
325 config.requested_server_list, valid_responses, dhcp_offer_list);
313 mp_add_subcheck_to_check(&overall, sc_res); 326 mp_add_subcheck_to_check(&overall, sc_res);
314 /* free allocated memory */ 327 /* free allocated memory */
315 free_dhcp_offer_list(dhcp_offer_list); 328 free_dhcp_offer_list(dhcp_offer_list);
@@ -357,17 +370,20 @@ int get_hardware_address(int sock, char *interface_name, unsigned char *client_h
357 } 370 }
358 371
359 if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { 372 if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
360 printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno)); 373 printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"),
374 interface_name, strerror(errno));
361 exit(STATE_UNKNOWN); 375 exit(STATE_UNKNOWN);
362 } 376 }
363 377
364 if ((buf = malloc(len)) == NULL) { 378 if ((buf = malloc(len)) == NULL) {
365 printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno)); 379 printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"),
380 interface_name, strerror(errno));
366 exit(4); 381 exit(4);
367 } 382 }
368 383
369 if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { 384 if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
370 printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno)); 385 printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"),
386 interface_name, strerror(errno));
371 exit(STATE_UNKNOWN); 387 exit(STATE_UNKNOWN);
372 } 388 }
373 389
@@ -398,12 +414,16 @@ int get_hardware_address(int sock, char *interface_name, unsigned char *client_h
398 unit = atoi(p); 414 unit = atoi(p);
399 strncat(dev, interface_name, 6); 415 strncat(dev, interface_name, 6);
400 } else { 416 } else {
401 printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name); 417 printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg "
418 "lnc0.\n"),
419 interface_name);
402 exit(STATE_UNKNOWN); 420 exit(STATE_UNKNOWN);
403 } 421 }
404 stat = mac_addr_dlpi(dev, unit, client_hardware_address); 422 stat = mac_addr_dlpi(dev, unit, client_hardware_address);
405 if (stat != 0) { 423 if (stat != 0) {
406 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); 424 printf(
425 _("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"),
426 dev, unit);
407 exit(STATE_UNKNOWN); 427 exit(STATE_UNKNOWN);
408 } 428 }
409 429
@@ -415,7 +435,9 @@ int get_hardware_address(int sock, char *interface_name, unsigned char *client_h
415 435
416 stat = mac_addr_dlpi(dev, unit, client_hardware_address); 436 stat = mac_addr_dlpi(dev, unit, client_hardware_address);
417 if (stat != 0) { 437 if (stat != 0) {
418 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); 438 printf(
439 _("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"),
440 dev, unit);
419 exit(STATE_UNKNOWN); 441 exit(STATE_UNKNOWN);
420 } 442 }
421 /* Kompf 2000-2003 */ 443 /* Kompf 2000-2003 */
@@ -463,8 +485,10 @@ get_ip_address_wrapper get_ip_address(int sock, char *interface_name) {
463} 485}
464 486
465/* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ 487/* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */
466static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, struct in_addr dhcp_ip, struct in_addr requested_address, 488static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, struct in_addr dhcp_ip,
467 bool request_specific_address, struct in_addr my_ip, 489 struct in_addr requested_address,
490 bool request_specific_address,
491 struct in_addr my_ip,
468 unsigned char *client_hardware_address) { 492 unsigned char *client_hardware_address) {
469 dhcp_packet discover_packet = {0}; 493 dhcp_packet discover_packet = {0};
470 /* boot request flag (backward compatible with BOOTP servers) */ 494 /* boot request flag (backward compatible with BOOTP servers) */
@@ -506,8 +530,9 @@ static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, str
506 530
507 unsigned short opts = 4; 531 unsigned short opts = 4;
508 /* DHCP message type is embedded in options field */ 532 /* DHCP message type is embedded in options field */
509 discover_packet.options[opts++] = DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ 533 discover_packet.options[opts++] =
510 discover_packet.options[opts++] = '\x01'; /* DHCP message option length in bytes */ 534 DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */
535 discover_packet.options[opts++] = '\x01'; /* DHCP message option length in bytes */
511 discover_packet.options[opts++] = DHCPDISCOVER; 536 discover_packet.options[opts++] = DHCPDISCOVER;
512 537
513 /* the IP address we're requesting */ 538 /* the IP address we're requesting */
@@ -535,8 +560,10 @@ static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, str
535 }; 560 };
536 561
537 if (verbose) { 562 if (verbose) {
538 printf(_("DHCPDISCOVER to %s port %d\n"), inet_ntoa(sockaddr_broadcast.sin_addr), ntohs(sockaddr_broadcast.sin_port)); 563 printf(_("DHCPDISCOVER to %s port %d\n"), inet_ntoa(sockaddr_broadcast.sin_addr),
539 printf("DHCPDISCOVER XID: %u (0x%X)\n", ntohl(discover_packet.xid), ntohl(discover_packet.xid)); 564 ntohs(sockaddr_broadcast.sin_port));
565 printf("DHCPDISCOVER XID: %u (0x%X)\n", ntohl(discover_packet.xid),
566 ntohl(discover_packet.xid));
540 printf("DHCDISCOVER ciaddr: %s\n", inet_ntoa(discover_packet.ciaddr)); 567 printf("DHCDISCOVER ciaddr: %s\n", inet_ntoa(discover_packet.ciaddr));
541 printf("DHCDISCOVER yiaddr: %s\n", inet_ntoa(discover_packet.yiaddr)); 568 printf("DHCDISCOVER yiaddr: %s\n", inet_ntoa(discover_packet.yiaddr));
542 printf("DHCDISCOVER siaddr: %s\n", inet_ntoa(discover_packet.siaddr)); 569 printf("DHCDISCOVER siaddr: %s\n", inet_ntoa(discover_packet.siaddr));
@@ -554,7 +581,8 @@ static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, str
554} 581}
555 582
556/* waits for a DHCPOFFER message from one or more DHCP servers */ 583/* waits for a DHCPOFFER message from one or more DHCP servers */
557get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t packet_xid, dhcp_offer *dhcp_offer_list, 584get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t packet_xid,
585 dhcp_offer *dhcp_offer_list,
558 const unsigned char *client_hardware_address) { 586 const unsigned char *client_hardware_address) {
559 time_t start_time; 587 time_t start_time;
560 time(&start_time); 588 time(&start_time);
@@ -578,7 +606,8 @@ get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t
578 dhcp_packet offer_packet = {0}; 606 dhcp_packet offer_packet = {0};
579 607
580 result = OK; 608 result = OK;
581 result = receive_dhcp_packet(&offer_packet, sizeof(offer_packet), sock, dhcpoffer_timeout, &source); 609 result = receive_dhcp_packet(&offer_packet, sizeof(offer_packet), sock, dhcpoffer_timeout,
610 &source);
582 611
583 if (result != OK) { 612 if (result != OK) {
584 if (verbose) { 613 if (verbose) {
@@ -607,8 +636,9 @@ get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t
607 /* check packet xid to see if its the same as the one we used in the discover packet */ 636 /* check packet xid to see if its the same as the one we used in the discover packet */
608 if (ntohl(offer_packet.xid) != packet_xid) { 637 if (ntohl(offer_packet.xid) != packet_xid) {
609 if (verbose) { 638 if (verbose) {
610 printf(_("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"), ntohl(offer_packet.xid), 639 printf(
611 packet_xid); 640 _("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"),
641 ntohl(offer_packet.xid), packet_xid);
612 } 642 }
613 643
614 continue; 644 continue;
@@ -648,7 +678,8 @@ get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t
648 printf("DHCPOFFER giaddr: %s\n", inet_ntoa(offer_packet.giaddr)); 678 printf("DHCPOFFER giaddr: %s\n", inet_ntoa(offer_packet.giaddr));
649 } 679 }
650 680
651 add_dhcp_offer_wrapper add_res = add_dhcp_offer(source.sin_addr, &offer_packet, dhcp_offer_list); 681 add_dhcp_offer_wrapper add_res =
682 add_dhcp_offer(source.sin_addr, &offer_packet, dhcp_offer_list);
652 if (add_res.error != OK) { 683 if (add_res.error != OK) {
653 // TODO 684 // TODO
654 } else { 685 } else {
@@ -673,7 +704,8 @@ get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t
673 704
674/* sends a DHCP packet */ 705/* sends a DHCP packet */
675int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest) { 706int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest) {
676 int result = sendto(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)dest, sizeof(*dest)); 707 int result =
708 sendto(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)dest, sizeof(*dest));
677 709
678 if (verbose) { 710 if (verbose) {
679 printf(_("send_dhcp_packet result: %d\n"), result); 711 printf(_("send_dhcp_packet result: %d\n"), result);
@@ -687,7 +719,8 @@ int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in
687} 719}
688 720
689/* receives a DHCP packet */ 721/* receives a DHCP packet */
690int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address) { 722int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout,
723 struct sockaddr_in *address) {
691 /* wait for data to arrive (up time timeout) */ 724 /* wait for data to arrive (up time timeout) */
692 struct timeval timeout_val = { 725 struct timeval timeout_val = {
693 .tv_sec = timeout, 726 .tv_sec = timeout,
@@ -711,7 +744,8 @@ int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, st
711 744
712 struct sockaddr_in source_address = {0}; 745 struct sockaddr_in source_address = {0};
713 socklen_t address_size = sizeof(source_address); 746 socklen_t address_size = sizeof(source_address);
714 int recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)&source_address, &address_size); 747 int recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0,
748 (struct sockaddr *)&source_address, &address_size);
715 if (verbose) { 749 if (verbose) {
716 printf("recv_result: %d\n", recv_result); 750 printf("recv_result: %d\n", recv_result);
717 } 751 }
@@ -775,7 +809,8 @@ int create_dhcp_socket(bool unicast, char *network_interface_name) {
775 strncpy(interface.ifr_ifrn.ifrn_name, network_interface_name, IFNAMSIZ - 1); 809 strncpy(interface.ifr_ifrn.ifrn_name, network_interface_name, IFNAMSIZ - 1);
776 interface.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = '\0'; 810 interface.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = '\0';
777 if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { 811 if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) {
778 printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"), network_interface_name); 812 printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"),
813 network_interface_name);
779 exit(STATE_UNKNOWN); 814 exit(STATE_UNKNOWN);
780 } 815 }
781 816
@@ -786,7 +821,8 @@ int create_dhcp_socket(bool unicast, char *network_interface_name) {
786 821
787 /* bind the socket */ 822 /* bind the socket */
788 if (bind(sock, (struct sockaddr *)&myname, sizeof(myname)) < 0) { 823 if (bind(sock, (struct sockaddr *)&myname, sizeof(myname)) < 0) {
789 printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"), DHCP_CLIENT_PORT); 824 printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"),
825 DHCP_CLIENT_PORT);
790 exit(STATE_UNKNOWN); 826 exit(STATE_UNKNOWN);
791 } 827 }
792 828
@@ -800,7 +836,8 @@ int close_dhcp_socket(int sock) {
800} 836}
801 837
802/* adds a requested server address to list in memory */ 838/* adds a requested server address to list in memory */
803int add_requested_server(struct in_addr server_address, int *requested_servers, requested_server **requested_server_list) { 839int add_requested_server(struct in_addr server_address, int *requested_servers,
840 requested_server **requested_server_list) {
804 requested_server *new_server = (requested_server *)malloc(sizeof(requested_server)); 841 requested_server *new_server = (requested_server *)malloc(sizeof(requested_server));
805 if (new_server == NULL) { 842 if (new_server == NULL) {
806 return ERROR; 843 return ERROR;
@@ -822,7 +859,8 @@ int add_requested_server(struct in_addr server_address, int *requested_servers,
822} 859}
823 860
824/* adds a DHCP OFFER to list in memory */ 861/* adds a DHCP OFFER to list in memory */
825add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr source, dhcp_packet *offer_packet, dhcp_offer *dhcp_offer_list) { 862add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr source, dhcp_packet *offer_packet,
863 dhcp_offer *dhcp_offer_list) {
826 if (offer_packet == NULL) { 864 if (offer_packet == NULL) {
827 add_dhcp_offer_wrapper tmp = { 865 add_dhcp_offer_wrapper tmp = {
828 .error = ERROR, 866 .error = ERROR,
@@ -859,15 +897,18 @@ add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr source, dhcp_packet *offer_
859 dhcp_lease_time = ntohl(dhcp_lease_time); 897 dhcp_lease_time = ntohl(dhcp_lease_time);
860 break; 898 break;
861 case DHCP_OPTION_RENEWAL_TIME: 899 case DHCP_OPTION_RENEWAL_TIME:
862 memcpy(&dhcp_renewal_time, &offer_packet->options[dchp_opt_idx], sizeof(dhcp_renewal_time)); 900 memcpy(&dhcp_renewal_time, &offer_packet->options[dchp_opt_idx],
901 sizeof(dhcp_renewal_time));
863 dhcp_renewal_time = ntohl(dhcp_renewal_time); 902 dhcp_renewal_time = ntohl(dhcp_renewal_time);
864 break; 903 break;
865 case DHCP_OPTION_REBINDING_TIME: 904 case DHCP_OPTION_REBINDING_TIME:
866 memcpy(&dhcp_rebinding_time, &offer_packet->options[dchp_opt_idx], sizeof(dhcp_rebinding_time)); 905 memcpy(&dhcp_rebinding_time, &offer_packet->options[dchp_opt_idx],
906 sizeof(dhcp_rebinding_time));
867 dhcp_rebinding_time = ntohl(dhcp_rebinding_time); 907 dhcp_rebinding_time = ntohl(dhcp_rebinding_time);
868 break; 908 break;
869 case DHCP_OPTION_SERVER_IDENTIFIER: 909 case DHCP_OPTION_SERVER_IDENTIFIER:
870 memcpy(&serv_ident.s_addr, &offer_packet->options[dchp_opt_idx], sizeof(serv_ident.s_addr)); 910 memcpy(&serv_ident.s_addr, &offer_packet->options[dchp_opt_idx],
911 sizeof(serv_ident.s_addr));
871 break; 912 break;
872 } 913 }
873 914
@@ -955,7 +996,8 @@ int free_dhcp_offer_list(dhcp_offer *dhcp_offer_list) {
955/* frees memory allocated to requested server list */ 996/* frees memory allocated to requested server list */
956int free_requested_server_list(requested_server *requested_server_list) { 997int free_requested_server_list(requested_server *requested_server_list) {
957 requested_server *next_server; 998 requested_server *next_server;
958 for (requested_server *this_server = requested_server_list; this_server != NULL; this_server = next_server) { 999 for (requested_server *this_server = requested_server_list; this_server != NULL;
1000 this_server = next_server) {
959 next_server = this_server->next; 1001 next_server = this_server->next;
960 free(this_server); 1002 free(this_server);
961 } 1003 }
@@ -964,8 +1006,10 @@ int free_requested_server_list(requested_server *requested_server_list) {
964} 1006}
965 1007
966/* gets state and plugin output to return */ 1008/* gets state and plugin output to return */
967mp_subcheck get_results(bool exclusive, const int requested_servers, const struct in_addr requested_address, bool request_specific_address, 1009mp_subcheck get_results(bool exclusive, const int requested_servers,
968 requested_server *requested_server_list, int valid_responses, dhcp_offer *dhcp_offer_list) { 1010 const struct in_addr requested_address, bool request_specific_address,
1011 requested_server *requested_server_list, int valid_responses,
1012 dhcp_offer *dhcp_offer_list) {
969 mp_subcheck sc_dhcp_results = mp_subcheck_init(); 1013 mp_subcheck sc_dhcp_results = mp_subcheck_init();
970 sc_dhcp_results = mp_set_subcheck_default_state(sc_dhcp_results, STATE_OK); 1014 sc_dhcp_results = mp_set_subcheck_default_state(sc_dhcp_results, STATE_OK);
971 1015
@@ -995,22 +1039,28 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc
995 /* checks responses from requested servers */ 1039 /* checks responses from requested servers */
996 int requested_responses = 0; 1040 int requested_responses = 0;
997 if (requested_servers > 0) { 1041 if (requested_servers > 0) {
998 for (requested_server *temp_server = requested_server_list; temp_server != NULL; temp_server = temp_server->next) { 1042 for (requested_server *temp_server = requested_server_list; temp_server != NULL;
999 for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) { 1043 temp_server = temp_server->next) {
1044 for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL;
1045 temp_offer = temp_offer->next) {
1000 /* get max lease time we were offered */ 1046 /* get max lease time we were offered */
1001 if (temp_offer->lease_time > max_lease_time || temp_offer->lease_time == DHCP_INFINITE_TIME) { 1047 if (temp_offer->lease_time > max_lease_time ||
1048 temp_offer->lease_time == DHCP_INFINITE_TIME) {
1002 max_lease_time = temp_offer->lease_time; 1049 max_lease_time = temp_offer->lease_time;
1003 } 1050 }
1004 1051
1005 /* see if we got the address we requested */ 1052 /* see if we got the address we requested */
1006 if (!memcmp(&requested_address, &temp_offer->offered_address, sizeof(requested_address))) { 1053 if (!memcmp(&requested_address, &temp_offer->offered_address,
1054 sizeof(requested_address))) {
1007 received_requested_address = true; 1055 received_requested_address = true;
1008 } 1056 }
1009 1057
1010 /* see if the servers we wanted a response from, talked to us or not */ 1058 /* see if the servers we wanted a response from, talked to us or not */
1011 if (!memcmp(&temp_offer->server_address, &temp_server->server_address, sizeof(temp_server->server_address))) { 1059 if (!memcmp(&temp_offer->server_address, &temp_server->server_address,
1060 sizeof(temp_server->server_address))) {
1012 if (verbose) { 1061 if (verbose) {
1013 printf(_("DHCP Server Match: Offerer=%s"), inet_ntoa(temp_offer->server_address)); 1062 printf(_("DHCP Server Match: Offerer=%s"),
1063 inet_ntoa(temp_offer->server_address));
1014 printf(_(" Requested=%s"), inet_ntoa(temp_server->server_address)); 1064 printf(_(" Requested=%s"), inet_ntoa(temp_server->server_address));
1015 if (temp_server->answered) { 1065 if (temp_server->answered) {
1016 printf(_(" (duplicate)")); 1066 printf(_(" (duplicate)"));
@@ -1028,7 +1078,8 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc
1028 } 1078 }
1029 1079
1030 /* exclusive mode: check for undesired offers */ 1080 /* exclusive mode: check for undesired offers */
1031 for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) { 1081 for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL;
1082 temp_offer = temp_offer->next) {
1032 if (!temp_offer->desired) { 1083 if (!temp_offer->desired) {
1033 undesired_offer = temp_offer; /* Checks only for the first undesired offer */ 1084 undesired_offer = temp_offer; /* Checks only for the first undesired offer */
1034 break; /* no further checks needed */ 1085 break; /* no further checks needed */
@@ -1036,7 +1087,8 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc
1036 } 1087 }
1037 1088
1038 mp_subcheck sc_rqust_srvs = mp_subcheck_init(); 1089 mp_subcheck sc_rqust_srvs = mp_subcheck_init();
1039 xasprintf(&sc_rqust_srvs.output, "%d of %d requested servers responded", requested_responses, requested_servers); 1090 xasprintf(&sc_rqust_srvs.output, "%d of %d requested servers responded",
1091 requested_responses, requested_servers);
1040 1092
1041 if (requested_responses == requested_servers) { 1093 if (requested_responses == requested_servers) {
1042 sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, STATE_OK); 1094 sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, STATE_OK);
@@ -1053,14 +1105,17 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc
1053 1105
1054 } else { 1106 } else {
1055 /* else check and see if we got our requested address from any server */ 1107 /* else check and see if we got our requested address from any server */
1056 for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) { 1108 for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL;
1109 temp_offer = temp_offer->next) {
1057 /* get max lease time we were offered */ 1110 /* get max lease time we were offered */
1058 if (temp_offer->lease_time > max_lease_time || temp_offer->lease_time == DHCP_INFINITE_TIME) { 1111 if (temp_offer->lease_time > max_lease_time ||
1112 temp_offer->lease_time == DHCP_INFINITE_TIME) {
1059 max_lease_time = temp_offer->lease_time; 1113 max_lease_time = temp_offer->lease_time;
1060 } 1114 }
1061 1115
1062 /* see if we got the address we requested */ 1116 /* see if we got the address we requested */
1063 if (!memcmp(&requested_address, &temp_offer->offered_address, sizeof(requested_address))) { 1117 if (!memcmp(&requested_address, &temp_offer->offered_address,
1118 sizeof(requested_address))) {
1064 received_requested_address = true; 1119 received_requested_address = true;
1065 } 1120 }
1066 } 1121 }
@@ -1069,7 +1124,8 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc
1069 if (max_lease_time == DHCP_INFINITE_TIME) { 1124 if (max_lease_time == DHCP_INFINITE_TIME) {
1070 xasprintf(&sc_dhcp_results.output, "%s, max lease time = Infinity", sc_dhcp_results.output); 1125 xasprintf(&sc_dhcp_results.output, "%s, max lease time = Infinity", sc_dhcp_results.output);
1071 } else { 1126 } else {
1072 xasprintf(&sc_dhcp_results.output, "%s, max lease time = %" PRIu32 " seconds", sc_dhcp_results.output, max_lease_time); 1127 xasprintf(&sc_dhcp_results.output, "%s, max lease time = %" PRIu32 " seconds",
1128 sc_dhcp_results.output, max_lease_time);
1073 } 1129 }
1074 1130
1075 if (exclusive) { 1131 if (exclusive) {
@@ -1083,8 +1139,8 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc
1083 // Get the addresses for printout 1139 // Get the addresses for printout
1084 // 1.address of the sending server 1140 // 1.address of the sending server
1085 char server_address[INET_ADDRSTRLEN]; 1141 char server_address[INET_ADDRSTRLEN];
1086 const char *server_address_transformed = 1142 const char *server_address_transformed = inet_ntop(
1087 inet_ntop(AF_INET, &undesired_offer->server_address, server_address, sizeof(server_address)); 1143 AF_INET, &undesired_offer->server_address, server_address, sizeof(server_address));
1088 1144
1089 if (server_address != server_address_transformed) { 1145 if (server_address != server_address_transformed) {
1090 die(STATE_UNKNOWN, "inet_ntop failed"); 1146 die(STATE_UNKNOWN, "inet_ntop failed");
@@ -1093,13 +1149,15 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc
1093 // 2.address offered 1149 // 2.address offered
1094 char offered_address[INET_ADDRSTRLEN]; 1150 char offered_address[INET_ADDRSTRLEN];
1095 const char *offered_address_transformed = 1151 const char *offered_address_transformed =
1096 inet_ntop(AF_INET, &undesired_offer->offered_address, offered_address, sizeof(offered_address)); 1152 inet_ntop(AF_INET, &undesired_offer->offered_address, offered_address,
1153 sizeof(offered_address));
1097 1154
1098 if (offered_address != offered_address_transformed) { 1155 if (offered_address != offered_address_transformed) {
1099 die(STATE_UNKNOWN, "inet_ntop failed"); 1156 die(STATE_UNKNOWN, "inet_ntop failed");
1100 } 1157 }
1101 1158
1102 xasprintf(&sc_rogue_server.output, "Rogue DHCP Server detected! Server %s offered %s", server_address, offered_address); 1159 xasprintf(&sc_rogue_server.output, "Rogue DHCP Server detected! Server %s offered %s",
1160 server_address, offered_address);
1103 } else { 1161 } else {
1104 sc_rogue_server = mp_set_subcheck_state(sc_rogue_server, STATE_OK); 1162 sc_rogue_server = mp_set_subcheck_state(sc_rogue_server, STATE_OK);
1105 xasprintf(&sc_rogue_server.output, "No Rogue DHCP Server detected"); 1163 xasprintf(&sc_rogue_server.output, "No Rogue DHCP Server detected");
@@ -1112,10 +1170,12 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc
1112 1170
1113 if (received_requested_address) { 1171 if (received_requested_address) {
1114 sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, STATE_OK); 1172 sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, STATE_OK);
1115 xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was offered", inet_ntoa(requested_address)); 1173 xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was offered",
1174 inet_ntoa(requested_address));
1116 } else { 1175 } else {
1117 sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, STATE_WARNING); 1176 sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, STATE_WARNING);
1118 xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was NOT offered", inet_ntoa(requested_address)); 1177 xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was NOT offered",
1178 inet_ntoa(requested_address));
1119 } 1179 }
1120 1180
1121 mp_add_subcheck_to_subcheck(&sc_dhcp_results, sc_rqustd_addr); 1181 mp_add_subcheck_to_subcheck(&sc_dhcp_results, sc_rqustd_addr);
@@ -1138,18 +1198,19 @@ process_arguments_wrapper process_arguments(int argc, char **argv) {
1138 }; 1198 };
1139 1199
1140 int option_index = 0; 1200 int option_index = 0;
1141 static struct option long_options[] = {{"serverip", required_argument, 0, 's'}, 1201 static struct option long_options[] = {
1142 {"requestedip", required_argument, 0, 'r'}, 1202 {"serverip", required_argument, 0, 's'},
1143 {"timeout", required_argument, 0, 't'}, 1203 {"requestedip", required_argument, 0, 'r'},
1144 {"interface", required_argument, 0, 'i'}, 1204 {"timeout", required_argument, 0, 't'},
1145 {"mac", required_argument, 0, 'm'}, 1205 {"interface", required_argument, 0, 'i'},
1146 {"unicast", no_argument, 0, 'u'}, 1206 {"mac", required_argument, 0, 'm'},
1147 {"exclusive", no_argument, 0, 'x'}, 1207 {"unicast", no_argument, 0, 'u'},
1148 {"verbose", no_argument, 0, 'v'}, 1208 {"exclusive", no_argument, 0, 'x'},
1149 {"version", no_argument, 0, 'V'}, 1209 {"verbose", no_argument, 0, 'v'},
1150 {"help", no_argument, 0, 'h'}, 1210 {"version", no_argument, 0, 'V'},
1151 {"output-format", required_argument, 0, output_format_index}, 1211 {"help", no_argument, 0, 'h'},
1152 {0, 0, 0, 0}}; 1212 {"output-format", required_argument, 0, output_format_index},
1213 {0, 0, 0, 0}};
1153 1214
1154 check_dhcp_config config = check_dhcp_config_init(); 1215 check_dhcp_config config = check_dhcp_config_init();
1155 int option_char = 0; 1216 int option_char = 0;
@@ -1163,7 +1224,8 @@ process_arguments_wrapper process_arguments(int argc, char **argv) {
1163 switch (option_char) { 1224 switch (option_char) {
1164 case 's': /* DHCP server address */ 1225 case 's': /* DHCP server address */
1165 resolve_host(optarg, &config.dhcp_ip); 1226 resolve_host(optarg, &config.dhcp_ip);
1166 add_requested_server(config.dhcp_ip, &config.num_of_requested_servers, &config.requested_server_list); 1227 add_requested_server(config.dhcp_ip, &config.num_of_requested_servers,
1228 &config.requested_server_list);
1167 break; 1229 break;
1168 1230
1169 case 'r': /* address we are requested from DHCP servers */ 1231 case 'r': /* address we are requested from DHCP servers */
@@ -1187,7 +1249,8 @@ process_arguments_wrapper process_arguments(int argc, char **argv) {
1187 break; 1249 break;
1188 1250
1189 case 'i': /* interface name */ 1251 case 'i': /* interface name */
1190 strncpy(config.network_interface_name, optarg, sizeof(config.network_interface_name) - 1); 1252 strncpy(config.network_interface_name, optarg,
1253 sizeof(config.network_interface_name) - 1);
1191 config.network_interface_name[sizeof(config.network_interface_name) - 1] = '\x0'; 1254 config.network_interface_name[sizeof(config.network_interface_name) - 1] = '\x0';
1192 break; 1255 break;
1193 1256
@@ -1289,7 +1352,8 @@ static int put_ctrl(int fd, int len, int pri) {
1289 1352
1290 ctl.len = len; 1353 ctl.len = len;
1291 if (putmsg(fd, &ctl, 0, pri) < 0) { 1354 if (putmsg(fd, &ctl, 0, pri) < 0) {
1292 printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), strerror(errno)); 1355 printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"),
1356 strerror(errno));
1293 exit(STATE_UNKNOWN); 1357 exit(STATE_UNKNOWN);
1294 } 1358 }
1295 1359
@@ -1302,7 +1366,8 @@ static int put_both(int fd, int clen, int dlen, int pri) {
1302 ctl.len = clen; 1366 ctl.len = clen;
1303 dat.len = dlen; 1367 dat.len = dlen;
1304 if (putmsg(fd, &ctl, &dat, pri) < 0) { 1368 if (putmsg(fd, &ctl, &dat, pri) < 0) {
1305 printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), strerror(errno)); 1369 printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"),
1370 strerror(errno));
1306 exit(STATE_UNKNOWN); 1371 exit(STATE_UNKNOWN);
1307 } 1372 }
1308 1373
@@ -1314,7 +1379,8 @@ static int dl_open(const char *dev, int unit, int *fd) {
1314 dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area; 1379 dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area;
1315 1380
1316 if ((*fd = open(dev, O_RDWR)) == -1) { 1381 if ((*fd = open(dev, O_RDWR)) == -1) {
1317 printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), dev, strerror(errno)); 1382 printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"),
1383 dev, strerror(errno));
1318 exit(STATE_UNKNOWN); 1384 exit(STATE_UNKNOWN);
1319 } 1385 }
1320 attach_req->dl_primitive = DL_ATTACH_REQ; 1386 attach_req->dl_primitive = DL_ATTACH_REQ;
@@ -1338,7 +1404,8 @@ static int dl_bind(int fd, int sap, u_char *addr) {
1338 put_ctrl(fd, sizeof(dl_bind_req_t), 0); 1404 put_ctrl(fd, sizeof(dl_bind_req_t), 0);
1339 get_msg(fd); 1405 get_msg(fd);
1340 if (GOT_ERR == check_ctrl(DL_BIND_ACK)) { 1406 if (GOT_ERR == check_ctrl(DL_BIND_ACK)) {
1341 printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), strerror(errno)); 1407 printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"),
1408 strerror(errno));
1342 exit(STATE_UNKNOWN); 1409 exit(STATE_UNKNOWN);
1343 } 1410 }
1344 bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, bind_ack->dl_addr_length); 1411 bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, bind_ack->dl_addr_length);
@@ -1455,7 +1522,8 @@ void print_help(void) {
1455 printf(" %s\n", "-u, --unicast"); 1522 printf(" %s\n", "-u, --unicast");
1456 printf(" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s")); 1523 printf(" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s"));
1457 printf(" %s\n", "-x, --exclusive"); 1524 printf(" %s\n", "-x, --exclusive");
1458 printf(" %s\n", _("Only requested DHCP server may response (rogue DHCP server detection), requires -s")); 1525 printf(" %s\n",
1526 _("Only requested DHCP server may response (rogue DHCP server detection), requires -s"));
1459 1527
1460 printf(UT_SUPPORT); 1528 printf(UT_SUPPORT);
1461} 1529}