diff options
-rw-r--r-- | plugins/check_dhcp.c | 446 |
1 files changed, 330 insertions, 116 deletions
diff --git a/plugins/check_dhcp.c b/plugins/check_dhcp.c index ee893cd..5c3c199 100644 --- a/plugins/check_dhcp.c +++ b/plugins/check_dhcp.c | |||
@@ -45,17 +45,57 @@ | |||
45 | #include <arpa/inet.h> | 45 | #include <arpa/inet.h> |
46 | 46 | ||
47 | #if defined( __linux__ ) | 47 | #if defined( __linux__ ) |
48 | |||
48 | #include <linux/if_ether.h> | 49 | #include <linux/if_ether.h> |
49 | #include <features.h> | 50 | #include <features.h> |
50 | #else | 51 | |
52 | #elif defined (__bsd__) | ||
53 | |||
51 | #include <netinet/if_ether.h> | 54 | #include <netinet/if_ether.h> |
52 | #include <sys/sysctl.h> | 55 | #include <sys/sysctl.h> |
53 | #include <net/if_dl.h> | 56 | #include <net/if_dl.h> |
57 | |||
58 | #elif defined(__sun__) || defined(__solaris__) | ||
59 | |||
60 | #define INSAP 22 | ||
61 | #define OUTSAP 24 | ||
62 | |||
63 | #include <signal.h> | ||
64 | #include <ctype.h> | ||
65 | #include <sys/stropts.h> | ||
66 | #include <sys/poll.h> | ||
67 | #include <sys/dlpi.h> | ||
68 | |||
69 | #define bcopy(source, destination, length) memcpy(destination, source, length) | ||
70 | |||
71 | #define AREA_SZ 5000 /* buffer length in bytes */ | ||
72 | static u_long ctl_area[AREA_SZ]; | ||
73 | static u_long dat_area[AREA_SZ]; | ||
74 | static struct strbuf ctl = {AREA_SZ, 0, (char *)ctl_area}; | ||
75 | static struct strbuf dat = {AREA_SZ, 0, (char *)dat_area}; | ||
76 | |||
77 | #define GOT_CTRL 1 | ||
78 | #define GOT_DATA 2 | ||
79 | #define GOT_BOTH 3 | ||
80 | #define GOT_INTR 4 | ||
81 | #define GOT_ERR 128 | ||
82 | |||
83 | #define u_int8_t uint8_t | ||
84 | #define u_int16_t uint16_t | ||
85 | #define u_int32_t uint32_t | ||
86 | |||
87 | static int get_msg(int); | ||
88 | static int check_ctrl(int); | ||
89 | static int put_ctrl(int, int, int); | ||
90 | static int put_both(int, int, int, int); | ||
91 | static int dl_open(const char *, int, int *); | ||
92 | static int dl_bind(int, int, u_char *); | ||
93 | long mac_addr_dlpi( const char *, int, u_char *); | ||
94 | |||
54 | #endif | 95 | #endif |
55 | 96 | ||
56 | const char *progname = "check_dhcp"; | 97 | const char *progname = "check_dhcp"; |
57 | 98 | ||
58 | /*#define DEBUG*/ | ||
59 | #define HAVE_GETOPT_H | 99 | #define HAVE_GETOPT_H |
60 | 100 | ||
61 | 101 | ||
@@ -166,6 +206,7 @@ int requested_responses=0; | |||
166 | 206 | ||
167 | int request_specific_address=FALSE; | 207 | int request_specific_address=FALSE; |
168 | int received_requested_address=FALSE; | 208 | int received_requested_address=FALSE; |
209 | int verbose=0; | ||
169 | struct in_addr requested_address; | 210 | struct in_addr requested_address; |
170 | 211 | ||
171 | 212 | ||
@@ -233,6 +274,9 @@ int main(int argc, char **argv){ | |||
233 | 274 | ||
234 | /* determines hardware address on client machine */ | 275 | /* determines hardware address on client machine */ |
235 | int get_hardware_address(int sock,char *interface_name){ | 276 | int get_hardware_address(int sock,char *interface_name){ |
277 | |||
278 | int i; | ||
279 | |||
236 | #if defined(__linux__) | 280 | #if defined(__linux__) |
237 | struct ifreq ifr; | 281 | struct ifreq ifr; |
238 | 282 | ||
@@ -245,7 +289,9 @@ int get_hardware_address(int sock,char *interface_name){ | |||
245 | } | 289 | } |
246 | 290 | ||
247 | memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); | 291 | memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); |
248 | #else | 292 | |
293 | #elif defined(__bsd__) | ||
294 | |||
249 | /* Code from getmac.c posted at http://lists.freebsd.org/pipermail/freebsd-hackers/2004-June/007415.html | 295 | /* Code from getmac.c posted at http://lists.freebsd.org/pipermail/freebsd-hackers/2004-June/007415.html |
250 | * by Alecs King based on Unix Network programming Ch 17 | 296 | * by Alecs King based on Unix Network programming Ch 17 |
251 | */ | 297 | */ |
@@ -263,39 +309,76 @@ int get_hardware_address(int sock,char *interface_name){ | |||
263 | mib[4] = NET_RT_IFLIST; | 309 | mib[4] = NET_RT_IFLIST; |
264 | 310 | ||
265 | if ((mib[5] = if_nametoindex(interface_name)) == 0) { | 311 | if ((mib[5] = if_nametoindex(interface_name)) == 0) { |
266 | perror("if_nametoindex error"); | 312 | printf("Error: if_nametoindex error - %s.\n", strerror(errno)); |
267 | exit(2); | 313 | exit(STATE_UNKNOWN); |
268 | } | 314 | } |
269 | 315 | ||
270 | if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { | 316 | if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { |
271 | perror("sysctl 1 error"); | 317 | printf("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n", interface_name, strerror(errno)); |
272 | exit(3); | 318 | exit(STATE_UNKNOWN); |
273 | } | 319 | } |
274 | 320 | ||
275 | if ((buf = malloc(len)) == NULL) { | 321 | if ((buf = malloc(len)) == NULL) { |
276 | perror("malloc error"); | 322 | printf("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n", interface_name, strerror(errno)); |
277 | exit(4); | 323 | exit(4); |
278 | } | 324 | } |
279 | 325 | ||
280 | if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { | 326 | if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { |
281 | perror("sysctl 2 error"); | 327 | printf("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n", interface_name, strerror(errno)); |
282 | exit(5); | 328 | exit(STATE_UNKNOWN); |
283 | } | 329 | } |
284 | 330 | ||
285 | ifm = (struct if_msghdr *)buf; | 331 | ifm = (struct if_msghdr *)buf; |
286 | sdl = (struct sockaddr_dl *)(ifm + 1); | 332 | sdl = (struct sockaddr_dl *)(ifm + 1); |
287 | ptr = (unsigned char *)LLADDR(sdl); | 333 | ptr = (unsigned char *)LLADDR(sdl); |
288 | memcpy(&client_hardware_address[0], ptr, 6) ; | 334 | memcpy(&client_hardware_address[0], ptr, 6) ; |
289 | #endif | ||
290 | 335 | ||
336 | #elif defined(__sun__) || defined(__solaris__) | ||
337 | |||
338 | /* | ||
339 | * Lifted from | ||
340 | * | ||
341 | * mac_addr_dlpi.c | ||
342 | * | ||
343 | * Copyright @2000, 2003 Martin Kompf, martin@kompf.de | ||
344 | * | ||
345 | * Return the MAC (ie, ethernet hardware) address by using the dlpi api. | ||
346 | * | ||
347 | */ | ||
348 | |||
349 | long stat; | ||
350 | char dev[20] = "/dev/"; | ||
351 | char *p; | ||
352 | int unit; | ||
353 | |||
354 | for (p = interface_name; *p && isalpha(*p); p++) | ||
355 | /* no-op */ ; | ||
356 | if ( p != '\0' ) { | ||
357 | unit = atoi(p) ; | ||
358 | *p = '\0' ; | ||
359 | strncat(dev, interface_name, 6) ; | ||
360 | } else { | ||
361 | printf("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n", interface_name); | ||
362 | exit(STATE_UNKNOWN); | ||
363 | } | ||
364 | stat = mac_addr_dlpi(dev, unit, client_hardware_address); | ||
365 | if (stat != 0) { | ||
366 | printf("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n", dev, unit); | ||
367 | exit(STATE_UNKNOWN); | ||
368 | } | ||
291 | 369 | ||
292 | #ifdef DEBUG | 370 | #else |
293 | printf("Hardware address: %02x:%02x:%02x:",client_hardware_address[0],client_hardware_address[1],client_hardware_address[2]); | 371 | printf("Error: can't get MAC address for this architcture.\n"); |
294 | printf("%02x:",client_hardware_address[3]); | 372 | exit(STATE_UNKNOWN); |
295 | printf("%02x:%02x\n",client_hardware_address[4],client_hardware_address[5]); | ||
296 | printf("\n"); | ||
297 | #endif | 373 | #endif |
298 | 374 | ||
375 | if (verbose) { | ||
376 | printf( "Hadrware address: "); | ||
377 | for (i=0; i<6; ++i) | ||
378 | printf("%2.2x", client_hardware_address[i]); | ||
379 | printf( "\n"); | ||
380 | } | ||
381 | |||
299 | return OK; | 382 | return OK; |
300 | } | 383 | } |
301 | 384 | ||
@@ -364,21 +447,20 @@ int send_dhcp_discover(int sock){ | |||
364 | bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero)); | 447 | bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero)); |
365 | 448 | ||
366 | 449 | ||
367 | #ifdef DEBUG | 450 | if (verbose) { |
368 | printf("DHCPDISCOVER to %s port %d\n",inet_ntoa(sockaddr_broadcast.sin_addr),ntohs(sockaddr_broadcast.sin_port)); | 451 | printf("DHCPDISCOVER to %s port %d\n",inet_ntoa(sockaddr_broadcast.sin_addr),ntohs(sockaddr_broadcast.sin_port)); |
369 | printf("DHCPDISCOVER XID: %lu (0x%X)\n",ntohl(discover_packet.xid),ntohl(discover_packet.xid)); | 452 | printf("DHCPDISCOVER XID: %lu (0x%X)\n",ntohl(discover_packet.xid),ntohl(discover_packet.xid)); |
370 | printf("DHCDISCOVER ciaddr: %s\n",inet_ntoa(discover_packet.ciaddr)); | 453 | printf("DHCDISCOVER ciaddr: %s\n",inet_ntoa(discover_packet.ciaddr)); |
371 | printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr)); | 454 | printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr)); |
372 | printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr)); | 455 | printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr)); |
373 | printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr)); | 456 | printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr)); |
374 | #endif | 457 | } |
375 | 458 | ||
376 | /* send the DHCPDISCOVER packet out */ | 459 | /* send the DHCPDISCOVER packet out */ |
377 | send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast); | 460 | send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast); |
378 | 461 | ||
379 | #ifdef DEBUG | 462 | if (verbose) |
380 | printf("\n\n"); | 463 | printf("\n\n"); |
381 | #endif | ||
382 | 464 | ||
383 | return OK; | 465 | return OK; |
384 | } | 466 | } |
@@ -406,9 +488,8 @@ int get_dhcp_offer(int sock){ | |||
406 | if((current_time-start_time)>=dhcpoffer_timeout) | 488 | if((current_time-start_time)>=dhcpoffer_timeout) |
407 | break; | 489 | break; |
408 | 490 | ||
409 | #ifdef DEBUG | 491 | if (verbose) |
410 | printf("\n\n"); | 492 | printf("\n\n"); |
411 | #endif | ||
412 | 493 | ||
413 | bzero(&source,sizeof(source)); | 494 | bzero(&source,sizeof(source)); |
414 | bzero(&offer_packet,sizeof(offer_packet)); | 495 | bzero(&offer_packet,sizeof(offer_packet)); |
@@ -417,70 +498,69 @@ int get_dhcp_offer(int sock){ | |||
417 | result=receive_dhcp_packet(&offer_packet,sizeof(offer_packet),sock,dhcpoffer_timeout,&source); | 498 | result=receive_dhcp_packet(&offer_packet,sizeof(offer_packet),sock,dhcpoffer_timeout,&source); |
418 | 499 | ||
419 | if(result!=OK){ | 500 | if(result!=OK){ |
420 | #ifdef DEBUG | 501 | if (verbose) |
421 | printf("Result=ERROR\n"); | 502 | printf("Result=ERROR\n"); |
422 | #endif | 503 | |
423 | continue; | 504 | continue; |
424 | } | 505 | } |
425 | else{ | 506 | else{ |
426 | #ifdef DEBUG | 507 | if (verbose) |
427 | printf("Result=OK\n"); | 508 | printf("Result=OK\n"); |
428 | #endif | 509 | |
429 | responses++; | 510 | responses++; |
430 | } | 511 | } |
431 | 512 | ||
432 | #ifdef DEBUG | 513 | if (verbose) { |
433 | printf("DHCPOFFER from IP address %s\n",inet_ntoa(source.sin_addr)); | 514 | printf("DHCPOFFER from IP address %s\n",inet_ntoa(source.sin_addr)); |
434 | printf("DHCPOFFER XID: %lu (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid)); | 515 | printf("DHCPOFFER XID: %lu (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid)); |
435 | #endif | 516 | } |
436 | 517 | ||
437 | /* check packet xid to see if its the same as the one we used in the discover packet */ | 518 | /* check packet xid to see if its the same as the one we used in the discover packet */ |
438 | if(ntohl(offer_packet.xid)!=packet_xid){ | 519 | if(ntohl(offer_packet.xid)!=packet_xid){ |
439 | #ifdef DEBUG | 520 | if (verbose) |
440 | printf("DHCPOFFER XID (%lu) did not match DHCPDISCOVER XID (%lu) - ignoring packet\n",ntohl(offer_packet.xid),packet_xid); | 521 | printf("DHCPOFFER XID (%lu) did not match DHCPDISCOVER XID (%lu) - ignoring packet\n",ntohl(offer_packet.xid),packet_xid); |
441 | #endif | 522 | |
442 | continue; | 523 | continue; |
443 | } | 524 | } |
444 | 525 | ||
445 | /* check hardware address */ | 526 | /* check hardware address */ |
446 | result=OK; | 527 | result=OK; |
447 | #ifdef DEBUG | 528 | if (verbose) |
448 | printf("DHCPOFFER chaddr: "); | 529 | printf("DHCPOFFER chaddr: "); |
449 | #endif | 530 | |
450 | for(x=0;x<ETHERNET_HARDWARE_ADDRESS_LENGTH;x++){ | 531 | for(x=0;x<ETHERNET_HARDWARE_ADDRESS_LENGTH;x++){ |
451 | #ifdef DEBUG | 532 | if (verbose) |
452 | printf("%02X",(unsigned char)offer_packet.chaddr[x]); | 533 | printf("%02X",(unsigned char)offer_packet.chaddr[x]); |
453 | #endif | 534 | |
454 | if(offer_packet.chaddr[x]!=client_hardware_address[x]){ | 535 | if(offer_packet.chaddr[x]!=client_hardware_address[x]) |
455 | result=ERROR; | 536 | result=ERROR; |
456 | } | 537 | } |
457 | } | 538 | if (verbose) |
458 | #ifdef DEBUG | 539 | printf("\n"); |
459 | printf("\n"); | 540 | |
460 | #endif | ||
461 | if(result==ERROR){ | 541 | if(result==ERROR){ |
462 | #ifdef DEBUG | 542 | if (verbose) |
463 | printf("DHCPOFFER hardware address did not match our own - ignoring packet\n"); | 543 | printf("DHCPOFFER hardware address did not match our own - ignoring packet\n"); |
464 | #endif | 544 | |
465 | continue; | 545 | continue; |
466 | } | 546 | } |
467 | 547 | ||
468 | #ifdef DEBUG | 548 | if (verbose) { |
469 | printf("DHCPOFFER ciaddr: %s\n",inet_ntoa(offer_packet.ciaddr)); | 549 | printf("DHCPOFFER ciaddr: %s\n",inet_ntoa(offer_packet.ciaddr)); |
470 | printf("DHCPOFFER yiaddr: %s\n",inet_ntoa(offer_packet.yiaddr)); | 550 | printf("DHCPOFFER yiaddr: %s\n",inet_ntoa(offer_packet.yiaddr)); |
471 | printf("DHCPOFFER siaddr: %s\n",inet_ntoa(offer_packet.siaddr)); | 551 | printf("DHCPOFFER siaddr: %s\n",inet_ntoa(offer_packet.siaddr)); |
472 | printf("DHCPOFFER giaddr: %s\n",inet_ntoa(offer_packet.giaddr)); | 552 | printf("DHCPOFFER giaddr: %s\n",inet_ntoa(offer_packet.giaddr)); |
473 | #endif | 553 | } |
474 | 554 | ||
475 | add_dhcp_offer(source.sin_addr,&offer_packet); | 555 | add_dhcp_offer(source.sin_addr,&offer_packet); |
476 | 556 | ||
477 | valid_responses++; | 557 | valid_responses++; |
478 | } | 558 | } |
479 | 559 | ||
480 | #ifdef DEBUG | 560 | if (verbose) { |
481 | printf("Total responses seen on the wire: %d\n",responses); | 561 | printf("Total responses seen on the wire: %d\n",responses); |
482 | printf("Valid responses for this machine: %d\n",valid_responses); | 562 | printf("Valid responses for this machine: %d\n",valid_responses); |
483 | #endif | 563 | } |
484 | 564 | ||
485 | return OK; | 565 | return OK; |
486 | } | 566 | } |
@@ -494,9 +574,8 @@ int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in | |||
494 | 574 | ||
495 | result=sendto(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)dest,sizeof(*dest)); | 575 | result=sendto(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)dest,sizeof(*dest)); |
496 | 576 | ||
497 | #ifdef DEBUG | 577 | if (verbose) |
498 | printf("send_dhcp_packet result: %d\n",result); | 578 | printf("send_dhcp_packet result: %d\n",result); |
499 | #endif | ||
500 | 579 | ||
501 | if(result<0) | 580 | if(result<0) |
502 | return ERROR; | 581 | return ERROR; |
@@ -524,9 +603,8 @@ int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, st | |||
524 | 603 | ||
525 | /* make sure some data has arrived */ | 604 | /* make sure some data has arrived */ |
526 | if(!FD_ISSET(sock,&readfds)){ | 605 | if(!FD_ISSET(sock,&readfds)){ |
527 | #ifdef DEBUG | 606 | if (verbose) |
528 | printf("No (more) data received\n"); | 607 | printf("No (more) data received\n"); |
529 | #endif | ||
530 | return ERROR; | 608 | return ERROR; |
531 | } | 609 | } |
532 | 610 | ||
@@ -537,26 +615,24 @@ int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, st | |||
537 | bzero(&source_address,sizeof(source_address)); | 615 | bzero(&source_address,sizeof(source_address)); |
538 | address_size=sizeof(source_address); | 616 | address_size=sizeof(source_address); |
539 | recv_result=recvfrom(sock,(char *)buffer,buffer_size,MSG_PEEK,(struct sockaddr *)&source_address,&address_size); | 617 | recv_result=recvfrom(sock,(char *)buffer,buffer_size,MSG_PEEK,(struct sockaddr *)&source_address,&address_size); |
540 | #ifdef DEBUG | 618 | if (verbose) |
541 | printf("recv_result_1: %d\n",recv_result); | 619 | printf("recv_result_1: %d\n",recv_result); |
542 | #endif | ||
543 | recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)&source_address,&address_size); | 620 | recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)&source_address,&address_size); |
544 | #ifdef DEBUG | 621 | if (verbose) |
545 | printf("recv_result_2: %d\n",recv_result); | 622 | printf("recv_result_2: %d\n",recv_result); |
546 | #endif | ||
547 | 623 | ||
548 | if(recv_result==-1){ | 624 | if(recv_result==-1){ |
549 | #ifdef DEBUG | 625 | if (verbose) { |
550 | printf("recvfrom() failed, "); | 626 | printf("recvfrom() failed, "); |
551 | printf("errno: (%d) -> %s\n",errno,strerror(errno)); | 627 | printf("errno: (%d) -> %s\n",errno,strerror(errno)); |
552 | #endif | 628 | } |
553 | return ERROR; | 629 | return ERROR; |
554 | } | 630 | } |
555 | else{ | 631 | else{ |
556 | #ifdef DEBUG | 632 | if (verbose) { |
557 | printf("receive_dhcp_packet() result: %d\n",recv_result); | 633 | printf("receive_dhcp_packet() result: %d\n",recv_result); |
558 | printf("receive_dhcp_packet() source: %s\n",inet_ntoa(source_address.sin_addr)); | 634 | printf("receive_dhcp_packet() source: %s\n",inet_ntoa(source_address.sin_addr)); |
559 | #endif | 635 | } |
560 | 636 | ||
561 | memcpy(address,&source_address,sizeof(source_address)); | 637 | memcpy(address,&source_address,sizeof(source_address)); |
562 | return OK; | 638 | return OK; |
@@ -589,9 +665,8 @@ int create_dhcp_socket(void){ | |||
589 | exit(STATE_UNKNOWN); | 665 | exit(STATE_UNKNOWN); |
590 | } | 666 | } |
591 | 667 | ||
592 | #ifdef DEBUG | 668 | if (verbose) |
593 | printf("DHCP socket: %d\n",sock); | 669 | printf("DHCP socket: %d\n",sock); |
594 | #endif | ||
595 | 670 | ||
596 | /* set the reuse address flag so we don't get errors when restarting */ | 671 | /* set the reuse address flag so we don't get errors when restarting */ |
597 | flag=1; | 672 | flag=1; |
@@ -657,9 +732,8 @@ int add_requested_server(struct in_addr server_address){ | |||
657 | 732 | ||
658 | requested_servers++; | 733 | requested_servers++; |
659 | 734 | ||
660 | #ifdef DEBUG | 735 | if (verbose) |
661 | printf("Requested server address: %s\n",inet_ntoa(new_server->server_address)); | 736 | printf("Requested server address: %s\n",inet_ntoa(new_server->server_address)); |
662 | #endif | ||
663 | 737 | ||
664 | return OK; | 738 | return OK; |
665 | } | 739 | } |
@@ -691,9 +765,8 @@ int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ | |||
691 | /* get option length */ | 765 | /* get option length */ |
692 | option_length=offer_packet->options[x++]; | 766 | option_length=offer_packet->options[x++]; |
693 | 767 | ||
694 | #ifdef DEBUG | 768 | if (verbose) |
695 | printf("Option: %d (0x%02X)\n",option_type,option_length); | 769 | printf("Option: %d (0x%02X)\n",option_type,option_length); |
696 | #endif | ||
697 | 770 | ||
698 | /* get option data */ | 771 | /* get option data */ |
699 | if(option_type==DHCP_OPTION_LEASE_TIME) | 772 | if(option_type==DHCP_OPTION_LEASE_TIME) |
@@ -708,19 +781,19 @@ int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ | |||
708 | for(y=0;y<option_length;y++,x++); | 781 | for(y=0;y<option_length;y++,x++); |
709 | } | 782 | } |
710 | 783 | ||
711 | #ifdef DEBUG | 784 | if (verbose) { |
712 | if(dhcp_lease_time==DHCP_INFINITE_TIME) | 785 | if(dhcp_lease_time==DHCP_INFINITE_TIME) |
713 | printf("Lease Time: Infinite\n"); | 786 | printf("Lease Time: Infinite\n"); |
714 | else | 787 | else |
715 | printf("Lease Time: %lu seconds\n",(unsigned long)dhcp_lease_time); | 788 | printf("Lease Time: %lu seconds\n",(unsigned long)dhcp_lease_time); |
716 | if(dhcp_renewal_time==DHCP_INFINITE_TIME) | 789 | if(dhcp_renewal_time==DHCP_INFINITE_TIME) |
717 | printf("Renewal Time: Infinite\n"); | 790 | printf("Renewal Time: Infinite\n"); |
718 | else | 791 | else |
719 | printf("Renewal Time: %lu seconds\n",(unsigned long)dhcp_renewal_time); | 792 | printf("Renewal Time: %lu seconds\n",(unsigned long)dhcp_renewal_time); |
720 | if(dhcp_rebinding_time==DHCP_INFINITE_TIME) | 793 | if(dhcp_rebinding_time==DHCP_INFINITE_TIME) |
721 | printf("Rebinding Time: Infinite\n"); | 794 | printf("Rebinding Time: Infinite\n"); |
722 | printf("Rebinding Time: %lu seconds\n",(unsigned long)dhcp_rebinding_time); | 795 | printf("Rebinding Time: %lu seconds\n",(unsigned long)dhcp_rebinding_time); |
723 | #endif | 796 | } |
724 | 797 | ||
725 | new_offer=(dhcp_offer *)malloc(sizeof(dhcp_offer)); | 798 | new_offer=(dhcp_offer *)malloc(sizeof(dhcp_offer)); |
726 | 799 | ||
@@ -735,10 +808,10 @@ int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ | |||
735 | new_offer->rebinding_time=dhcp_rebinding_time; | 808 | new_offer->rebinding_time=dhcp_rebinding_time; |
736 | 809 | ||
737 | 810 | ||
738 | #ifdef DEBUG | 811 | if (verbose) { |
739 | printf("Added offer from server @ %s",inet_ntoa(new_offer->server_address)); | 812 | printf("Added offer from server @ %s",inet_ntoa(new_offer->server_address)); |
740 | printf(" of IP address %s\n",inet_ntoa(new_offer->offered_address)); | 813 | printf(" of IP address %s\n",inet_ntoa(new_offer->offered_address)); |
741 | #endif | 814 | } |
742 | 815 | ||
743 | /* add new offer to head of list */ | 816 | /* add new offer to head of list */ |
744 | new_offer->next=dhcp_offer_list; | 817 | new_offer->next=dhcp_offer_list; |
@@ -807,10 +880,10 @@ int get_results(void){ | |||
807 | 880 | ||
808 | /* see if the servers we wanted a response from talked to us or not */ | 881 | /* see if the servers we wanted a response from talked to us or not */ |
809 | if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){ | 882 | if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){ |
810 | #ifdef DEBUG | 883 | if (verbose) { |
811 | printf("DHCP Server Match: Offerer=%s",inet_ntoa(temp_offer->server_address)); | 884 | printf("DHCP Server Match: Offerer=%s",inet_ntoa(temp_offer->server_address)); |
812 | printf(" Requested=%s\n",inet_ntoa(temp_server->server_address)); | 885 | printf(" Requested=%s\n",inet_ntoa(temp_server->server_address)); |
813 | #endif | 886 | } |
814 | requested_responses++; | 887 | requested_responses++; |
815 | } | 888 | } |
816 | } | 889 | } |
@@ -1039,6 +1112,11 @@ int call_getopt(int argc, char **argv){ | |||
1039 | print_help(); | 1112 | print_help(); |
1040 | exit(STATE_OK); | 1113 | exit(STATE_OK); |
1041 | 1114 | ||
1115 | case 'v': /* verbose */ | ||
1116 | |||
1117 | verbose=1; | ||
1118 | break; | ||
1119 | |||
1042 | case '?': /* help */ | 1120 | case '?': /* help */ |
1043 | 1121 | ||
1044 | /*usage("Invalid argument\n");*/ | 1122 | /*usage("Invalid argument\n");*/ |
@@ -1059,3 +1137,139 @@ int validate_arguments(void){ | |||
1059 | return OK; | 1137 | return OK; |
1060 | } | 1138 | } |
1061 | 1139 | ||
1140 | #if defined(__sun__) || defined(__solaris__) | ||
1141 | |||
1142 | |||
1143 | /* | ||
1144 | * Copyright @2000, 2003 Martin Kompf, martin@kompf.de | ||
1145 | * | ||
1146 | * Nagios plugins thanks Martin for this code. | ||
1147 | */ | ||
1148 | |||
1149 | /* get a message from a stream; return type of message */ | ||
1150 | static int get_msg(int fd) | ||
1151 | { | ||
1152 | int flags = 0; | ||
1153 | int res, ret; | ||
1154 | ctl_area[0] = 0; | ||
1155 | dat_area[0] = 0; | ||
1156 | ret = 0; | ||
1157 | res = getmsg(fd, &ctl, &dat, &flags); | ||
1158 | |||
1159 | if(res < 0) { | ||
1160 | if(errno == EINTR) { | ||
1161 | return(GOT_INTR); | ||
1162 | } else { | ||
1163 | printf("%s\n", "get_msg FAILED."); | ||
1164 | return(GOT_ERR); | ||
1165 | } | ||
1166 | } | ||
1167 | if(ctl.len > 0) { | ||
1168 | ret |= GOT_CTRL; | ||
1169 | } | ||
1170 | if(dat.len > 0) { | ||
1171 | ret |= GOT_DATA; | ||
1172 | } | ||
1173 | return(ret); | ||
1174 | } | ||
1175 | |||
1176 | /* verify that dl_primitive in ctl_area = prim */ | ||
1177 | static int check_ctrl(int prim) | ||
1178 | { | ||
1179 | dl_error_ack_t *err_ack = (dl_error_ack_t *)ctl_area; | ||
1180 | if(err_ack->dl_primitive != prim) { | ||
1181 | printf("Error: DLPI stream API failed to get MAC in check_ctrl: %s.\n", strerror(errno)); | ||
1182 | exit(STATE_UNKNOWN); | ||
1183 | } | ||
1184 | return 0; | ||
1185 | } | ||
1186 | |||
1187 | /* put a control message on a stream */ | ||
1188 | static int put_ctrl(int fd, int len, int pri) | ||
1189 | { | ||
1190 | ctl.len = len; | ||
1191 | if(putmsg(fd, &ctl, 0, pri) < 0) { | ||
1192 | printf("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n", strerror(errno)); | ||
1193 | exit(STATE_UNKNOWN); | ||
1194 | } | ||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | /* put a control + data message on a stream */ | ||
1199 | static int put_both(int fd, int clen, int dlen, int pri) | ||
1200 | { | ||
1201 | ctl.len = clen; | ||
1202 | dat.len = dlen; | ||
1203 | if(putmsg(fd, &ctl, &dat, pri) < 0) { | ||
1204 | printf("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n", strerror(errno)); | ||
1205 | exit(STATE_UNKNOWN); | ||
1206 | } | ||
1207 | return 0; | ||
1208 | } | ||
1209 | |||
1210 | /* open file descriptor and attach */ | ||
1211 | static int dl_open(const char *dev, int unit, int *fd) | ||
1212 | { | ||
1213 | dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area; | ||
1214 | if((*fd = open(dev, O_RDWR)) == -1) { | ||
1215 | printf("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n", dev, strerror(errno)); | ||
1216 | exit(STATE_UNKNOWN); | ||
1217 | } | ||
1218 | attach_req->dl_primitive = DL_ATTACH_REQ; | ||
1219 | attach_req->dl_ppa = unit; | ||
1220 | put_ctrl(*fd, sizeof(dl_attach_req_t), 0); | ||
1221 | get_msg(*fd); | ||
1222 | return check_ctrl(DL_OK_ACK); | ||
1223 | } | ||
1224 | |||
1225 | /* send DL_BIND_REQ */ | ||
1226 | static int dl_bind(int fd, int sap, u_char *addr) | ||
1227 | { | ||
1228 | dl_bind_req_t *bind_req = (dl_bind_req_t *)ctl_area; | ||
1229 | dl_bind_ack_t *bind_ack = (dl_bind_ack_t *)ctl_area; | ||
1230 | bind_req->dl_primitive = DL_BIND_REQ; | ||
1231 | bind_req->dl_sap = sap; | ||
1232 | bind_req->dl_max_conind = 1; | ||
1233 | bind_req->dl_service_mode = DL_CLDLS; | ||
1234 | bind_req->dl_conn_mgmt = 0; | ||
1235 | bind_req->dl_xidtest_flg = 0; | ||
1236 | put_ctrl(fd, sizeof(dl_bind_req_t), 0); | ||
1237 | get_msg(fd); | ||
1238 | if (GOT_ERR == check_ctrl(DL_BIND_ACK)) { | ||
1239 | printf("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n", strerror(errno)); | ||
1240 | exit(STATE_UNKNOWN); | ||
1241 | } | ||
1242 | bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, | ||
1243 | bind_ack->dl_addr_length); | ||
1244 | return 0; | ||
1245 | } | ||
1246 | |||
1247 | /*********************************************************************** | ||
1248 | * interface: | ||
1249 | * function mac_addr_dlpi - get the mac address of the interface with | ||
1250 | * type dev (eg lnc, hme) and unit (0, 1 ..) | ||
1251 | * | ||
1252 | * parameter: addr: an array of six bytes, has to be allocated by the caller | ||
1253 | * | ||
1254 | * return: 0 if OK, -1 if the address could not be determined | ||
1255 | * | ||
1256 | * | ||
1257 | ***********************************************************************/ | ||
1258 | |||
1259 | long mac_addr_dlpi( const char *dev, int unit, u_char *addr) { | ||
1260 | |||
1261 | int fd; | ||
1262 | u_char mac_addr[25]; | ||
1263 | |||
1264 | if (GOT_ERR != dl_open(dev, unit, &fd)) { | ||
1265 | if (GOT_ERR != dl_bind(fd, INSAP, mac_addr)) { | ||
1266 | bcopy( mac_addr, addr, 6); | ||
1267 | return 0; | ||
1268 | } | ||
1269 | } | ||
1270 | close(fd); | ||
1271 | return -1; | ||
1272 | } | ||
1273 | |||
1274 | #endif | ||
1275 | |||