1 /* dhcp_probe:
2 
3 	Broadcast BOOTPREQUEST, DHCPDISCOVER, and DHCPREQUEST packets out specified interfaces,
4 	listen for answers, discard those from known "good" servers, log the others.
5 	The intent is to provide a way to find rogue BootP and DHCP servers.
6 	This will only find rogue servers that happen to answer us; rogue servers configured to
7 	only answer a selected set of clients will not be discovered.
8 */
9 
10 /* Copyright (c) 2000-2021, The Trustees of Princeton University, All Rights Reserved. */
11 
12 
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16 
17 #include "defs.h"
18 #include "defaults.h"
19 
20 #include "dhcp_probe.h"
21 #include "bootp.h"
22 #include "daemonize.h"
23 #include "get_myeaddr.h"
24 #include "get_myipaddr.h"
25 #include "configfile.h"
26 #include "report.h"
27 #include "utils.h"
28 
29 #ifndef lint
30 static const char rcsid[] = "dhcp_probe version " VERSION;
31 static const char copyright[] = "Copyright 2000-2021, The Trustees of Princeton University.  All rights reserved.";
32 static const char contact[] = "networking at princeton dot edu";
33 #endif
34 
35 /* initialize options to defaults */
36 int debug = 0;
37 int dont_fork = 0;
38 char *config_file = CONFIG_FILE;
39 char *pid_file = PID_FILE;
40 char *capture_file = NULL;
41 /* Init snaplen to the max number of bytes we might need to capture in response to a single packet we send.
42    This needs to include the complete size of the ethernet frame.
43    Of course, we can't really know this ahead of time; who knows how many servers out there might
44    answer us, and how large their responses might be?
45    The simplest approach is to just overestimate generously.  Although a normal reply is under 600 bytes,
46    nothing prevents someone from sending maximum-size Ethernet frames (1514 bytes) as responses.
47    So if you want to be prepared to handle 20 responses to a single packet, you would set snaplen to 20*1514.
48    Note than since pcap_open_live() declares this an 'int', don't specify a value larger than that.
49 */
50 int snaplen = CAPTURE_BUFSIZE;
51 int socket_receive_timeout_feature = 0;
52 
53 char *prog = NULL;
54 char *logfile_name = NULL;
55 
56 int sockfd;
57 
58 volatile sig_atomic_t reread_config_file; /* for signal handler */
59 volatile sig_atomic_t reopen_log_file; /* for signal handler */
60 volatile sig_atomic_t reopen_capture_file; /* for signal handler */
61 volatile sig_atomic_t quit_requested; /* for signal handler */
62 volatile sig_atomic_t alarm_fired; /* for signal handler */
63 
64 pcap_t *pd = NULL;					/* libpcap - packet capture descriptor used for actual packet capture */
65 pcap_t *pd_template = NULL;			/* libpcap - packet capture descriptor just used as template */
66 
67 pcap_dumper_t *pcap_dump_d = NULL;	/* libpcap - dump descriptor */
68 
69 /* An array listing all the valid packet flavors we may write */
70 enum dhcp_flavor_t packet_flavors[] = {BOOTP, DHCP_INIT, DHCP_SELECTING, DHCP_INIT_REBOOT, DHCP_REBINDING};
71 
72 char *ifname;
73 struct libnet_ether_addr my_eaddr;
74 
75 int use_8021q = 0;
76 int vlan_id = 0;
77 
78 int
main(int argc,char ** argv)79 main(int argc, char **argv)
80 {
81 	int c, errflag=0;
82 	extern char *optarg;
83 	extern int optind, opterr, optopt;
84 	struct sigaction sa;
85 	FILE *pid_fp;
86 	char *cwd = CWD;
87 
88 	int write_packet_len;
89 	int bytes_written;
90 
91 	unsigned int time_to_sleep;
92 	sigset_t new_sigset, old_sigset;
93 	int receive_and_process_responses_rc;
94 
95 	/* for libpcap */
96 	struct bpf_program bpf_code;
97 	int linktype;
98 	char pcap_errbuf[PCAP_ERRBUF_SIZE];
99 
100 	/* get progname = last component of argv[0] */
101 	prog = strrchr(argv[0], '/');
102 	if (prog)
103 		prog++;
104 	else
105 		prog = argv[0];
106 
107 	while ((c = getopt(argc, argv, "c:d:fhl:o:p:Q:s:Tvw:")) != EOF) {
108 		switch (c) {
109 			case 'c':
110 				if (optarg[0] != '/') {
111 					fprintf(stderr, "%s: invalid config file '%s', must be an absolute pathname\n", prog, optarg);
112 					errflag++;
113 					break;
114 				}
115 				config_file = optarg;
116 				break;
117 			case 'd': {
118 				char *stmp = optarg;
119 				if ((sscanf(stmp, "%d", &debug) != 1) || (debug < 0)) {
120 					fprintf(stderr, "%s: invalid debug level '%s'\n", prog, optarg);
121 					debug = 0;
122 					errflag++;
123 				}
124 				break;
125 			}
126 			case 'f':
127 				dont_fork = 1;
128 				break;
129 			case 'h':
130 				usage();
131 				my_exit(0, 0, 0);
132 			case 'l':
133 				if (optarg[0] != '/') {
134 					fprintf(stderr, "%s: invalid log file '%s', must be an absolute pathname\n", prog, optarg);
135 					errflag++;
136 					break;
137 				}
138 				logfile_name = optarg;
139 				break;
140 			case 'o':
141 				if (optarg[0] != '/') {
142 					fprintf(stderr, "%s: invalid capture file '%s', must be an absolute pathname\n", prog, optarg);
143 					errflag++;
144 					break;
145 				}
146 				capture_file = optarg;
147 				break;
148 			case 'p':
149 				if (optarg[0] != '/') {
150 					fprintf(stderr, "%s: invalid pid file '%s', must be an absolute pathname\n", prog, optarg);
151 					errflag++;
152 					break;
153 				}
154 				pid_file = optarg;
155 				break;
156 			case 'Q': {
157 				char *stmp = optarg;
158 				if ((sscanf(stmp, "%d", &vlan_id) != 1) || (vlan_id < VLAN_ID_MIN) || (vlan_id > VLAN_ID_MAX)) {
159 					fprintf(stderr, "%s: invalid vlan ID '%s', must be integer %d ... %d\n", prog, optarg, VLAN_ID_MIN, VLAN_ID_MAX);
160 					errflag++;
161 				} else {
162 					use_8021q++;
163 				}
164 				break;
165 			}
166 			case 's': {
167 				char *stmp = optarg;
168 				/* XXX sscanf() silently forces to integer range.  If you specify a value outside
169 				   the range, and the conversion results in a positive value within the range, we
170 				   will silently use the converted value.
171 				*/
172 				if ((sscanf(stmp, "%d", &snaplen) != 1) || (snaplen < 1)) {
173 					fprintf(stderr, "%s: invalid capture buffer size '%s'\n", prog, optarg);
174 					snaplen = CAPTURE_BUFSIZE;
175 					errflag++;
176 				}
177 				break;
178 			}
179 			case 'T':
180 				socket_receive_timeout_feature = 1;
181 				break;
182 			case 'v':
183 				printf("DHCP Probe version %s\n", VERSION);
184 				my_exit(0, 0, 0);
185 			case 'w':
186 				if (optarg[0] != '/') {
187 					fprintf(stderr, "%s: invalid working directory '%s', must be an absolute pathname\n", prog, optarg);
188 					errflag++;
189 					break;
190 				}
191 				cwd = optarg;
192 				break;
193 			case '?':
194 				usage();
195 				my_exit(0, 0, 0);
196 			default:
197 				errflag++;
198 				break;
199 		}
200 	}
201 	if (optind == argc || errflag) {
202 		usage();
203 		my_exit(1, 0, 1);
204 	}
205 
206 	if (! dont_fork)
207 		daemonize();
208 
209 	/* initialize logging */
210 	report_init(dont_fork, logfile_name);
211 
212 	if (chdir(cwd) < 0) {
213 		report(LOG_ERR, "chdir(%s): %s", cwd, get_errmsg());
214 		my_exit(1, 0, 1);
215 	}
216 
217 	report(LOG_NOTICE, "starting, version %s", VERSION);
218 
219 	/* Before writing our pid, prepare to respond reasonably if we get any of our supported signals.
220 			SIGHUP,SIGUSR1,SIGUSR2 - ignore until our internal data structs are ready for it
221 			SIGINT,SIGTERM,SIGQUIT - leave default for now, so it will still kill us, but not try to look at uninit'd pcap structs
222 	*/
223 	if (dont_fork) { /* we didn't daemonize earlier */
224 		/* ignore SIGHUP */
225 		sigemptyset(&sa.sa_mask);
226 		sa.sa_handler = SIG_IGN;
227 		if (sigaction(SIGHUP, &sa, NULL) < 0) {
228 			report(LOG_ERR, "sigaction: %s", get_errmsg());
229 			my_exit(1, 0, 1);
230 		}
231 	} /* else we already set SIGHUP to ignore while daemonizing, so we don't need to do it again */
232 	/* ignore SIGUSR1 */
233 	sigemptyset(&sa.sa_mask);
234 	sa.sa_handler = SIG_IGN;
235 	if (sigaction(SIGUSR1, &sa, NULL) < 0) {
236 		report(LOG_ERR, "sigaction: %s", get_errmsg());
237 		my_exit(1, 0, 1);
238 	}
239 	/* ignore SIGUSR2 */
240 	sigemptyset(&sa.sa_mask);
241 	sa.sa_handler = SIG_IGN;
242 	if (sigaction(SIGUSR2, &sa, NULL) < 0) {
243 		report(LOG_ERR, "sigaction: %s", get_errmsg());
244 		my_exit(1, 0, 1);
245 	}
246 
247 
248 	/* write pid file as soon as possible after (possibly) forking */
249 	if ((pid_fp = open_for_writing(pid_file)) == NULL) {
250 		report(LOG_ERR, "could not open pid file %s for writing", pid_file);
251 		my_exit(1, 0, 1);
252 	} else {
253 		fprintf(pid_fp, "%d\n", (int) getpid());
254 		fclose(pid_fp);
255 	}
256 
257 	if (! read_configfile(config_file)) {
258 		my_exit(1, 1, 1);
259 	}
260 
261 	reread_config_file = 0; /* set by signal handler */
262 	reopen_log_file = 0; /* set by signal handler */
263 	reopen_capture_file = 0; /* set by signal handler */
264 	quit_requested = 0;
265 	alarm_fired = 0;
266 
267 	ifname = strdup(argv[optind]); /* interface name is a required final argument */
268 
269 	/* general purpose dgram socket for various uses */
270 	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
271 		report(LOG_ERR, "socket(): %s", get_errmsg());
272 		my_exit(1, 1, 1);
273 	}
274 
275 	if (GetDo_not_lookup_enet_and_ip_addresses()) {
276 		/* Do not lookup Ethernet address and IP address for the named interface.
277 		   Instead, use ether_src explicitly specified in config file.
278 		*/
279 
280 		/* read_configfile() guarantees that when GetDo_not_lookup_enet_and_ip_addresses() is true,
281 		   ether_src was specified in the config file, so GetEther_src() will return that value.
282 		*/
283 		bcopy(GetEther_src(), &my_eaddr, sizeof(my_eaddr));
284 
285 	} else {
286 		struct in_addr my_ipaddr;
287 
288 		/* We need to know the Ethernet address for the named interface, but don't have a direct
289 	   	way to look that up.
290 	   	So we go the roundabout route of looking up the (first) IP address associated with that interface,
291 	   	then looking in our ARP cache for this IP address to see the associated ethernet address. */
292 
293 		/* lookup IP address for specified interface */
294 		if (get_myipaddr(sockfd, ifname, &my_ipaddr) < 0) {
295 			report(LOG_ERR, "couldn't determine IP addr for interface %s", ifname);
296 			my_exit(1, 1, 1);
297 		}
298 
299 		/* lookup ethernet address for specified IP address */
300 		/* note that my_eaddr must be init'd before calling GetChaddr() */
301 		if (get_myeaddr(sockfd, &my_ipaddr, &my_eaddr, ifname) < 0) {
302 			report(LOG_ERR, "couldn't determine my ethernet addr for my IP address %s", inet_ntoa(my_ipaddr));
303 			my_exit(1, 1, 1);
304 		}
305 	}
306 
307 	if (debug > 0) {
308 		if (use_8021q) {
309 			report(LOG_INFO, "using interface %s, 802.1Q VLAN ID %d, hardware address %s",
310 				ifname, vlan_id, ether_ntoa(&my_eaddr));
311 		} else {
312 			report(LOG_INFO, "using interface %s, no 802.1Q, hardware address %s",
313 				ifname, ether_ntoa(&my_eaddr));
314 		}
315 		if (socket_receive_timeout_feature)
316 			report(LOG_INFO, "socket receive timeout feature enabled");
317 	}
318 
319 	/* We're ready to handle SIGINT, SIGTERM, SIGQUIT ourself */
320 	sigemptyset(&sa.sa_mask);
321 	sa.sa_handler = catcher;
322 	sa.sa_flags = 0;
323 	if (sigaction(SIGINT, &sa, NULL) < 0) {
324 		report(LOG_ERR, "sigaction: %s", get_errmsg());
325 		my_exit(1, 1, 1);
326 	}
327 	sigemptyset(&sa.sa_mask);
328 	sa.sa_handler = catcher;
329 	sa.sa_flags = 0;
330 	if (sigaction(SIGTERM, &sa, NULL) < 0) {
331 		report(LOG_ERR, "sigaction: %s", get_errmsg());
332 		my_exit(1, 1, 1);
333 	}
334 	sigemptyset(&sa.sa_mask);
335 	sa.sa_handler = catcher;
336 	sa.sa_flags = 0;
337 	if (sigaction(SIGQUIT, &sa, NULL) < 0) {
338 		report(LOG_ERR, "sigaction: %s", get_errmsg());
339 		my_exit(1, 1, 1);
340 	}
341 
342 
343 
344 	/* install SIGHUP handler to re-read config files on demand */
345 	sigemptyset(&sa.sa_mask);
346 	sa.sa_handler = catcher;
347 	sa.sa_flags = 0;
348 	if (sigaction(SIGHUP, &sa, NULL) < 0) {
349 		report(LOG_ERR, "sigaction: %s", get_errmsg());
350 		my_exit(1, 1, 1);
351 	}
352 
353 	/* install SIGUSR1 handler to close/re-open logfile (if logfile being used) */
354 	sigemptyset(&sa.sa_mask);
355 	sa.sa_handler = catcher;
356 	sa.sa_flags = 0;
357 	if (sigaction(SIGUSR1, &sa, NULL) < 0) {
358 		report(LOG_ERR, "sigaction: %s", get_errmsg());
359 		my_exit(1, 1, 1);
360 	}
361 
362 	/* install SIGUSR2 handler to close/re-open capture file (if capture file being used) */
363 	sigemptyset(&sa.sa_mask);
364 	sa.sa_handler = catcher;
365 	sa.sa_flags = 0;
366 	if (sigaction(SIGUSR2, &sa, NULL) < 0) {
367 		report(LOG_ERR, "sigaction: %s", get_errmsg());
368 		my_exit(1, 1, 1);
369 	}
370 
371 	/* install SIGCHLD handler to reap children (e.g. when alert_program_name or alert_program_name2 is specified */
372 	sigemptyset(&sa.sa_mask);
373 	sa.sa_handler = catcher;
374 	sa.sa_flags = 0;
375 	if (sigaction(SIGCHLD, &sa, NULL) < 0) {
376 		report(LOG_ERR, "sigaction: %s", get_errmsg());
377 		my_exit(1, 1, 1);
378 	}
379 
380 	/* install SIGALRM handler to handle timer expirations. */
381 	sigemptyset(&sa.sa_mask);
382 	sa.sa_handler = catcher;
383 	sa.sa_flags = 0;
384 	if (sigaction(SIGALRM, &sa, NULL) < 0) {
385 		report(LOG_ERR, "sigaction: %s", get_errmsg());
386 		my_exit(1, 1, 1);
387 	}
388 
389 	/* each packet we may write is the same length */
390 	write_packet_len = LIBNET_IPV4_H + LIBNET_UDP_H + sizeof(struct bootp);
391 	if (use_8021q) {
392 		write_packet_len +=  LIBNET_802_1Q_H;
393 	} else {
394 		write_packet_len +=  LIBNET_ETH_H;
395 	}
396 
397 	/* init all the frames we may write */
398 	if (! init_libnet_context_queue()) {
399 		my_exit(1, 1, 1);
400 	}
401 
402 	if (capture_file) { /* we are saving unexpected responses to a capture file */
403 
404 		/* open a packet capture descriptor
405 		   This is NOT the one we'll actually use to read the interface to capture packets!
406 		   When we call pcap_dump_open() to open a savefile, we're supposed to pass it the packet capture descriptor;
407 		   that's just so pcap_dump_open() can figure out what sort of interface and snaplen are involved -- it needs
408 		   to squirrel that info away to write a good header into the dump file, and to know how many bytes to
409 		   write for each packet.  The problem is that we're not going to keep capturing from a single
410 		   packet capture descriptor; instead we open and close packet capture descriptors repeatedly, to allow
411 		   us to NOT be listening when we don't need to (and also to vary some capture parms based on the changing cf file).
412 		   To avoid having to open and close our dump file repeatedly (each time writing a *unique* dump file), we will open
413 		   a SECOND packet capture descriptor 'pd_template' which we'll keep open for the program's life.  That
414 		   one will share the key characteristics with the ones we actually use to capture packets (i.e. interface and snaplen).
415 		   Note this implies we must not let the user change those values during the run.
416 		*/
417 		pcap_errbuf[0] = '\0'; /* so we can tell if a warning was produced on success */
418 		if ((pd_template = pcap_open_live(ifname, snaplen, 0, 1, pcap_errbuf)) == NULL) {
419 			report(LOG_ERR, "pcap_open_live %s: %s", ifname, pcap_errbuf);
420 			my_exit(1, 1, 1);
421 		}
422 		if (pcap_errbuf[0] != '\0')
423 			/* even on success, a warning may be produced */
424 			report(LOG_WARNING, "pcap_open_live %s: %s", ifname, pcap_errbuf);
425 
426 		/* XXX Note pcap_dump_open() does does an fopen() on capture_file with mode "w", and writes
427 		   a pcap header to it.  It's up to the user to ensure the capture_file specified is safe.
428 		   Since we are probably running as root, opportunities for abuse abound.  The user
429 		   must be careful to specify a capture_file located in a directory no one else may write to,
430 		   and to ensure the capture_file does not exist, or if it does, it safe to overwrite.
431 		*/
432 		if ((pcap_dump_d = pcap_dump_open(pd_template, capture_file)) == NULL) {
433 			report(LOG_ERR, "pcap_dump_open: %s", pcap_geterr(pd_template));
434 			my_exit(1, 1, 1);
435 		}
436 	}
437 
438 	while (1) { /* MAIN EVENT LOOP */
439 		int promiscuous;
440 		libnet_t *l;						/* to iterate through libnet context queue */
441 		/* struct pcap_stat ps;	*/			/* to hold pcap stats */
442 
443 		if (debug > 10)
444 			report(LOG_DEBUG, "starting new cycle");
445 
446 		/* handle signals.
447 		   If this is not the first time through the main event loop, this
448 		   is where signals that arrived while we were sleeping get handled.  Note that
449 		   we also handle signals at a second location in the main event loop (after capturing responses
450 		   before we go to sleep).
451 		*/
452 		if (quit_requested) { /* set by signal handler */
453 			if (debug > 1)
454 				report(LOG_INFO, "received request to quit");
455 			break;
456 		}
457 		if (reopen_log_file) { /* set by signal handler */
458 			close_and_reopen_log_file(logfile_name);
459 			reopen_log_file = 0;
460 		}
461 		if (reopen_capture_file) { /* set by signal handler */
462 			close_and_reopen_capture_file();
463 			reopen_capture_file = 0;
464 		}
465 		if (reread_config_file)	{ /* set by signal handler */
466 			reconfigure(write_packet_len);
467 			reread_config_file = 0;
468 		}
469 
470 
471 		/* We open (and later close) the packet capture descriptor on each packet sent (rather than just
472 		   once for the entire program) because a change in the configfile (specifically, 'chaddr')
473 		   can change whether we need to listen promiscuously or not, and GetResponse_wait_time().
474 		   And we need to do it for each sent packet (as opposed to each cycle) to be able to specify
475 		   a fresh timeout each time, apparently (???).
476 		   Too, if we are listening promiscuously and the cycle_time is long, we'd prefer to leave the
477 		   interface in promiscuous mode as little as possible, since that can affect the host's performance.
478 		*/
479 
480 		/* If we're going to claim a chaddr different than my_eaddr, some of the responses
481 		   may come back to chaddr (as opposed to my_eaddr or broadcast), so we'll need to
482 		   listen promiscuously.
483 		   If we're going to claim an ether_src different than my_eaddr, in theory that should
484 		   make no difference; bootp/dhcp servers should rely on chaddr, not ether_src.  Still,
485 		   it's possible there's a server out there that does it wrong, and might therefore mistakenly
486 		   send responses to ether_src.  So lets also listen promiscuously if ether_src != my_eaddr.
487 		*/
488 		if (bcmp(GetChaddr(), &my_eaddr, sizeof(struct libnet_ether_addr)) ||
489 		    bcmp(GetEther_src(), &my_eaddr, sizeof(struct libnet_ether_addr)))
490 			promiscuous = 1;
491 		else
492 			promiscuous = 0;
493 
494 
495 		for (l = libnet_cq_head(); libnet_cq_last(); l = libnet_cq_next()) { /* write one flavor packet and listen for answers */
496 
497 			int packets_recv;
498 			int pcap_open_retries;
499 
500 			/* We set up for packet capture BEFORE writing our packet, to minimize the delay
501 			   between our writing and when we are able to start capturing.  (I cannot tell from
502 			   the pcap(3) doc whether packets matching the filter that arrive after pcap_open_live()
503 			   and before pcap_loop() are actually captured and buffered.  I assume not, if only because
504 			   that would imply that until calling pcap_setfilter(), we'd be capturing and buffering more than
505 			   we wanted!
506 			*/
507 
508 			/* open packet capture descriptor */
509 			/* XXX On Solaris 7, sometimes pcap_open_live() fails with a message like:
510 					pcap_open_live qfe0: recv_ack: info unexpected primitive ack 0x8
511 			   It's not clear what causes this, or what the 0x8 code indicates.
512 			   The error appears to be transient; retrying sometimes will work, so I've wrapped the call in a retry loop.
513 			   I've also added a delay after each failure; perhaps the failure has something to do with the fact that
514 			   we call pcap_open_live() so soon after pcap_close() (for the second and succeeding packets in each cycle);
515 			   adding a delay might help in that case.
516 			*/
517 			pcap_open_retries = PCAP_OPEN_LIVE_RETRY_MAX;
518 			while (pcap_open_retries--) {
519 				pcap_errbuf[0] = '\0'; /* so we can tell if a warning was produced on success */
520 				if ((pd = pcap_open_live(ifname, snaplen, promiscuous, GetResponse_wait_time(), pcap_errbuf)) != NULL) {
521 					break; /* success */
522 				} else { /* failure */
523 					if (pcap_open_retries == 0) {
524 						report(LOG_DEBUG, "pcap_open_live(%s): %s; retry count (%d) exceeded, giving up", ifname, pcap_errbuf, PCAP_OPEN_LIVE_RETRY_MAX);
525 						my_exit(1, 1, 1);
526 					} else {
527 						if (debug > 1)
528 							report(LOG_DEBUG, "pcap_open_live(%s): %s; will retry", ifname, pcap_errbuf);
529 						sleep(PCAP_OPEN_LIVE_RETRY_DELAY); /* before next retry */
530 					}
531 				} /* failure */
532 			}
533 			if (pcap_errbuf[0] != '\0')
534 				/* even on success, a warning may be produced */
535 				report(LOG_WARNING, "pcap_open_live(%s): succeeded but with warning: %s", ifname, pcap_errbuf);
536 
537 			/* make sure this interface is ethernet */
538 			linktype = pcap_datalink(pd);
539 			if (linktype != DLT_EN10MB) {
540 				/* In libpcap 0.9.8 on Solaris 9 SPARC, this only happened if you pointed us to an interface
541 				   that truly had the wrong datalink type.
542 				   It was not a transient error, so we exited.
543 				   However, by libpcap version 1.1.1 on Solaris 9 SPARC, this happens from time to time;
544 				   pcap_datalink() returns 0, indicating DLT_NULL.
545 				   Perhaps that's a bug introduced after libpcap 0.9.8.
546 				   As this seems to be a transient error, we no longer exit, but instead just log the error,
547 				   and skip the rest of the current cycle.
548 				   A side effect of this change is that when you DO mistakenly point dhcp_probe to
549 				   a non-Ethernet interface (the error is not transient), we keep trying instead
550 				   of exiting.  If a future libpcap change returns to the old behavior (where the
551 				   interface type remains consistent), we should go back to the old behavior of exiting.
552 				*/
553 				/*
554 				report(LOG_ERR, "interface %s link layer type %d not ethernet", ifname, linktype);
555 				my_exit(1, 1, 1);
556 				*/
557 				report(LOG_ERR, "interface %s link layer type %d not ethernet, skipping rest of this probe cycle", ifname, linktype);
558 				break; /* for (l) ... */
559 			}
560 
561 			/* compile bpf filter to select just udp/ip traffic to udp port bootpc  */
562 			/* Although one would expect frames on an untagged logical network interface to arrive without any 802.1Q tag,
563 			   some Ethernet drivers will deliver some frames with an 802.1Q tag in which vlan==0.
564 			   This may be because the frame arrived with an 802.1Q tag in which the 802.1p priority was non-zero.
565 			   To preserve that priority field, they retain the 802.1Q tag and set the vlan field to 0.
566 			   As per spec, a frame received with 802.1Q tag in which vlan == 0 should be treated as an untagged frame.
567 			   So our bpf filter needs to include both untagged and tagged frames.
568 			*/
569 			if (pcap_compile(pd, &bpf_code, "udp dst port bootpc or (vlan and udp dst port bootpc)", 1, PCAP_NETMASK_UNKNOWN) < 0) {
570 				report(LOG_ERR, "pcap_compile: %s", pcap_geterr(pd));
571 				my_exit(1, 1, 1);
572 			}
573 			/* install compiled filter */
574 			if (pcap_setfilter(pd, &bpf_code) < 0) {
575 				report(LOG_ERR, "pcap_setfilter: %s", pcap_geterr(pd));
576 				my_exit(1, 1, 1);
577 			}
578 			if (socket_receive_timeout_feature)
579 				set_pcap_timeout(pd);
580 
581 			/* write one packet */
582 
583 			if (debug > 10)
584 				report(LOG_DEBUG, "writing packet %s", (char *) libnet_cq_getlabel(l));
585 
586 			if ((bytes_written = libnet_write(l)) == -1) {
587 				report(LOG_ERR, "libnet_write failed: %s", libnet_geterror(l));
588 			} else {
589 				if (bytes_written < write_packet_len)
590 					report(LOG_ERR, "libnet_write: bytes written: %d (expected %d)", bytes_written, write_packet_len);
591 			}
592 
593 			/* XXX Are response packets lost if they arrive between our call (above) to libnet_write(),
594 			   and our call(s) to pcap_dispatch() in receive_and_process_responses() below?
595 			   Or if they arrive between calls to pcap_dispatch() in receive_and_process_responses()?
596 			*/
597 
598 			/* Defer any interruptions due to children.
599 			   These are possible as process_response() could fork an alert_program or alert_program2 child.
600 			*/
601 			sigemptyset(&new_sigset);
602 			sigaddset(&new_sigset, SIGCHLD);
603 			sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset);  /* block SIGCHLD */
604 
605 			if (debug > 10)
606 				report(LOG_DEBUG, "listening for answers for %d milliseconds", GetResponse_wait_time());
607 
608 			packets_recv = 0;
609 
610 			/* Receive and process responses until specified timeout or quit is requested. */
611 			if ((receive_and_process_responses_rc = receive_and_process_responses(GetResponse_wait_time() / 1000)) >= 0)
612 				packets_recv = receive_and_process_responses_rc;
613 			/* meaning of other return codes not presently defined */
614 
615 			if (debug > 10)
616 				report(LOG_DEBUG, "done listening, captured %d packets", packets_recv);
617 
618 			sigprocmask(SIG_SETMASK, &old_sigset, NULL);  /* unblock SIGCHLD */
619 
620 			/* I was hoping that perhaps pcap_stats() would return a nonzero number of packets dropped when
621 			   the buffer size specified to pcap_open_live() turns out to be too small -- so we could
622 			   provide some indication that you need to specify a larger buffer.  Alas, even in that situation
623 			   the ps_drop field is still 0.
624 			 *
625 			 *	if (pcap_stats(pd, &ps) < 0) {
626 			 *		report(LOG_ERR, "pcap_stats(): %s", pcap_geterr(pd));
627 			 *	} else if (debug > 10) {
628 			 *		report(LOG_DEBUG, "pcap_stats: packets received %u, packets dropped %u",  ps.ps_recv, ps.ps_drop);
629 			 *	}
630 			 */
631 
632 			/* close packet capture descriptor */
633 			pcap_close(pd);
634 			pd = NULL;
635 
636 			/* check for 'quit' request after sending each packet, since waiting until end of probe cycle
637 			   would impose a substantial delay. */
638 			if (quit_requested) { /* set by signal handler */
639 				if (debug > 1)
640 					report(LOG_INFO, "received request to quit");
641 				break;
642 			}
643 			/* don't check for requests to re-read configuration file here, because that sort of change
644 			   requires we construct new packets to send, not something to do in the middle of a cycle...
645 			   and can alter the response_timeout value used within the cycle. */
646 			/* don't check for requests to close-and-reopen the logfile, or close-and-reopen the
647 			   capture file here.  (should we?) */
648 
649 		} /* write each flavor packet and listen for answers */
650 
651 		/* Cleanup from iterating through the context queue. */
652 		if (!libnet_cq_end_loop()) {
653 			report(LOG_ERR, "libnet_cq_end_loop() failed");
654 			my_exit(1, 1, 1);
655 		}
656 
657 		if (debug > 10)
658 			report(LOG_DEBUG, "cycle complete, going to sleep for %d seconds", GetCycle_time());
659 
660 		/* Although we already handled signals at the top of the main event loop,
661 		   we do so again here, because the time through the main loop can be substantial due
662 		   to the time we capture packets, and signals may have come in...we don't want to postpone
663 		   handling them until we finish sleeping as well.
664 		*/
665 		if (quit_requested) { /* set by signal handler */
666 			if (debug > 1)
667 				report(LOG_INFO, "received request to quit");
668 			break;
669 		}
670 		if (reopen_log_file) { /* set by signal handler */
671 			close_and_reopen_log_file(logfile_name);
672 			reopen_log_file = 0;
673 		}
674 		if (reopen_capture_file) { /* set by signal handler */
675 			close_and_reopen_capture_file();
676 			reopen_capture_file = 0;
677 		}
678 		if (reread_config_file)	{ /* set by signal handler */
679 			reconfigure(write_packet_len);
680 			reread_config_file = 0;
681 		}
682 
683 		/* We allow must signals that come in during our sleep() to interrupt us.  E.g. we want to cut short
684 		   our sleep when we're signalled to exit.  But we must block SIGCHLD during our sleep.  That's because
685 		   if we forked an alert_program or alert_program2 child above, its termination will likely happen while we're sleeping;
686 		   we'll end up being interrupted by the SIGCHLD almost immediately, cutting short our sleep and forcing
687 		   us to proceed to the next probe cycle far too soon.
688 		*/
689 
690 		alarm(0); /* cancel any alarm left over, just in-case something's left by libpcap */
691 		time_to_sleep = GetCycle_time();
692 
693 		sigemptyset(&new_sigset);
694 		sigaddset(&new_sigset, SIGCHLD);
695 		sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset);  /* block SIGCHLD */
696 
697 		sleep(time_to_sleep);
698 
699 		sigprocmask(SIG_SETMASK, &old_sigset, NULL);  /* unblock SIGCHLD */
700 
701 		alarm(0); /* cancel any alarm left over, just in case we were interrupted */
702 
703 	} /* MAIN EVENT LOOP */
704 
705 
706 	/* we only reach here after receiving a signal requesting we quit */
707 
708 	if (pd_template) /* only used if a capture file requested */
709 		pcap_close(pd_template);
710 
711 	my_exit(0, 1, 1);
712 
713 	/* NOTREACHED */
714 	exit(0); /* silence compiler warning */
715 }
716 
717 
718 int
receive_and_process_responses(int timeout_secs)719 receive_and_process_responses(int timeout_secs)
720 {
721 /* Listen for all replies until the specified timeout expires, or quit is requested.
722    For each reply, 'process_response' is called with ptrs to the reply packet.
723 
724    If return value is >= 0, it is the number of packets received as reported by pcap.
725    The meaning of return values < 0 is not presently defined.
726 
727    XXX If you didn't specify enough buffer space, it appears that the packets that didn't fit
728    are silently lost; pcap_dispatch() doesn't provide any indication via a negative rc, and
729    even pcap_stats() doesn't show these as drops, so we can't provide some indication to the
730    user that the buffer specified is too small.
731 */
732 
733 	int packets_recv;
734 
735 	packets_recv = 0;
736 
737 	/* As per pcap(3), the timeout specified in pcap_open_live() may be ignored.
738 	   On some platforms, pcap_dispatch() may return return sooner, or might never return.
739 	   So we set our own timeout with alarm(), and call pcap_dispatch() repeatedly until our timeout expires
740 	   (or we notice that quit was requested).
741 
742 	   XXX Setting our our alarm() may not work if libpcap() also uses the same alarm.
743 	*/
744 
745 	alarm_fired = 0;
746 	alarm(timeout_secs);
747 
748 	do {
749 		int pcap_rc;
750 
751 		pcap_rc = pcap_dispatch(pd, -1, process_response, NULL);
752 
753 		if (pcap_rc == -2)
754 			/* Returned as per request by pcap_breakloop(), prior to any packets being processed */
755 			; /* not an error from our perspective */
756 		else if (pcap_rc < 0)
757 			report(LOG_ERR, "pcap_dispatch(): %s", pcap_geterr(pd));
758 		else if (pcap_rc > 0)
759 			packets_recv += pcap_rc;
760 		/* else pc_rc == 0, not an error, and no need to increment packets_recv */
761 
762 	} while (!alarm_fired && !quit_requested);
763 
764 	alarm(0);
765 
766 	return packets_recv;
767 }
768 
769 
770 void
process_response(u_char * user,const struct pcap_pkthdr * pkthdr,const u_char * packet)771 process_response(u_char *user, const struct pcap_pkthdr *pkthdr, const u_char *packet)
772 {
773 /* Process one response packet.
774    We are called by pcap_dispatch() for each packet it captures.
775    When we return, control returns to pcap_dispatch() so it can continue capturing packets.
776 */
777 
778 	struct libnet_ethernet_hdr *ether_header; /* access ethernet header */
779 	struct my_ether_vlan_header *my_ether_vlan_header; /* possibly access ethernet 802.1Q header */
780 	struct libnet_ipv4_hdr *ip_header;				/* access ip header */
781 	bpf_u_int32 ether_len;		/* bpf_u_int32 from pcap.h */
782 	struct udphdr *udp_header; /* access UDP header */
783 	struct bootp *bootp_pkt; /* access bootp/dhcp packet */
784 	int bootp_min_len;
785 	int isYiaddrInLeaseNetworksOfConcern = 0; /* boolean */
786 	char yiaddr_network_of_concern_addenda[STR_MAXLEN];
787 	int isLegalServer;			/* boolean */
788 
789 	/* fields parsed out from packet*/
790 	struct libnet_ether_addr ether_dhost, ether_shost;
791 	uint16_t ether_type, ether_type_inner;
792 	uint16_t ether_vid;
793 	size_t ether_or_vlan_header_len; 	/* = sizeof(struct libnet_ethernet_hdr) or sizeof(struct my_ether_vlan_header) depending on response packet */
794 	struct in_addr ip_src, ip_dst, yiaddr;
795 	/* string versions of same */
796 	char ether_dhost_str[MAX_ETHER_ADDR_STR], ether_shost_str[MAX_ETHER_ADDR_STR];
797 	char ether_type_str[MAX_ETHER_TYPE_STR], ether_type_inner_str[MAX_ETHER_TYPE_STR];
798 	char ip_src_str[MAX_IP_ADDR_STR], ip_dst_str[MAX_IP_ADDR_STR], yiaddr_str[MAX_IP_ADDR_STR];
799 	int ip_header_len_bytes;
800 	int udp_len; /* XXX why does udp.h declare this as signed? */
801 	int udp_payload_len;
802 
803 	char *alert_program_name, *alert_program_name2;
804 
805 	if (debug > 10)
806 		report(LOG_DEBUG, "   captured a packet");
807 
808 	if ((pkthdr->caplen < (ether_len = pkthdr->len)) && (debug > 1)) {
809 		report(LOG_WARNING, "interface %s, packet truncated (ethernet frame length %u, captured %u), ignoring", ifname, ether_len, pkthdr->caplen);
810 		return;
811 	}
812 
813 	if ((ether_len < sizeof(struct libnet_ethernet_hdr)) && (debug > 1)) {
814 		report(LOG_WARNING, "interface %s, short packet (got %d bytes, smaller than an Ethernet header)", ifname, ether_len);
815 		return;
816 	}
817 
818 	/* we use ether_header to access the Ethernet header */
819 	ether_header = (struct libnet_ethernet_hdr *) packet;
820 
821     /* we may use my_ether_vlan_header to access the Ethernet 801.Q header */
822     my_ether_vlan_header = (struct my_ether_vlan_header *) packet;
823 
824 	/* parse fields out of ethernet header for easier access */
825 	bcopy(&(ether_header->ether_dhost), &ether_dhost, sizeof(ether_dhost));
826 	bcopy(&(ether_header->ether_shost), &ether_shost, sizeof(ether_shost));
827 	ether_type = ntohs(ether_header->ether_type);
828 
829 	/* create printable versions of the fields we parsed above */
830 	bcopy(ether_ntoa(&ether_dhost), &ether_dhost_str, sizeof(ether_dhost_str));
831 	bcopy(ether_ntoa(&ether_shost), &ether_shost_str, sizeof(ether_shost_str));
832 	snprintf(ether_type_str, sizeof(ether_type_str), "0x%4.4X", ether_type);
833 
834 	if (debug > 10)
835 		report(LOG_DEBUG, "     interface %s, from ether %s to %s type %s", ifname, ether_shost_str, ether_dhost_str, ether_type_str);
836 
837 	if (ether_type == ETHERTYPE_IP) {
838 		ether_or_vlan_header_len = sizeof(struct libnet_ethernet_hdr);
839 
840 	} else if (ether_type == ETHERTYPE_VLAN) {
841 
842 		if (ether_len < sizeof(struct my_ether_vlan_header) && (debug > 1)) {
843 			report(LOG_WARNING, "interface %s, short packet from ether %s to %s type %s (got %d bytes, smaller than an Ethernet 802.1Q header)", ifname, ether_shost_str, ether_dhost_str, ether_type_str, ether_len);
844 			return;
845 		}
846 
847 		/* We're supposed to be running on an interface which delivers untagged packets to us.
848 		   Ethernet driver might still deliver to us an 802.1Q-tagged packet with VLAN==0.
849 		   It might do so because the packet arrived with a non-zero 802.1p priority, and the driver
850 		   decided that stripping the entire 802.1Q header would lose the priority information, so it
851 		   instead chose to retain the 802.1Q header but reset the VLAN ID field to 0.
852 		   802.1Q spec permits use of VLAN ID 0 to mean an untagged packet.
853 		   So despite running on an untagged network interface, we must still accept frames with 802.1Q tag where VLAN ID == 0.
854 		*/
855 		/* The lower 12 bits of the TCI are the VLAN ID. */
856 		ether_vid = ntohs((my_ether_vlan_header->ether_tci & 0x1FFF));
857 		if (ether_vid && (debug > 1) ) {
858 			report(LOG_WARNING, "interface %s, ether src %s: non-zero 802.1Q VLAN ID %u", ether_vid);
859 			return;
860 		}
861 
862 		ether_type_inner = ntohs(my_ether_vlan_header->ether_type);
863 		snprintf(ether_type_inner_str, sizeof(ether_type_inner_str), "0x%4.4X", ether_type_inner);
864 
865 		if ((ether_type_inner != ETHERTYPE_IP) && (debug > 1)) {
866 			report(LOG_WARNING, "interface %s, ether src %s: unexpected 802.1Q inner ether_type %s", ifname, ether_shost_str, ether_type_inner_str);
867 			return;
868 		}
869 
870 		ether_or_vlan_header_len = sizeof(struct my_ether_vlan_header);
871 
872 	} else {
873 		if (debug > 1) {
874 			report(LOG_WARNING, "interface %s, ether src %s: unexpected ether_type %s", ifname, ether_shost_str, ether_type_str);
875 		}
876 		return;
877 	}
878 
879 	/* If the frame is untagged, ether_or_vlan_header_len is now set to the length of the ethernet header.
880 	   Else if the frame is tagged, ether_or_vlan_header_len is now set to the length of the ethernet VLAN header.
881 	*/
882 
883 	if (ether_len < ether_or_vlan_header_len + sizeof(struct libnet_ipv4_hdr)) {
884 		report(LOG_WARNING, "interface %s, ether src %s type %s: short packet (got %d bytes, smaller than IP header in Ethernet)", ifname, ether_shost_str, ether_type_str, ether_len);
885 		return;
886 	}
887 
888 	/* we use ip_header to access the IP header */
889 	ip_header = (struct libnet_ipv4_hdr *) (packet + ether_or_vlan_header_len);
890 
891 	/* parse fields out of ip header for easier access */
892 	bcopy(&(ip_header->ip_src), &ip_src, sizeof(ip_header->ip_src));
893 	bcopy(&(ip_header->ip_dst), &ip_dst, sizeof(ip_header->ip_dst));
894 	/* create printable versions of the fields we parsed above */
895 	bcopy(inet_ntoa(ip_src), &ip_src_str, sizeof(ip_src_str));
896 	bcopy(inet_ntoa(ip_dst), &ip_dst_str, sizeof(ip_dst_str));
897 
898 	if (debug > 10)
899 		report(LOG_DEBUG, "     from IP %s to %s", ip_src_str, ip_dst_str);
900 
901 	ip_header_len_bytes = ip_header->ip_hl << 2;
902 
903 	/* Repeat the packet size check (through IP header), but taking into account ip_header_len_bytes */
904 	if (ether_len < ether_or_vlan_header_len + ip_header_len_bytes) {
905 		report(LOG_WARNING, "interface %s, short packet (got %d bytes, smaller than IP header in Ethernet)", ifname, ether_len);
906 		return;
907 	}
908 
909 	/* we use udp_header to access the UDP header */
910 	udp_header = (struct udphdr *) (packet + ether_or_vlan_header_len + ip_header_len_bytes);
911 
912 	if (ether_len <  ether_or_vlan_header_len + ip_header_len_bytes + sizeof(struct udphdr)) {
913 		report(LOG_WARNING, "interface %s ether src %s: short packet (got %d bytes, smaller than UDP/IP header in Ethernet)", ifname, ether_shost_str, ether_len);
914 		return;
915 	}
916 
917 	udp_len = udp_header->uh_ulen;
918 	if (udp_len < sizeof(struct udphdr)) {
919 		report(LOG_WARNING, "interface %s, ether src %s: invalid UDP packet (UDP length %d, smaller than minimum value %d)", ifname, ether_shost_str, udp_len, sizeof(struct udphdr));
920 		return;
921 	}
922 
923 	udp_payload_len = udp_len - sizeof(struct udphdr);
924 
925 	/* The smallest bootp/dhcp packet (the UDP payload) is actually smaller than sizeof(struct bootp),
926 	   as it's possible for DHCP replies to have shorter bootp_options fields.
927 	*/
928 	bootp_min_len = sizeof(struct bootp) - BOOTP_OPTIONS_LEN;
929 
930 	if (udp_payload_len < bootp_min_len) {
931 		report(LOG_WARNING, "interface %s, ether src %s: invalid BootP/DHCP packet (UDP payload length %d, smaller than minimal BootP/DHCP payload %d)", ifname, ether_shost_str, udp_payload_len, bootp_min_len);
932 		return;
933 	}
934 
935 	/* we use bootp_pkt to access the bootp/dhcp packet */
936 	bootp_pkt = (struct bootp *) (packet + ether_or_vlan_header_len + ip_header_len_bytes + sizeof(struct udphdr));
937 
938 	/* Make sure the packet is in response to our query, otherwise ignore it.
939 	   Our query had bootp_htype=HTYPE_ETHER, bootp_hlen=HLEN_ETHER, and bootp_chaddr=GetChaddr().
940 	   Any reply with different values isn't in response to our probe, so we must ignore it.
941 	*/
942 	if (bootp_pkt->bootp_htype != HTYPE_ETHER) {
943 		if (debug > 10)
944 			report(LOG_DEBUG, "     bootp_htype (%d) != HTYPE_ETHER (%d), so this is not a response to my probe, ignoring", bootp_pkt->bootp_htype, HTYPE_ETHER);
945 		return;
946 	}
947 
948 	if (bootp_pkt->bootp_hlen != HLEN_ETHER) {
949 		if (debug > 10)
950 			report(LOG_DEBUG, "     bootp_hlen (%d) != HLEN_ETHER (%d), so this is not a response to my probe, ignoring", bootp_pkt->bootp_hlen, HLEN_ETHER);
951 		return;
952 	}
953 
954 	if (bcmp(bootp_pkt->bootp_chaddr, GetChaddr(), HLEN_ETHER)) {
955 		if (debug > 10) {
956 			struct libnet_ether_addr ether_tmp;
957 			char ether_tmp_str[MAX_ETHER_ADDR_STR];
958 
959 			/* create printable version of bootp_pkt->bootp_chaddr */
960 			bcopy(&(bootp_pkt->bootp_chaddr), &ether_tmp, sizeof(ether_tmp));
961 			bcopy(ether_ntoa(&ether_tmp), &ether_tmp_str, sizeof(ether_tmp_str));
962 
963 			report(LOG_DEBUG, "     bootp_chaddr (%s) != my chaddr (%s), so this is not a response to my probe, ignoring", ether_tmp_str, ether_ntoa(GetChaddr()));
964 		}
965 		return;
966 	}
967 
968 	/* at this point we know the packet is a response to my probe */
969 
970 	/* Determine if the response is from an expected server. */
971 	isLegalServer = 1; /* start by assuming it is expected. */
972 
973 	if (!isLegalServersMember(&ip_src)) {
974 		if (debug > 10)
975 			report(LOG_DEBUG, "     ip_src %s is not a legal server", ip_src_str);
976 		isLegalServer = 0;
977 	}
978 
979 	if (!isLegalServerEthersrcsMember(&ether_shost)) {
980 		if (debug > 10)
981 			report(LOG_DEBUG, "     ether_shost %s is not a legal server", ether_shost_str);
982 		isLegalServer = 0;
983 	}
984 
985 	if (isLegalServer) {
986 		if (debug > 10)
987 			report(LOG_DEBUG, "     this is a legal server, ignoring");
988 		return;
989 	}
990 
991 	/* at this point we know the responder is unexpected */
992 
993 	/* parse yiaddr out of bootp packet easier access */
994 	bcopy(&(bootp_pkt->bootp_yiaddr), &yiaddr, sizeof(bootp_pkt->bootp_yiaddr));
995 	/* create printable version of the field we parsed above */
996 	bcopy(inet_ntoa(yiaddr), &yiaddr_str, sizeof(yiaddr_str));
997 
998 	if (yiaddr.s_addr != INADDR_ANY) {
999 		if (isInLeaseNetworksOfConcern(&yiaddr)) {
1000 			isYiaddrInLeaseNetworksOfConcern = 1;
1001 			if (debug > 10)
1002 				report(LOG_DEBUG, "     yiaddr %s is in inside a lease_network_of_concern", yiaddr_str);
1003 		}
1004 	}
1005 
1006 
1007 	/* report unexpected server */
1008 	/* Producing this log message is our entire reason for existance. */
1009 
1010 	/* The log message may end with an addenda to further alert you that the yiaddr was inside a network of concern.
1011 	   Prepare that possible addenda first.
1012 	*/
1013 	if (isYiaddrInLeaseNetworksOfConcern) {
1014 		snprintf(yiaddr_network_of_concern_addenda, sizeof(yiaddr_network_of_concern_addenda), "  Response also contains yiaddr %s inside a network of concern.", yiaddr_str);
1015 	} else {
1016 		yiaddr_network_of_concern_addenda[0] = '\0';
1017 	}
1018 
1019 	report(LOG_WARNING, "received unexpected response on interface %s from BootP/DHCP server with IP source %s (ether src %s).%s", ifname, ip_src_str, ether_shost_str, yiaddr_network_of_concern_addenda);
1020 
1021 
1022 	/* also save the response packet if we are writing to capture file */
1023 	if (pcap_dump_d) {
1024 		pcap_dump((u_char *) pcap_dump_d, pkthdr, packet);
1025 	}
1026 
1027 	/* Also call the alert_program_name if the user has specified one. */
1028 	/* We must fetch it anew as it may have changed due to configfile change */
1029 	alert_program_name = GetAlert_program_name();
1030 	if (alert_program_name) {
1031 		/* We run it in a child, so we don't block waiting for it to return. */
1032 		pid_t pid;
1033 		if ((pid = fork()) < 0) {
1034 			report(LOG_ERR, "can't fork to run %s: %s", alert_program_name, get_errmsg());
1035 			/* just skip running alert_program_name, but keep running since we're still fine */
1036 		} else if (pid == 0) { /* child */
1037 			/* We do allow child to inherit fd 0,1,2.  If we're logging to stderr, we want child to have it too. */
1038 			if (sockfd) /* We don't want child to inherit the general purpose dgram socket */
1039 				close(sockfd);
1040 			libnet_cq_destroy(); /* We don't want child to inherit to inherit libnet context queue */
1041 			if (pd) /* We don't want child to inherit packet capture descriptor, nor packet dumpfile descriptor. */
1042 				pcap_close(pd);
1043 			if (pcap_dump_d)
1044 				pcap_dump_close(pcap_dump_d);
1045 			if (execl(alert_program_name, alert_program_name, prog, ifname, ip_src_str, ether_shost_str, (char *) 0 ) < 0) {
1046 				report(LOG_ERR, "can't execute alert_program_name '%s': %s", alert_program_name, get_errmsg());
1047 				exit(0);  /* child exits */
1048 			}
1049 		}
1050 	} /* if (alert_program_name) */
1051 
1052 	/* Also call the alert_program_name2 if the user has specified one. */
1053 	/* We must fetch it anew as it may have changed due to configfile change */
1054 	alert_program_name2 = GetAlert_program_name2();
1055 	if (alert_program_name2) {
1056 		/* We run it in a child, so we don't block waiting for it to return. */
1057 		pid_t pid;
1058 		if ((pid = fork()) < 0) {
1059 			report(LOG_ERR, "can't fork to run %s: %s", alert_program_name2, get_errmsg());
1060 			/* just skip running alert_program_name2, but keep running since we're still fine */
1061 		} else if (pid == 0) { /* child */
1062 			int execl_rc;
1063 			/* We do allow child to inherit fd 0,1,2.  If we're logging to stderr, we want child to have it too. */
1064 			if (sockfd) /* We don't want child to inherit the general purpose dgram socket */
1065 				close(sockfd);
1066 			libnet_cq_destroy(); /* We don't want child to inherit to inherit libnet context queue */
1067 			if (pd) /* We don't want child to inherit packet capture descriptor, nor packet dumpfile descriptor. */
1068 				pcap_close(pd);
1069 			if (pcap_dump_d)
1070 				pcap_dump_close(pcap_dump_d);
1071 			if (isYiaddrInLeaseNetworksOfConcern) {
1072 				/* include "-y yiaddr' option */
1073 				execl_rc = execl(alert_program_name2, alert_program_name2, "-p", prog, "-I", ifname, "-i", ip_src_str, "-m", ether_shost_str, "-y", yiaddr_str, (char *) 0 );
1074 			} else {
1075 				/* do not include "-y yiaddr' option */
1076 				execl_rc = execl(alert_program_name2, alert_program_name2, "-p", prog, "-I", ifname, "-i", ip_src_str, "-m", ether_shost_str, (char *) 0 );
1077 			}
1078 			if (execl_rc < 0) {
1079 				report(LOG_ERR, "can't execute alert_program_name2 '%s': %s", alert_program_name2, get_errmsg());
1080 				exit(0);  /* child exits */
1081 			}
1082 		}
1083 	} /* if (alert_program_name2) */
1084 
1085 
1086 	return;
1087 }
1088 
1089 
1090 void
set_pcap_timeout(pcap_t * pd)1091 set_pcap_timeout(pcap_t *pd)
1092 {
1093 /*
1094 	Set a receive timeout on the socket underlying the pcap descriptor.
1095 
1096 	Ideally, this would not be necessary, as we already passed a timeout to pcap_open_live().
1097 	But as the pcap(3) man page explains, that timeout is not supported on some platforms.
1098 	In those cases, applying a timeout directly to the underlying socket might help.
1099 */
1100 
1101 	struct timeval timeout;
1102 	int time_wait;
1103 
1104 	time_wait = GetResponse_wait_time();
1105 	timeout.tv_sec  = time_wait / 1000;
1106 	timeout.tv_usec = (time_wait % 1000) * 1000;
1107 	if(setsockopt(pcap_fileno(pd), SOL_SOCKET, SO_RCVTIMEO,
1108 			&timeout, sizeof(timeout)) < 0) {
1109 		report(LOG_ERR, "set_pcap_timeout(): unable to set receive timeout: %s", get_errmsg());
1110 		my_exit(1, 1, 1);
1111 	}
1112 
1113 }
1114 
1115 
1116 void
reconfigure(const int write_packet_len)1117 reconfigure(const int write_packet_len)
1118 {
1119 /* Perform all necessary functions to handle a request to reconfigure.
1120    Must not be called until after initial configuration is complete.
1121 */
1122 
1123 	if (! read_configfile(config_file)) {
1124 		my_exit(1, 1, 1);
1125 	}
1126 
1127 	/* Contents of the packets we send may need to change as a result of change
1128 	   to the configuration.  Free the packets we've already constructed, and build new ones. */
1129 	if (! init_libnet_context_queue()) {
1130 		my_exit(1, 1, 1);
1131 	}
1132 
1133 	return;
1134 }
1135 
1136 
1137 void
close_and_reopen_capture_file(void)1138 close_and_reopen_capture_file(void)
1139 {
1140 /*	Close and re-open capture file.
1141 	If we are not capturing to a file, return silently.
1142 	Returns on success, exits on error.
1143 
1144 	Note that since pcap_dump_open() opens the file with mode "w" and writes a pcap header to it,
1145 	if you want to keep the existing capture file's contents, you must move the existing
1146 	capture file aside before this routine is called.  In practice, that means you move the
1147 	file aside first, then send a signal triggering the close and re-open.
1148 */
1149 
1150 	if (pcap_dump_d) { /* a capture file was already open */
1151 		if (debug > 1)
1152 			report(LOG_NOTICE, "closing capture file");
1153 
1154 		/* close */
1155 		 pcap_dump_close(pcap_dump_d);
1156 
1157 		/* re-open */
1158 		/* XXX Note pcap_dump_open() does does an fopen() on capture_file with mode "w", and writes
1159 		   a pcap header to it.  It's up to the user to ensure the capture_file specified is safe.
1160 		   Since we are probably running as root, opportunities for abuse abound.  The user
1161 		   must be careful to specify a capture_file located in a directory no one else may write to,
1162 		   and to ensure the capture_file does not exist, or if it does, it safe to overwrite.
1163 		*/
1164 		if ((pcap_dump_d = pcap_dump_open(pd_template, capture_file)) == NULL) {
1165 			report(LOG_ERR, "close_and_reopen_capture_file: pcap_dump_open: %s", pcap_geterr(pd_template));
1166 			my_exit(1, 1, 1);
1167 		}
1168 
1169 		if (debug > 1)
1170 			report(LOG_NOTICE, "re-opened capture file");
1171 
1172 	}
1173 	return;
1174 }
1175 
1176 
1177 void
catcher(int sig)1178 catcher(int sig)
1179 {
1180 /*	Signal catcher. */
1181 
1182 	/* If the signal arrives while we are in pcap_dispatch(), when we return from the
1183 	   signal handler, pcap_dispatch() normally will resume reading packets.
1184 	   That's the behavior we want for most signals, but not the following:
1185 
1186 	   * When the signal requests that we quit,
1187 	   we don't want pcap_dispatch() to resume reading packets.
1188 	   In an environment in which pcap_dispatch() receives no packets matching
1189 	   the specified pcap filter, pcap_dispatch() might continue reading packets forever,
1190 	   preventing us from quitting.
1191 
1192 	   * When the signal is an alarm to indicate a timer has expired,
1193 	   we don't want pcap_dispatch() to resume reading packets.
1194 
1195 	   So in those situations, we also call pcap_breakloop() (when pd != NULL)
1196 	   to specify that pcap_dispatch() should instead return.
1197 	*/
1198 
1199 
1200 	if ((sig == SIGINT) || (sig == SIGTERM) || (sig == SIGQUIT))  { /* quit gracefully */
1201 		quit_requested = 1;
1202 		if (pd)
1203 			pcap_breakloop(pd);
1204 		return;
1205 
1206 	} else if (sig ==  SIGALRM) { /* timer */
1207 		alarm_fired = 1;
1208 		if (pd)
1209 			pcap_breakloop(pd);
1210 		return;
1211 
1212 	} else if (sig == SIGHUP) { /* re-read config file */
1213 		/* Doing the reread while in the signal handler is way too dangerous.
1214 		   We'll do it at the start or end of the next main event loop.
1215 		*/
1216 		reread_config_file = 1;
1217 		return;
1218 
1219 	} else if (sig == SIGUSR1) { /* close and re-open logfile (if logfile being used) */
1220 		/* Doing the close and reopen in the signal handler is way too dangerous.
1221 		   We'll do it at the start or end of the next main event loop.
1222 		*/
1223 		reopen_log_file = 1;
1224 		return;
1225 	} else if (sig == SIGUSR2) { /* close and re-open capture file (if capture file being used) */
1226 		/* Doing the close and reopen in the signal handler is way too dangerous.
1227 		   We'll do it at the start or end of the next main event loop.
1228 		*/
1229 		reopen_capture_file = 1;
1230 		return;
1231 	} else if (sig == SIGCHLD) { /* reap, e.g. calls to user-specified alert_program_name */
1232 		int stat, errno_save;
1233 
1234 		errno_save = errno;
1235 		while ((waitpid(-1, &stat, WNOHANG)) > 0)
1236 			;
1237 		errno = errno_save;
1238 		return;
1239 	}
1240 
1241 	return;
1242 }
1243 
1244 
1245 void
cleanup(void)1246 cleanup(void)
1247 {
1248 /*	Cleanup tasks at exit. */
1249 
1250 	/* Destroy all the libnet contexts (if any), and the context queue (if any). */
1251 	libnet_cq_destroy();
1252 
1253 	if (pcap_dump_d) /* capture file is open */
1254 		pcap_dump_close(pcap_dump_d);
1255 
1256 	if (pid_file)
1257 		unlink(pid_file); /* may fail if file was never written */
1258 
1259 	return;
1260 }
1261 
1262 void
my_exit(int exit_status,int do_cleanup,int do_log)1263 my_exit(int exit_status, int do_cleanup, int do_log)
1264 {
1265 	/* A wrapper for exit().  */
1266 
1267 	if (do_log)
1268 		report(LOG_NOTICE, "exiting");
1269 
1270 	if (do_cleanup)
1271 		cleanup();
1272 
1273 	exit(exit_status);
1274 }
1275 
1276 
1277 void
usage(void)1278 usage(void)
1279 {
1280 /*	Print usage message and return. */
1281 
1282 	fprintf(stderr, "Usage: %s [-c config_file] [-d debuglevel] [-f] [-h] [-l log_file] [-o capture_file] [-p pid_file] [-Q vlan_id] [-s capture_bufsize] [-T] [-v] [-w cwd] interface_name\n", prog);
1283 	fprintf(stderr, "   -c config_file                 override default config file [%s]\n", CONFIG_FILE);
1284 	fprintf(stderr, "   -d debuglevel                  enable debugging at specified level\n");
1285 	fprintf(stderr, "   -f                             don't fork (only use for debugging)\n");
1286 	fprintf(stderr, "   -h                             display this help message then exit\n");
1287 	fprintf(stderr, "   -l log_file                    log to file instead of syslog\n");
1288 	fprintf(stderr, "   -o capture_file                enable capturing of unexpected answers\n");
1289 	fprintf(stderr, "   -p pid_file                    override default pid file [%s]\n", PID_FILE);
1290 	fprintf(stderr, "   -Q vlan_id                     tag outgoing frames with an 802.1Q VLAN ID\n");
1291 	fprintf(stderr, "   -s capture_bufsize             override default capture bufsize [%d]\n", CAPTURE_BUFSIZE);
1292 	fprintf(stderr, "   -T                             enable the socket receive timeout feature\n");
1293 	fprintf(stderr, "   -v                             display version number then exit\n");
1294 	fprintf(stderr, "   -w cwd                         override default working directory [%s]\n", CWD);
1295 	fprintf(stderr, "   interface_name                 name of ethernet interface\n");
1296 
1297 	return;
1298 }
1299 
1300