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 ee893cd2..5c3c199d 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 | |||
