diff options
Diffstat (limited to 'relay/dhcrelay.c')
-rw-r--r-- | relay/dhcrelay.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index c72d6f31..4127fccc 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -153,6 +153,7 @@ char *progname; " [-pf <pid-file>] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ +" [-iu interface0 [ ... -iu interfaceN]\n" \ " [-U interface]\n" \ " server0 [ ... serverN]\n\n" \ " %s -6 [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \ @@ -168,6 +169,7 @@ char *progname; " [-pf <pid-file>] [--no-pid]\n" \ " [-m append|replace|forward|discard]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ +" [-iu interface0 [ ... -iu interfaceN]\n" \ " [-U interface]\n" \ " server0 [ ... serverN]\n\n" #endif @@ -325,7 +327,34 @@ main(int argc, char **argv) { isc_result_totext(status)); } strcpy(tmp->name, argv[i]); - interface_snorf(tmp, INTERFACE_REQUESTED); + interface_snorf(tmp, (INTERFACE_REQUESTED | + INTERFACE_STREAMS)); + interface_dereference(&tmp, MDL); + } else if (!strcmp(argv[i], "-iu")) { +#ifdef DHCPv6 + if (local_family_set && (local_family == AF_INET6)) { + usage(use_v4command, argv[i]); + } + local_family_set = 1; + local_family = AF_INET; +#endif + if (++i == argc) { + usage(use_noarg, argv[i-1]); + } + if (strlen(argv[i]) >= sizeof(tmp->name)) { + log_fatal("%s: interface name too long " + "(is %ld)", + argv[i], (long)strlen(argv[i])); + } + status = interface_allocate(&tmp, MDL); + if (status != ISC_R_SUCCESS) { + log_fatal("%s: interface_allocate: %s", + argv[i], + isc_result_totext(status)); + } + strcpy(tmp->name, argv[i]); + interface_snorf(tmp, (INTERFACE_REQUESTED | + INTERFACE_UPSTREAM)); interface_dereference(&tmp, MDL); } else if (!strcmp(argv[i], "-a")) { #ifdef DHCPv6 @@ -398,7 +427,8 @@ main(int argc, char **argv) { uplink->name[sizeof(uplink->name) - 1] = 0x00; strncpy(uplink->name, argv[i], sizeof(uplink->name) - 1); - interface_snorf(uplink, INTERFACE_REQUESTED); + interface_snorf(uplink, (INTERFACE_REQUESTED | + INTERFACE_STREAMS)); /* Turn on -a, in case they don't do so explicitly */ add_agent_options = 1; @@ -730,6 +760,11 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, /* If it's a bootreply, forward it to the client. */ if (packet->op == BOOTREPLY) { + if (!(ip->flags & INTERFACE_UPSTREAM)) { + log_debug("Dropping reply received on %s", ip->name); + return; + } + if (!(packet->flags & htons(BOOTP_BROADCAST)) && can_unicast_without_arp(out)) { to.sin_addr = packet->yiaddr; |