| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: dhcrelay.c,v 1.6 2016/01/10 20:10:45 christos Exp $ */ | | 1 | /* $NetBSD: dhcrelay.c,v 1.6.8.1 2017/06/10 06:30:07 snj Exp $ */ |
2 | /* dhcrelay.c | | 2 | /* dhcrelay.c |
3 | | | 3 | |
4 | DHCP/BOOTP Relay Agent. */ | | 4 | DHCP/BOOTP Relay Agent. */ |
5 | | | 5 | |
6 | /* | | 6 | /* |
7 | * Copyright(c) 2004-2015 by Internet Systems Consortium, Inc.("ISC") | | 7 | * Copyright(c) 2004-2015 by Internet Systems Consortium, Inc.("ISC") |
8 | * Copyright(c) 1997-2003 by Internet Software Consortium | | 8 | * Copyright(c) 1997-2003 by Internet Software Consortium |
9 | * | | 9 | * |
10 | * Permission to use, copy, modify, and distribute this software for any | | 10 | * Permission to use, copy, modify, and distribute this software for any |
11 | * purpose with or without fee is hereby granted, provided that the above | | 11 | * purpose with or without fee is hereby granted, provided that the above |
12 | * copyright notice and this permission notice appear in all copies. | | 12 | * copyright notice and this permission notice appear in all copies. |
13 | * | | 13 | * |
14 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES | | 14 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES |
| @@ -18,27 +18,27 @@ | | | @@ -18,27 +18,27 @@ |
18 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | | 18 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
19 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | | 19 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT |
20 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 20 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
21 | * | | 21 | * |
22 | * Internet Systems Consortium, Inc. | | 22 | * Internet Systems Consortium, Inc. |
23 | * 950 Charter Street | | 23 | * 950 Charter Street |
24 | * Redwood City, CA 94063 | | 24 | * Redwood City, CA 94063 |
25 | * <info@isc.org> | | 25 | * <info@isc.org> |
26 | * https://www.isc.org/ | | 26 | * https://www.isc.org/ |
27 | * | | 27 | * |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | #include <sys/cdefs.h> | | 30 | #include <sys/cdefs.h> |
31 | __RCSID("$NetBSD: dhcrelay.c,v 1.6 2016/01/10 20:10:45 christos Exp $"); | | 31 | __RCSID("$NetBSD: dhcrelay.c,v 1.6.8.1 2017/06/10 06:30:07 snj Exp $"); |
32 | | | 32 | |
33 | #include "dhcpd.h" | | 33 | #include "dhcpd.h" |
34 | #include <syslog.h> | | 34 | #include <syslog.h> |
35 | #include <signal.h> | | 35 | #include <signal.h> |
36 | #include <sys/time.h> | | 36 | #include <sys/time.h> |
37 | | | 37 | |
38 | TIME default_lease_time = 43200; /* 12 hours... */ | | 38 | TIME default_lease_time = 43200; /* 12 hours... */ |
39 | TIME max_lease_time = 86400; /* 24 hours... */ | | 39 | TIME max_lease_time = 86400; /* 24 hours... */ |
40 | struct tree_cache *global_options[256]; | | 40 | struct tree_cache *global_options[256]; |
41 | | | 41 | |
42 | struct option *requested_opts[2]; | | 42 | struct option *requested_opts[2]; |
43 | | | 43 | |
44 | /* Needed to prevent linking against conflex.c. */ | | 44 | /* Needed to prevent linking against conflex.c. */ |
| @@ -197,33 +197,26 @@ main(int argc, char **argv) { | | | @@ -197,33 +197,26 @@ main(int argc, char **argv) { |
197 | if (fd == 1) | | 197 | if (fd == 1) |
198 | fd = open("/dev/null", O_RDWR); | | 198 | fd = open("/dev/null", O_RDWR); |
199 | if (fd == 2) | | 199 | if (fd == 2) |
200 | log_perror = 0; /* No sense logging to /dev/null. */ | | 200 | log_perror = 0; /* No sense logging to /dev/null. */ |
201 | else if (fd != -1) | | 201 | else if (fd != -1) |
202 | close(fd); | | 202 | close(fd); |
203 | | | 203 | |
204 | openlog("dhcrelay", DHCP_LOG_OPTIONS, LOG_DAEMON); | | 204 | openlog("dhcrelay", DHCP_LOG_OPTIONS, LOG_DAEMON); |
205 | | | 205 | |
206 | #if !defined(DEBUG) | | 206 | #if !defined(DEBUG) |
207 | setlogmask(LOG_UPTO(LOG_INFO)); | | 207 | setlogmask(LOG_UPTO(LOG_INFO)); |
208 | #endif | | 208 | #endif |
209 | | | 209 | |
210 | /* Set up the isc and dns library managers */ | | | |
211 | status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB, | | | |
212 | NULL, NULL); | | | |
213 | if (status != ISC_R_SUCCESS) | | | |
214 | log_fatal("Can't initialize context: %s", | | | |
215 | isc_result_totext(status)); | | | |
216 | | | | |
217 | /* Set up the OMAPI. */ | | 210 | /* Set up the OMAPI. */ |
218 | status = omapi_init(); | | 211 | status = omapi_init(); |
219 | if (status != ISC_R_SUCCESS) | | 212 | if (status != ISC_R_SUCCESS) |
220 | log_fatal("Can't initialize OMAPI: %s", | | 213 | log_fatal("Can't initialize OMAPI: %s", |
221 | isc_result_totext(status)); | | 214 | isc_result_totext(status)); |
222 | | | 215 | |
223 | /* Set up the OMAPI wrappers for the interface object. */ | | 216 | /* Set up the OMAPI wrappers for the interface object. */ |
224 | interface_setup(); | | 217 | interface_setup(); |
225 | | | 218 | |
226 | for (i = 1; i < argc; i++) { | | 219 | for (i = 1; i < argc; i++) { |
227 | if (!strcmp(argv[i], "-4")) { | | 220 | if (!strcmp(argv[i], "-4")) { |
228 | #ifdef DHCPv6 | | 221 | #ifdef DHCPv6 |
229 | if (local_family_set && (local_family == AF_INET6)) { | | 222 | if (local_family_set && (local_family == AF_INET6)) { |
| @@ -526,37 +519,26 @@ main(int argc, char **argv) { | | | @@ -526,37 +519,26 @@ main(int argc, char **argv) { |
526 | dhcpv6_universe.code_hash, | | 519 | dhcpv6_universe.code_hash, |
527 | &code, 0, MDL)) | | 520 | &code, 0, MDL)) |
528 | log_fatal("Unable to find the RELAY_MSG " | | 521 | log_fatal("Unable to find the RELAY_MSG " |
529 | "option definition."); | | 522 | "option definition."); |
530 | code = D6O_INTERFACE_ID; | | 523 | code = D6O_INTERFACE_ID; |
531 | if (!option_code_hash_lookup(&requested_opts[1], | | 524 | if (!option_code_hash_lookup(&requested_opts[1], |
532 | dhcpv6_universe.code_hash, | | 525 | dhcpv6_universe.code_hash, |
533 | &code, 0, MDL)) | | 526 | &code, 0, MDL)) |
534 | log_fatal("Unable to find the INTERFACE_ID " | | 527 | log_fatal("Unable to find the INTERFACE_ID " |
535 | "option definition."); | | 528 | "option definition."); |
536 | } | | 529 | } |
537 | #endif | | 530 | #endif |
538 | | | 531 | |
539 | /* Get the current time... */ | | | |
540 | gettimeofday(&cur_tv, NULL); | | | |
541 | | | | |
542 | /* Discover all the network interfaces. */ | | | |
543 | discover_interfaces(DISCOVER_RELAY); | | | |
544 | | | | |
545 | #ifdef DHCPv6 | | | |
546 | if (local_family == AF_INET6) | | | |
547 | setup_streams(); | | | |
548 | #endif | | | |
549 | | | | |
550 | /* Become a daemon... */ | | 532 | /* Become a daemon... */ |
551 | if (!no_daemon) { | | 533 | if (!no_daemon) { |
552 | int pid; | | 534 | int pid; |
553 | FILE *pf; | | 535 | FILE *pf; |
554 | int pfdesc; | | 536 | int pfdesc; |
555 | | | 537 | |
556 | log_perror = 0; | | 538 | log_perror = 0; |
557 | | | 539 | |
558 | if ((pid = fork()) < 0) | | 540 | if ((pid = fork()) < 0) |
559 | log_fatal("Can't fork daemon: %m"); | | 541 | log_fatal("Can't fork daemon: %m"); |
560 | else if (pid) | | 542 | else if (pid) |
561 | exit(0); | | 543 | exit(0); |
562 | | | 544 | |
| @@ -577,26 +559,44 @@ main(int argc, char **argv) { | | | @@ -577,26 +559,44 @@ main(int argc, char **argv) { |
577 | fclose(pf); | | 559 | fclose(pf); |
578 | } | | 560 | } |
579 | } | | 561 | } |
580 | } | | 562 | } |
581 | | | 563 | |
582 | (void) close(0); | | 564 | (void) close(0); |
583 | (void) close(1); | | 565 | (void) close(1); |
584 | (void) close(2); | | 566 | (void) close(2); |
585 | (void) setsid(); | | 567 | (void) setsid(); |
586 | | | 568 | |
587 | IGNORE_RET (chdir("/")); | | 569 | IGNORE_RET (chdir("/")); |
588 | } | | 570 | } |
589 | | | 571 | |
| | | 572 | /* Set up the isc and dns library managers */ |
| | | 573 | status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB, |
| | | 574 | NULL, NULL); |
| | | 575 | if (status != ISC_R_SUCCESS) |
| | | 576 | log_fatal("Can't initialize context: %s", |
| | | 577 | isc_result_totext(status)); |
| | | 578 | |
| | | 579 | /* Get the current time... */ |
| | | 580 | gettimeofday(&cur_tv, NULL); |
| | | 581 | |
| | | 582 | /* Discover all the network interfaces. */ |
| | | 583 | discover_interfaces(DISCOVER_RELAY); |
| | | 584 | |
| | | 585 | #ifdef DHCPv6 |
| | | 586 | if (local_family == AF_INET6) |
| | | 587 | setup_streams(); |
| | | 588 | #endif |
| | | 589 | |
590 | /* Set up the packet handler... */ | | 590 | /* Set up the packet handler... */ |
591 | if (local_family == AF_INET) | | 591 | if (local_family == AF_INET) |
592 | bootp_packet_handler = do_relay4; | | 592 | bootp_packet_handler = do_relay4; |
593 | #ifdef DHCPv6 | | 593 | #ifdef DHCPv6 |
594 | else | | 594 | else |
595 | dhcpv6_packet_handler = do_packet6; | | 595 | dhcpv6_packet_handler = do_packet6; |
596 | #endif | | 596 | #endif |
597 | | | 597 | |
598 | #if defined(ENABLE_GENTLE_SHUTDOWN) | | 598 | #if defined(ENABLE_GENTLE_SHUTDOWN) |
599 | /* no signal handlers until we deal with the side effects */ | | 599 | /* no signal handlers until we deal with the side effects */ |
600 | /* install signal handlers */ | | 600 | /* install signal handlers */ |
601 | signal(SIGINT, dhcp_signal_handler); /* control-c */ | | 601 | signal(SIGINT, dhcp_signal_handler); /* control-c */ |
602 | signal(SIGTERM, dhcp_signal_handler); /* kill */ | | 602 | signal(SIGTERM, dhcp_signal_handler); /* kill */ |
| @@ -938,27 +938,27 @@ find_interface_by_agent_option(struct dh | | | @@ -938,27 +938,27 @@ find_interface_by_agent_option(struct dh |
938 | | | 938 | |
939 | /* If we didn't get a match, the circuit ID was bogus. */ | | 939 | /* If we didn't get a match, the circuit ID was bogus. */ |
940 | ++bad_circuit_id; | | 940 | ++bad_circuit_id; |
941 | return (-1); | | 941 | return (-1); |
942 | } | | 942 | } |
943 | | | 943 | |
944 | /* | | 944 | /* |
945 | * Examine a packet to see if it's a candidate to have a Relay | | 945 | * Examine a packet to see if it's a candidate to have a Relay |
946 | * Agent Information option tacked onto its tail. If it is, tack | | 946 | * Agent Information option tacked onto its tail. If it is, tack |
947 | * the option on. | | 947 | * the option on. |
948 | */ | | 948 | */ |
949 | | | 949 | |
950 | #include <sys/cdefs.h> | | 950 | #include <sys/cdefs.h> |
951 | __RCSID("$NetBSD: dhcrelay.c,v 1.6 2016/01/10 20:10:45 christos Exp $"); | | 951 | __RCSID("$NetBSD: dhcrelay.c,v 1.6.8.1 2017/06/10 06:30:07 snj Exp $"); |
952 | static int | | 952 | static int |
953 | add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, | | 953 | add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, |
954 | unsigned length, struct in_addr giaddr) { | | 954 | unsigned length, struct in_addr giaddr) { |
955 | int is_dhcp = 0, mms; | | 955 | int is_dhcp = 0, mms; |
956 | unsigned optlen; | | 956 | unsigned optlen; |
957 | u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; | | 957 | u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; |
958 | | | 958 | |
959 | /* If we're not adding agent options to packets, we can skip | | 959 | /* If we're not adding agent options to packets, we can skip |
960 | this. */ | | 960 | this. */ |
961 | if (!add_agent_options) | | 961 | if (!add_agent_options) |
962 | return (length); | | 962 | return (length); |
963 | | | 963 | |
964 | /* If there's no cookie, it's a bootp packet, so we should just | | 964 | /* If there's no cookie, it's a bootp packet, so we should just |