diff options
author | Patrick Cervicek <patrick@cervicek.de> | 2015-10-09 11:46:51 +0200 |
---|---|---|
committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2023-10-01 15:09:20 +0200 |
commit | 11670da398ae4cd68ef2c182d0f688feaf663e26 (patch) | |
tree | 0e82978d7e1356ca2f83c5fba41018ffb812d379 | |
parent | a4c7111f90b00e5060eeebd73b71f67e6e161607 (diff) | |
download | monitoring-plugins-11670da.tar.gz |
check_dhcp.c merged patch from #752
- added dhcp rogue detection
contributed by Patrick Cervicek (patrick AT cervicek.de)
- closes #752
-rw-r--r-- | plugins-root/check_dhcp.c | 92 |
1 files changed, 56 insertions, 36 deletions
diff --git a/plugins-root/check_dhcp.c b/plugins-root/check_dhcp.c index 2d22619b..9aeff2b0 100644 --- a/plugins-root/check_dhcp.c +++ b/plugins-root/check_dhcp.c | |||
@@ -156,6 +156,7 @@ typedef struct dhcp_offer_struct{ | |||
156 | u_int32_t lease_time; /* lease time in seconds */ | 156 | u_int32_t lease_time; /* lease time in seconds */ |
157 | u_int32_t renewal_time; /* renewal time in seconds */ | 157 | u_int32_t renewal_time; /* renewal time in seconds */ |
158 | u_int32_t rebinding_time; /* rebinding time in seconds */ | 158 | u_int32_t rebinding_time; /* rebinding time in seconds */ |
159 | u_int8_t desired; /* is this offer desired (necessary in exclusive mode) */ | ||
159 | struct dhcp_offer_struct *next; | 160 | struct dhcp_offer_struct *next; |
160 | }dhcp_offer; | 161 | }dhcp_offer; |
161 | 162 | ||
@@ -199,6 +200,7 @@ typedef struct requested_server_struct{ | |||
199 | #define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ | 200 | #define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ |
200 | 201 | ||
201 | u_int8_t unicast = 0; /* unicast mode: mimic a DHCP relay */ | 202 | u_int8_t unicast = 0; /* unicast mode: mimic a DHCP relay */ |
203 | u_int8_t exclusive = 0; /* exclusive mode aka "rogue DHCP server detection" */ | ||
202 | struct in_addr my_ip; /* our address (required for relay) */ | 204 | struct in_addr my_ip; /* our address (required for relay) */ |
203 | struct in_addr dhcp_ip; /* server to query (if in unicast mode) */ | 205 | struct in_addr dhcp_ip; /* server to query (if in unicast mode) */ |
204 | unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]=""; | 206 | unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]=""; |
@@ -900,6 +902,7 @@ int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ | |||
900 | new_offer->lease_time=dhcp_lease_time; | 902 | new_offer->lease_time=dhcp_lease_time; |
901 | new_offer->renewal_time=dhcp_renewal_time; | 903 | new_offer->renewal_time=dhcp_renewal_time; |
902 | new_offer->rebinding_time=dhcp_rebinding_time; | 904 | new_offer->rebinding_time=dhcp_rebinding_time; |
905 | new_offer->desired=FALSE; /* exclusive mode: we'll check that in get_results */ | ||
903 | 906 | ||
904 | 907 | ||
905 | if(verbose){ | 908 | if(verbose){ |
@@ -945,7 +948,7 @@ int free_requested_server_list(void){ | |||
945 | 948 | ||
946 | /* gets state and plugin output to return */ | 949 | /* gets state and plugin output to return */ |
947 | int get_results(void){ | 950 | int get_results(void){ |
948 | dhcp_offer *temp_offer; | 951 | dhcp_offer *temp_offer, *undesired_offer=NULL; |
949 | requested_server *temp_server; | 952 | requested_server *temp_server; |
950 | int result; | 953 | int result; |
951 | u_int32_t max_lease_time=0; | 954 | u_int32_t max_lease_time=0; |
@@ -976,16 +979,24 @@ int get_results(void){ | |||
976 | if(temp_server->answered) | 979 | if(temp_server->answered) |
977 | printf(_(" (duplicate)")); | 980 | printf(_(" (duplicate)")); |
978 | printf(_("\n")); | 981 | printf(_("\n")); |
979 | } | 982 | } |
980 | if(temp_server->answered == FALSE){ | 983 | if(temp_server->answered == FALSE){ |
981 | requested_responses++; | 984 | requested_responses++; |
982 | temp_server->answered=TRUE; | 985 | temp_server->answered=TRUE; |
983 | } | 986 | temp_offer->desired=TRUE; |
984 | } | 987 | } |
985 | } | 988 | } |
986 | } | 989 | } |
987 | 990 | } | |
988 | } | 991 | |
992 | /* exclusive mode: check for undesired offers */ | ||
993 | for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next) { | ||
994 | if (temp_offer->desired == FALSE) { | ||
995 | undesired_offer=temp_offer; /* Checks only for the first undesired offer */ | ||
996 | break; /* no further checks needed */ | ||
997 | } | ||
998 | } | ||
999 | } | ||
989 | 1000 | ||
990 | /* else check and see if we got our requested address from any server */ | 1001 | /* else check and see if we got our requested address from any server */ |
991 | else{ | 1002 | else{ |
@@ -999,8 +1010,8 @@ int get_results(void){ | |||
999 | /* see if we got the address we requested */ | 1010 | /* see if we got the address we requested */ |
1000 | if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) | 1011 | if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) |
1001 | received_requested_address=TRUE; | 1012 | received_requested_address=TRUE; |
1002 | } | 1013 | } |
1003 | } | 1014 | } |
1004 | 1015 | ||
1005 | result=STATE_OK; | 1016 | result=STATE_OK; |
1006 | if(valid_responses==0) | 1017 | if(valid_responses==0) |
@@ -1012,6 +1023,9 @@ int get_results(void){ | |||
1012 | else if(request_specific_address==TRUE && received_requested_address==FALSE) | 1023 | else if(request_specific_address==TRUE && received_requested_address==FALSE) |
1013 | result=STATE_WARNING; | 1024 | result=STATE_WARNING; |
1014 | 1025 | ||
1026 | if(exclusive && undesired_offer) | ||
1027 | result=STATE_CRITICAL; | ||
1028 | |||
1015 | if(result==0) /* garrett honeycutt 2005 */ | 1029 | if(result==0) /* garrett honeycutt 2005 */ |
1016 | printf("OK: "); | 1030 | printf("OK: "); |
1017 | else if(result==1) | 1031 | else if(result==1) |
@@ -1029,6 +1043,13 @@ int get_results(void){ | |||
1029 | 1043 | ||
1030 | printf(_("Received %d DHCPOFFER(s)"),valid_responses); | 1044 | printf(_("Received %d DHCPOFFER(s)"),valid_responses); |
1031 | 1045 | ||
1046 | |||
1047 | if(exclusive && undesired_offer){ | ||
1048 | printf(_(", Rogue DHCP Server detected! Server %s"),inet_ntoa(undesired_offer->server_address)); | ||
1049 | printf(_(" offered %s \n"),inet_ntoa(undesired_offer->offered_address)); | ||
1050 | return result; | ||
1051 | } | ||
1052 | |||
1032 | if(requested_servers>0) | 1053 | if(requested_servers>0) |
1033 | printf(_(", %s%d of %d requested servers responded"),((requested_responses<requested_servers) && requested_responses>0)?"only ":"",requested_responses,requested_servers); | 1054 | printf(_(", %s%d of %d requested servers responded"),((requested_responses<requested_servers) && requested_responses>0)?"only ":"",requested_responses,requested_servers); |
1034 | 1055 | ||
@@ -1071,16 +1092,16 @@ int call_getopt(int argc, char **argv){ | |||
1071 | {"interface", required_argument,0,'i'}, | 1092 | {"interface", required_argument,0,'i'}, |
1072 | {"mac", required_argument,0,'m'}, | 1093 | {"mac", required_argument,0,'m'}, |
1073 | {"unicast", no_argument, 0,'u'}, | 1094 | {"unicast", no_argument, 0,'u'}, |
1095 | {"exclusive", no_argument, 0,'x'}, | ||
1074 | {"verbose", no_argument, 0,'v'}, | 1096 | {"verbose", no_argument, 0,'v'}, |
1075 | {"version", no_argument, 0,'V'}, | 1097 | {"version", no_argument, 0,'V'}, |
1076 | {"help", no_argument, 0,'h'}, | 1098 | {"help", no_argument, 0,'h'}, |
1077 | {0,0,0,0} | 1099 | {0,0,0,0} |
1078 | }; | 1100 | }; |
1079 | 1101 | ||
1102 | int c=0; | ||
1080 | while(1){ | 1103 | while(1){ |
1081 | int c=0; | 1104 | c=getopt_long(argc,argv,"+hVvxt:s:r:t:i:m:u",long_options,&option_index); |
1082 | |||
1083 | c=getopt_long(argc,argv,"+hVvt:s:r:t:i:m:u",long_options,&option_index); | ||
1084 | 1105 | ||
1085 | if(c==-1||c==EOF||c==1) | 1106 | if(c==-1||c==EOF||c==1) |
1086 | break; | 1107 | break; |
@@ -1129,6 +1150,9 @@ int call_getopt(int argc, char **argv){ | |||
1129 | case 'u': /* unicast testing */ | 1150 | case 'u': /* unicast testing */ |
1130 | unicast=1; | 1151 | unicast=1; |
1131 | break; | 1152 | break; |
1153 | case 'x': /* exclusive testing aka "rogue DHCP server detection" */ | ||
1154 | exclusive=1; | ||
1155 | break; | ||
1132 | 1156 | ||
1133 | case 'V': /* version */ | 1157 | case 'V': /* version */ |
1134 | print_revision(progname, NP_VERSION); | 1158 | print_revision(progname, NP_VERSION); |
@@ -1142,10 +1166,6 @@ int call_getopt(int argc, char **argv){ | |||
1142 | verbose=1; | 1166 | verbose=1; |
1143 | break; | 1167 | break; |
1144 | 1168 | ||
1145 | case '?': /* help */ | ||
1146 | usage5 (); | ||
1147 | break; | ||
1148 | |||
1149 | default: | 1169 | default: |
1150 | break; | 1170 | break; |
1151 | } | 1171 | } |
@@ -1357,7 +1377,7 @@ void print_help(void){ | |||
1357 | 1377 | ||
1358 | printf("%s\n", _("This plugin tests the availability of DHCP servers on a network.")); | 1378 | printf("%s\n", _("This plugin tests the availability of DHCP servers on a network.")); |
1359 | 1379 | ||
1360 | printf ("\n\n"); | 1380 | printf ("\n\n"); |
1361 | 1381 | ||
1362 | print_usage(); | 1382 | print_usage(); |
1363 | 1383 | ||
@@ -1367,19 +1387,21 @@ void print_help(void){ | |||
1367 | printf (UT_VERBOSE); | 1387 | printf (UT_VERBOSE); |
1368 | 1388 | ||
1369 | printf (" %s\n", "-s, --serverip=IPADDRESS"); | 1389 | printf (" %s\n", "-s, --serverip=IPADDRESS"); |
1370 | printf (" %s\n", _("IP address of DHCP server that we must hear from")); | 1390 | printf (" %s\n", _("IP address of DHCP server that we must hear from")); |
1371 | printf (" %s\n", "-r, --requestedip=IPADDRESS"); | 1391 | printf (" %s\n", "-r, --requestedip=IPADDRESS"); |
1372 | printf (" %s\n", _("IP address that should be offered by at least one DHCP server")); | 1392 | printf (" %s\n", _("IP address that should be offered by at least one DHCP server")); |
1373 | printf (" %s\n", "-t, --timeout=INTEGER"); | 1393 | printf (" %s\n", "-t, --timeout=INTEGER"); |
1374 | printf (" %s\n", _("Seconds to wait for DHCPOFFER before timeout occurs")); | 1394 | printf (" %s\n", _("Seconds to wait for DHCPOFFER before timeout occurs")); |
1375 | printf (" %s\n", "-i, --interface=STRING"); | 1395 | printf (" %s\n", "-i, --interface=STRING"); |
1376 | printf (" %s\n", _("Interface to to use for listening (i.e. eth0)")); | 1396 | printf (" %s\n", _("Interface to to use for listening (i.e. eth0)")); |
1377 | printf (" %s\n", "-m, --mac=STRING"); | 1397 | printf (" %s\n", "-m, --mac=STRING"); |
1378 | printf (" %s\n", _("MAC address to use in the DHCP request")); | 1398 | printf (" %s\n", _("MAC address to use in the DHCP request")); |
1379 | printf (" %s\n", "-u, --unicast"); | 1399 | printf (" %s\n", "-u, --unicast"); |
1380 | printf (" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s")); | 1400 | printf (" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s")); |
1381 | 1401 | printf (" %s\n", "-x, --exclusive"); | |
1382 | printf (UT_SUPPORT); | 1402 | printf (" %s\n", _("Only requested DHCP server may response (rogue DHCP server detection), requires -s")); |
1403 | |||
1404 | printf (UT_SUPPORT); | ||
1383 | return; | 1405 | return; |
1384 | } | 1406 | } |
1385 | 1407 | ||
@@ -1387,12 +1409,10 @@ void print_help(void){ | |||
1387 | void | 1409 | void |
1388 | print_usage(void){ | 1410 | print_usage(void){ |
1389 | 1411 | ||
1390 | printf ("%s\n", _("Usage:")); | 1412 | printf ("%s\n", _("Usage:")); |
1391 | printf (" %s [-v] [-u] [-s serverip] [-r requestedip] [-t timeout]\n",progname); | 1413 | printf (" %s [-v] [-u] [-x] [-s serverip] [-r requestedip] [-t timeout]\n",progname); |
1392 | printf (" [-i interface] [-m mac]\n"); | 1414 | printf (" [-i interface] [-m mac]\n"); |
1393 | 1415 | ||
1394 | return; | 1416 | return; |
1395 | } | 1417 | } |
1396 | 1418 | ||
1397 | |||
1398 | |||