static int inet_sock;
static int forward_bcast;
static int forward_dhcp;
+static int parse_dhcp;
uint8_t local_addr[4];
int local_route_table;
fill_arp_packet(&pkt, rif, rif->src_ip, ipaddr);
pkt.arp.arp_op = htons(ARPOP_REQUEST);
- memcpy(pkt.arp.arp_spa, rif->src_ip, ETH_ALEN);
+ memcpy(pkt.arp.arp_spa, rif->src_ip, sizeof(pkt.arp.arp_spa));
memset(pkt.arp.arp_tha, 0, ETH_ALEN);
memset(pkt.eth.ether_dhost, 0xff, ETH_ALEN);
static void host_entry_timeout(struct uloop_timeout *timeout)
{
struct relayd_host *host = container_of(timeout, struct relayd_host, timeout);
+ struct relayd_interface *rif;
/*
* When a host is behind a managed interface, we must not expire its host
* giving up on it.
*/
if (host->rif->managed && host->cleanup_pending < host_ping_tries) {
- send_arp_request(host->rif, host->ipaddr);
+ list_for_each_entry(rif, &interfaces, list) {
+ send_arp_request(rif, host->ipaddr);
+ }
host->cleanup_pending++;
uloop_timeout_set(&host->timeout, 1000);
return;
if (!memcmp(pkt->arp.arp_spa, "\x00\x00\x00\x00", 4))
return;
+ host = find_host_by_ipaddr(NULL, pkt->arp.arp_spa);
+ if (!host || host->rif != rif)
+ relayd_refresh_host(rif, pkt->eth.ether_shost, pkt->arp.arp_spa);
+
if (local_route_table && !memcmp(pkt->arp.arp_tpa, local_addr, sizeof(local_addr))) {
send_arp_reply(rif, local_addr, pkt->arp.arp_sha, pkt->arp.arp_spa);
return;
}
- host = find_host_by_ipaddr(NULL, pkt->arp.arp_spa);
- if (!host || host->rif != rif)
- relayd_refresh_host(rif, pkt->eth.ether_shost, pkt->arp.arp_spa);
-
host = find_host_by_ipaddr(NULL, pkt->arp.arp_tpa);
/*
if (!forward_bcast && !forward_dhcp)
continue;
- if (relayd_handle_dhcp_packet(rif, pktbuf, pktlen, forward_dhcp))
+ if (relayd_handle_dhcp_packet(rif, pktbuf, pktlen, forward_dhcp, parse_dhcp))
continue;
if (forward_bcast)
}
#ifdef PACKET_RECV_TYPE
- pkt_type = (1 << PACKET_BROADCAST);
+ pkt_type = (1 << PACKET_BROADCAST) | (1 << PACKET_MULTICAST);
setsockopt(fd, SOL_PACKET, PACKET_RECV_TYPE, &pkt_type, sizeof(pkt_type));
#endif
if (strlen(ifname) >= IFNAMSIZ)
return NULL;
+ list_for_each_entry(rif, &interfaces, list) {
+ if (!strncmp(rif->ifname, ifname, IFNAMSIZ))
+ return rif;
+ }
+
rif = calloc(1, sizeof(*rif));
if (!rif)
return NULL;
* When we hit SIGTERM, clean up interfaces directly, so that we
* won't leave our routing in an invalid state.
*/
- cleanup_hosts();
- free_interfaces();
- exit(1);
+ uloop_end();
}
static int usage(const char *progname)
" -T <table> Set routing table number for automatically added routes\n"
" -B Enable broadcast forwarding\n"
" -D Enable DHCP forwarding\n"
+ " -P Disable DHCP options parsing\n"
" -L <ipaddr> Enable local access using <ipaddr> as source address\n"
"\n",
progname);
struct relayd_interface *rif = NULL;
struct in_addr addr, addr2;
bool local_addr_valid = false;
- bool managed;
+ bool managed = false;
int ifnum = 0;
char *s, *s2;
int mask;
host_ping_tries = 5;
forward_bcast = 0;
local_route_table = 0;
+ parse_dhcp = 1;
uloop_init();
- while ((ch = getopt(argc, argv, "I:i:t:BDdT:G:R:L:")) != -1) {
+ while ((ch = getopt(argc, argv, "I:i:t:p:BDPdT:G:R:L:")) != -1) {
switch(ch) {
case 'I':
managed = true;
case 'D':
forward_dhcp = 1;
break;
+ case 'P':
+ parse_dhcp = 0;
+ break;
case 'T':
route_table = atoi(optarg);
if (route_table <= 0)