1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
--- check_dhcp.c.orig 2007-12-14 21:04:26.000000000 +0100
+++ check_dhcp.c 2007-12-15 16:04:12.000000000 +0100
@@ -165,6 +165,7 @@
u_int32_t lease_time; /* lease time in seconds */
u_int32_t renewal_time; /* renewal time in seconds */
u_int32_t rebinding_time; /* rebinding time in seconds */
+ u_int8_t desired; /* is this offer desired (necessary in exclusive mode) */
struct dhcp_offer_struct *next;
}dhcp_offer;
@@ -209,6 +210,7 @@
#define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */
u_int8_t unicast = 0; /* unicast mode: mimic a DHCP relay */
+u_int8_t exclusive = 0; /* exclusive mode aka "rogue DHCP server detection" */
struct in_addr my_ip; /* our address (required for relay) */
struct in_addr dhcp_ip; /* server to query (if in unicast mode) */
unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]="";
@@ -919,6 +921,7 @@
new_offer->lease_time=dhcp_lease_time;
new_offer->renewal_time=dhcp_renewal_time;
new_offer->rebinding_time=dhcp_rebinding_time;
+ new_offer->desired=FALSE; /* exclusive mode: we'll check that in get_results */
if(verbose){
@@ -964,7 +967,7 @@
/* gets state and plugin output to return */
int get_results(void){
- dhcp_offer *temp_offer;
+ dhcp_offer *temp_offer, *undesired_offer=NULL;
requested_server *temp_server;
int result;
u_int32_t max_lease_time=0;
@@ -999,11 +1002,18 @@
if(temp_server->answered == FALSE){
requested_responses++;
temp_server->answered=TRUE;
+ temp_offer->desired=TRUE;
}
}
}
}
+ /* exclusive mode: check for undesired offers */
+ for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next)
+ if (temp_offer->desired == FALSE) {
+ undesired_offer=temp_offer; /* Checks only for the first undesired offer */
+ break; /* no further checks needed */
+ }
}
/* else check and see if we got our requested address from any server */
@@ -1030,6 +1040,9 @@
result=STATE_WARNING;
else if(request_specific_address==TRUE && received_requested_address==FALSE)
result=STATE_WARNING;
+
+ if(exclusive && undesired_offer)
+ result=STATE_CRITICAL;
if(result==0) /* garrett honeycutt 2005 */
printf("OK: ");
@@ -1046,6 +1059,12 @@
return result;
}
+ if(exclusive && undesired_offer){
+ printf(_("Rogue DHCP Server detected! Server %s"),inet_ntoa(undesired_offer->server_address));
+ printf(_(" offered %s \n"),inet_ntoa(undesired_offer->offered_address));
+ return result;
+ }
+
printf(_("Received %d DHCPOFFER(s)"),valid_responses);
if(requested_servers>0)
@@ -1100,6 +1119,7 @@
{"interface", required_argument,0,'i'},
{"mac", required_argument,0,'m'},
{"unicast", no_argument, 0,'u'},
+ {"exclusive", no_argument, 0,'x'},
{"verbose", no_argument, 0,'v'},
{"version", no_argument, 0,'V'},
{"help", no_argument, 0,'h'},
@@ -1107,7 +1127,7 @@
};
while(1){
- c=getopt_long(argc,argv,"+hVvt:s:r:t:i:m:u",long_options,&option_index);
+ c=getopt_long(argc,argv,"+hVvxt:s:r:t:i:m:u",long_options,&option_index);
i++;
@@ -1170,6 +1190,10 @@
unicast=1;
break;
+ case 'x': /* exclusive testing aka "rogue DHCP server detection" */
+ exclusive=1;
+ break;
+
case 'V': /* version */
print_revision(progname,revision);
exit(STATE_OK);
@@ -1415,6 +1439,8 @@
printf (" %s\n", _("MAC address to use in the DHCP request"));
printf (" %s\n", "-u, --unicast");
printf (" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s"));
+ printf (" %s\n", "-x, --exclusive");
+ printf (" %s\n", _("Only requested DHCP server may response (rogue DHCP server detection), requires -s"));
return;
}
@@ -1424,7 +1450,7 @@
print_usage(void){
printf (_("Usage:"));
- printf (" %s [-v] [-u] [-s serverip] [-r requestedip] [-t timeout]\n",progname);
+ printf (" %s [-v] [-u] [-x] [-s serverip] [-r requestedip] [-t timeout]\n",progname);
printf (" [-i interface] [-m mac]\n");
return;
|