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), ðer_dhost, sizeof(ether_dhost));
826 bcopy(&(ether_header->ether_shost), ðer_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(ðer_dhost), ðer_dhost_str, sizeof(ether_dhost_str));
831 bcopy(ether_ntoa(ðer_shost), ðer_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), ðer_tmp, sizeof(ether_tmp));
961 bcopy(ether_ntoa(ðer_tmp), ðer_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(ðer_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