summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/check_dhcp.c446
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 */
72static u_long ctl_area[AREA_SZ];
73static u_long dat_area[AREA_SZ];
74static struct strbuf ctl = {AREA_SZ, 0, (char *)ctl_area};
75static 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
87static int get_msg(int);
88static int check_ctrl(int);
89static int put_ctrl(int, int, int);
90static int put_both(int, int, int, int);
91static int dl_open(const char *, int, int *);
92static int dl_bind(int, int, u_char *);
93long mac_addr_dlpi( const char *, int, u_char *);
94
54#endif 95#endif
55 96
56const char *progname = "check_dhcp"; 97const 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
167int request_specific_address=FALSE; 207int request_specific_address=FALSE;
168int received_requested_address=FALSE; 208int received_requested_address=FALSE;
209int verbose=0;
169struct in_addr requested_address; 210struct 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 */
235int get_hardware_address(int sock,char *interface_name){ 276int 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 */
1150static 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 */
1177static 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 */
1188static 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 */
1199static 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 */
1211static 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 */
1226static 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
1259long 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