Commit Graph

254 Commits

Author SHA1 Message Date
Nicholas J. Kain
e0ef11848b Record the MAC address of the DHCP server and use it to identify the network
when the hardware link carrier is dropped and comes back.  Also, don't assume
that all networks have a default gateway.

Guard against spurious arp defense attempts that might be triggered by packets
that are still in the socket buffer from before the BPF was changed.

Split apart the AS_GW_CHECK and AS_GW_QUERY timeout handlers.

Cosmetic cleanups in state.c.
2011-07-11 13:24:59 -04:00
Nicholas J. Kain
83594bce4a Track pending events in time by using absolute times rather than relative
timeouts.
2011-07-11 11:31:27 -04:00
Nicholas J. Kain
9b3e1872cb Rather than use a single cs.timeout value, track individual timeouts for every
ARP state and for the current DHCP state.
2011-07-11 10:39:36 -04:00
Nicholas J. Kain
8c30c82240 Optimize timeout calculations so that curms() is called fewer times and
the timeout intervals are a bit more exact.
2011-07-11 08:59:50 -04:00
Nicholas J. Kain
2e328b6913 Don't strip high bit from lease time.
Change order of operations to prevent overflow with very long leases when
calculating rebind time duration.
2011-07-11 08:01:56 -04:00
Nicholas J. Kain
9762fa5315 Constify some more static structs. 2011-07-11 05:35:40 -04:00
Nicholas J. Kain
1e71f82f3a Refactor the ARP code to be similar to the dhcp code -- timeout functions and
packet response functions are handled by an array of function pointers indexed
by ARP state.

Split arp_retransmit() apart into simpler functions.

Fix a typo in renewing_timeout() that would result in too-short timeouts that
would soak cpu.

Call handle_arp_timeout() from the timeout_action() function rather than
having
explicit hooks in various <dhcpstate>_timeout() functions.

Make the function pointer arrays static const.
2011-07-11 05:09:38 -04:00
Nicholas J. Kain
8beb1d12d1 Fix a regression: if renewing or rebinding a dhcp lease that matches our
previous client ip, make sure to stop listening for dhcp packets, set the
proper timeout interval, and make sure we're in AS_DEFENSE state.
2011-07-06 11:41:49 -04:00
Nicholas J. Kain
080fefaea0 Handle hardware link state loss and restoration on networks that lack a
default gw properly.
2011-07-06 11:32:22 -04:00
Nicholas J. Kain
ad5c5d6803 Only perform arpreply_clear() after consuming an arp packet in
handle_arp_response() and when opening a new arp fd.  Do not clear the
arpreply buffer and offset on ARP state transitions.

Only perform ARP collision probing when binding a new lease from the
DS_REQUESTING state, or if we have renewed or rebound a lease with a different
IP than we had before.

Resequence the arp_dhcp_packet memcpy() in arp_check() so that the current
IP address is ARP checked rather than the previous one.
2011-07-06 09:26:07 -04:00
Nicholas J. Kain
a92cb1c4c6 Randomize the DHCP timeout by +[0,1000]ms to comply with RFC. 2011-07-06 08:46:05 -04:00
Nicholas J. Kain
daf42ccb29 Change ifchange_*() so that the interface and ip keywords are only sent to
ifchd if it is necessary to do so, just as is the case for other keywords.

Make data sending in ifchange_*() collect all keywords into a buffer that
is sent in a single sockwrite() rather than performing a sockwrite() for
every keyword.

Minor documentation updates.
2011-07-05 19:25:19 -04:00
Nicholas J. Kain
3316505f3c Define set_released() and use it for entering the DS_RELEASED state. 2011-07-05 18:29:06 -04:00
Nicholas J. Kain
3f496f7997 Clean up frenew(). It should only perform work in DS_RELEASED and DS_BOUND. 2011-07-05 18:18:57 -04:00
Nicholas J. Kain
04c380cd3b Call arp_close_fd() from reinit_selecting(). 2011-07-05 16:02:11 -04:00
Nicholas J. Kain
3205f823d9 Handle DS_REBINDING and DS_RENEWING states just like DS_BOUND when the
hardware link returns after having been lost.

Make the timeout action for DS_BOUND_GW_CHECK perform ARP retransmissions
rather than just sending a single query.
2011-07-05 15:57:11 -04:00
Nicholas J. Kain
3196ad750e cs->packetNum is not descriptive and is not used outside of state.c.
Rename it to num_dhcp_requests that is a static global to state.c.
2011-07-05 15:44:11 -04:00
Nicholas J. Kain
315cf6b135 Send probe requests in COLLISION_CHECK state in a way that is compliant with
RFC5227.  Rate-limiting is also supported.

Keep ARP stats per packet send type rather than per ARP state.  Use the new
stats to replace last_def_ts.

Multiple triggers of arp_gw_check from interface-up-events in quick succession
could cause the dhcpState to become corrupt.  Fix by making the ARP_GW_CHECK
be level triggered rather than edge triggered.

Make the timeout calculations in the ARP retransmission code much more
accurate.

Close the ARP fd if we give up on lease defense and go back to requesting a
new lease.

Do a second arp_announcement() after finding the default GW's hwaddr.

Clean up frenew to sanely handle the various ARP checking events.  Now renew
signals will be ignored during these states.  It was particularly insane
before if a renew signal were received during DS_COLLISION_CHECK.

If the hardware link carrier goes down, do not sleep.  Just keep working.
Only go to sleep if the user explicitly deconfigures the interface.  This
change is far more sane for non-mobile hosts, and still works fine with
roaming machines: the important thing is the gw hardware address checking that
is triggered when the interface comes back up.
2011-07-05 15:40:57 -04:00
Nicholas J. Kain
751ef43b45 Remove DEBUG prints. 2011-07-05 13:04:34 -04:00
Nicholas J. Kain
8b27b41c0c Enable active defense of IP address / lease, as described in RFC5227. 2011-07-05 13:03:55 -04:00
Nicholas J. Kain
74a79314d7 Document the --vendorid and --leasefile options in --help. 2011-07-05 11:18:28 -04:00
Nicholas J. Kain
f9809d74a4 Remove the -H alias for --hostname. 2011-07-05 11:14:35 -04:00
Nicholas J. Kain
f1fcd4dc16 Perform timeout-based ARP retransmission for AS_GW_CHECK and AS_GW_QUERY. 2011-07-05 11:07:42 -04:00
Nicholas J. Kain
a9c807c1df Rename DS_ARP_CHECK to the less confusing DS_COLLISION_CHECK.
Call arp_reopen_fd() if reading from the arp fd fails in any state other
than AS_COLLISION_CHECK or AS_GW_CHECK.
2011-07-04 22:59:07 -04:00
Nicholas J. Kain
b3acad9166 Use reinit_selecting() in arp.c. 2011-07-04 22:52:53 -04:00
Nicholas J. Kain
c79c65454c If sending on the arp fd fails, then re-open the arp fd and restore arp
state to what it was before closing the fd.  It may allow the client to
continue working in the face of error, as arp functionality is not critical
for simply holding a lease.
2011-07-04 22:35:53 -04:00
Nicholas J. Kain
4453391154 Move dhcp state handling code out of netlink.c and into state.c. netlink.c
now just calls hooks exposed by state.c, just like the dhcp packet,
poll timeout, and signal code.

Make ifchange_deconfig() idempotent.
2011-07-04 22:10:14 -04:00
Nicholas J. Kain
88804e0102 Cache the last configured dhcp packet in ifchange.c. Only send updates that
differ from what already existed.
2011-07-04 21:40:32 -04:00
Nicholas J. Kain
9ef66af020 Simplify the ifchange API. 2011-07-04 20:51:27 -04:00
Nicholas J. Kain
bb83b14237 Refactor the common ARP structure fields between arp sending functions
into the BASE_ARPMSG() macro to make it more obvious what is shared.

Resequence the gateway arp address print and the arp state change to
AS_DEFENSE so that the debug prints are less confusing.  No other change.
2011-07-04 20:19:30 -04:00
Nicholas J. Kain
dca662cd27 Massive overhaul to arp.c in preparation for adding address defense:
Use a separate state machine for the arp handling.  It's loosely coupled to
the dhcp code, and is thus much easier to reason about than the previous
approach that made the arp code use the dhcp state.

Add a BPF and C emulation of the BPF for RFC5227-style address defense.  Allow
switchable BPF filters for the arp socket.

Fix a regression introduced in the arp announcement commit.  Contrary to
RFC5227, the 'h_dest' field in the ARP packet should be set to all 0xff
for wildcard semantics, not all 0x00.

Keep track of the millisecond timestamp of the most recent ARP packet that has
been sent as well as the total number of packets that have been sent in
the current ARP state.  Use these values to implement time-based ARP
retransmit.

When querying the default gateway/router, use ARP packets that have the
source IP set to the client lease IP rather than 0.0.0.0.

Combine common code in the arp sending functions into arp_send().

Resequence the arp_announcement() in arp_success() so that it happens after
the interface is configured by ifchange() / ifchd.

Get rid of layering hack in ifchange.c to set the router address in the
client state.  Do it in the proper place in arp.c.

Add an early exit before ifchd_cmd() in ifchange.c.  This change prevents
sending a ':' to ifchd for a string type option with no string content.
2011-07-04 20:07:16 -04:00
Nicholas J. Kain
be44bf0a04 Resequence operations in selecting_timeout() so that two packets are sent with
corresponding waits for responses rather than sending two packets and
immediately backgrounding or failing after the second is sent without waiting
for a response.

Set sll_pkttype = PACKET_BROADCAST on outgoing raw dhcp packets.

Condense arguments for send_dhcp_cooked().
2011-07-03 18:56:57 -04:00
Nicholas J. Kain
e4ff1e9261 Remove the ugly hack for forcing nl_getifdata() to be synchronous. It now
properly performs a synchronous wait using poll().
2011-07-03 18:10:00 -04:00
Nicholas J. Kain
01c4731403 Make sure that the netlink socket will never block after program
initialization.  Fetching if/address/index/mac mappings is done only once at
program init, so it is done synchronously as an exception to this rule.

Rewrite the netlink handling.  Now uses NIH code that should be safe, small,
and correct.  No external deps FTW.
2011-07-03 17:30:55 -04:00
Nicholas J. Kain
2c2cc1cf22 Don't send host name option on DHCP decline or release packets. 2011-07-03 06:03:54 -04:00
Nicholas J. Kain
aa61d71f7d Autodetect if the clientid parameter is a valid mac address and treat it
accordingly.  Don't require an explicit parameter for it.
2011-07-03 05:45:05 -04:00
Nicholas J. Kain
f08c174725 Add clientid-mac option for sending a MAC address as a client identifier
other than our own.
2011-07-03 05:36:47 -04:00
Nicholas J. Kain
f84cdbde1e Fix regression:
Make the clientid to attach the ethernet type byte prefix to the option.
2011-07-03 04:33:16 -04:00
Nicholas J. Kain
801ec356f4 Convert DHCP option code numbers to an enum.
Convert many remaining /**/ comments to // where it makes for less visual
clutter.
2011-07-02 06:31:57 -04:00
Nicholas J. Kain
9224374d98 Send an ARP announcement after getting a new lease. 2011-07-02 05:48:24 -04:00
Nicholas J. Kain
d304fb6b38 Only bring down the interface at startup time if it is not already up and
running.  ndhc does its job entirely with raw sockets before a lease is
established, so it will work just fine, and this change allows for the dhcp
client to be re-run without causing downtime on an interface.
2011-07-02 04:58:58 -04:00
Nicholas J. Kain
46ed7f5998 Enforce stronger type checking on DHCP option values. Fix some endianness
issues as well.
2011-07-02 04:45:11 -04:00
Nicholas J. Kain
cfd9822252 Rename packet.[ch] to dhcp.[ch]. 2011-07-02 03:51:44 -04:00
Nicholas J. Kain
d9571c62cf Don't use malloc in ndhc. The only place it was used is in the options code.
Allow the user to specify the vendor identification option value using the
-V switch.  The default value is still "ndhc".
2011-07-02 03:48:08 -04:00
Nicholas J. Kain
7104b56ab9 Change netlink event handling so that the DHCP client will sleep if the
interface carrier is lost or the interface is deconfigured but still exists,
eg via ifconfig down.  If the hardware is removed, then ndhcp will exit.
2011-07-02 01:51:32 -04:00
Nicholas J. Kain
17570e9a38 Rewrite the netlink handling code to use libmnl. The size cost is very small,
and it is hard to do netlink completely correctly as it is poorly documented.
2011-07-02 01:34:50 -04:00
Nicholas J. Kain
38ad2399ed Clean up the DHCP packet sending functions and make them more RFC-compliant.
Rename cs->requestedIP to cs->clientAddr.
Move the IFS_* defines into netlink.c.
Cosmetic cleanups.
2011-07-01 11:37:13 -04:00
Nicholas J. Kain
a68c8cb64c Make the log prints less debug-like and more sysadmin-friendly. 2011-07-01 05:49:39 -04:00
Nicholas J. Kain
e1262cd563 Cosmetic cleanup of create_udp_listen_socket() to eliminate invariant
arguments.
2011-07-01 05:35:38 -04:00
Nicholas J. Kain
9974cc2f51 Separate out dhcp packet validation into validate_dhcp_packet(). 2011-07-01 05:33:12 -04:00