Adds two new read handlers, "gateway" and "netmask", which return the
DHCP-provided gateway router and netmask respectively.
--- dhcpclient.cc 2009-02-22 14:52:34.000000000 -0800
+++
/Users/nweaver/archive/honeyfarm/nw_misc/remote_tunnel/click_dhcp/dhcpclient.cc
2010-04-15 14:42:15.000000000 -0700
@@ -100,6 +100,17 @@
else
_server_ip = IPAddress();
+ if (const uint8_t *gateway = DHCPOptionUtil::fetch(p, DHO_ROUTERS, 4))
+ _gateway_ip = IPAddress(gateway);
+ else
+ _gateway_ip = IPAddress();
+
+ if (const uint8_t *netmask = DHCPOptionUtil::fetch(p, DHO_SUBNET_MASK, 4))
+ _netmask = IPAddress(netmask);
+ else
+ _netmask = IPAddress();
+
+
if (_lease_call)
_lease_call->call_write(unparse_lease());
@@ -541,6 +552,10 @@
return dc->_server_ip.unparse();
case 2:
return dc->unparse_lease();
+ case 3:
+ return dc->_gateway_ip.unparse();
+ case 4:
+ return dc->_netmask.unparse();
default:
return String();
}
@@ -552,6 +567,8 @@
add_read_handler("addr", read_handler, (void*)0);
add_read_handler("server", read_handler, (void*)1);
add_read_handler("lease", read_handler, (void*)2);
+ add_read_handler("gateway", read_handler, (void*)3);
+ add_read_handler("netmask", read_handler, (void*)4);
add_write_handler("lease", write_handler, (void*)0);
add_write_handler("release", write_handler, (void*)1);
}
--- dhcpclient.hh 2007-09-12 12:15:38.000000000 -0700
+++
/Users/nweaver/archive/honeyfarm/nw_misc/remote_tunnel/click_dhcp/dhcpclient.hh
2010-04-15 14:42:15.000000000 -0700
@@ -47,6 +47,14 @@
Returns the server's current IP address.
+=h gateway read-only
+
+Returns the gateway's IP address.
+
+=h netmask read-only
+
+Returns the local subnet mask.
+
=h lease read/write
The read handler returns information about the currently active DHCP lease.
@@ -147,6 +155,8 @@
EtherAddress _ethAddr;
IPAddress _my_ip;
IPAddress _server_ip;
+ IPAddress _gateway_ip;
+ IPAddress _netmask;
uint32_t _lease_duration;
uint32_t _start_timestamp_sec;
uint32_t _t1_timestamp_sec;
Useful in combination with the following patch to arpquerier.cc/arpquerier.hh,
which adds a new read/write handler for gateway and netmask.
When those are set, and the destination is not on the same subnet, it instead
ARPs for the gateway machine.
--- arpquerier.cc 2009-11-25 12:43:54.000000000 -0800
+++ /Users/nweaver/click/elements/ethernet/arpquerier.cc 2010-04-15
14:35:19.000000000 -0700
@@ -92,6 +92,9 @@
cpEnd) < 0)
return -1;
+ _my_gateway = IPAddress("0.0.0.0");
+ _my_netmask = my_mask;
+
if (!have_broadcast) {
_my_bcast_ip = _my_ip | ~my_mask;
if (_my_bcast_ip == _my_ip)
@@ -229,7 +232,20 @@
memcpy(ea->arp_spa, _my_ip.data(), 4);
memset(ea->arp_tha, 0, 6);
IPAddress want_ip = p->dst_ip_anno();
- memcpy(ea->arp_tpa, want_ip.data(), 4);
+
+ IPAddress my_mask = _my_netmask & _my_ip;
+ IPAddress other_mask = _my_netmask & want_ip;
+
+
+ if(my_mask == other_mask ||
+ _my_gateway == IPAddress("0.0.0.0")){
+ // On the same subnet or no gateway assigned
+ memcpy(ea->arp_tpa, want_ip.data(), 4);
+ } else {
+ // On a different subnet, so need to ARP for the gateway's IP
+ memcpy(ea->arp_tpa, _my_gateway.data(), 4);
+ }
+
q->set_timestamp_anno(p->timestamp_anno());
@@ -269,6 +285,18 @@
EtherAddress *dst_eth = reinterpret_cast<EtherAddress
*>(q->ether_header()->ether_dhost);
int r;
+ IPAddress my_mask = _my_netmask & _my_ip;
+ IPAddress other_mask = _my_netmask & dst_ip;
+
+
+ if(my_mask == other_mask ||
+ _my_gateway == IPAddress("0.0.0.0")){
+ // On same subnet, or no gateway, so no change
+ } else {
+ // Needs to go to the gateway's MAC address
+ dst_ip = _my_gateway;
+ }
+
// Easy case: requires only read lock
retry_read_lock:
r = _arpt->lookup(dst_ip, dst_eth, _poll_timeout_j);
@@ -411,6 +439,10 @@
add_data_handlers("drops", Handler::OP_READ, &_drops);
add_data_handlers("broadcast", Handler::OP_READ | Handler::OP_WRITE,
&_my_bcast_ip);
add_data_handlers("ipaddr", Handler::OP_READ | Handler::OP_WRITE, &_my_ip);
+ add_data_handlers("gateway",
+ Handler::OP_READ | Handler::OP_WRITE, &_my_gateway);
+ add_data_handlers("netmask",
+ Handler::OP_READ | Handler::OP_WRITE, &_my_netmask);
add_write_handler("insert", write_handler, h_insert);
add_write_handler("delete", write_handler, h_delete);
add_write_handler("clear", write_handler, h_clear);
--- arpquerier.hh 2009-11-06 15:06:37.000000000 -0800
+++ /Users/nweaver/click/elements/ethernet/arpquerier.hh 2010-04-15
12:33:39.000000000 -0700
@@ -191,6 +191,8 @@
EtherAddress _my_en;
IPAddress _my_ip;
IPAddress _my_bcast_ip;
+ IPAddress _my_gateway;
+ IPAddress _my_netmask;
uint32_t _poll_timeout_j;
int _broadcast_poll;
Together, this allows for a click configuration to grab a DHCP lease (for
whatever MAC address is desired) and then make sure that packets to the subnet
are ARP'ed as usual, but packets to other networks are sent directly to the
gateway.
_______________________________________________
click mailing list
[email protected]
https://amsterdam.lcs.mit.edu/mailman/listinfo/click