is received that is discarded by ndhc's basic checks and provokes a busy
loop in the main program loop because epoll_wait() constantly sees data that
is never drained from the socket buffer since arp_offset exceeds the
maximum size of an ARP packet and would overflow the packet buffer.
buffer and length instead take a pointer to a struct dhcpmsg. This argument
list choice implicitly gives safe length checks and is simpler.
Remove DHCP_OPTIONS_LENGTH.
Fold set_option() into alloc_option().
Make some more functions in options.[ch] static.
because safe_read() already protects against reads longer than a DHCP
packet in length.
Lots of cosmetic cleanups. Highlights:
- Remove pointless enums that just define sizeof for various structures.
- Rename struct dhcpMessage to struct dhcpmsg.
udp packet and use them in get_raw_packet().
Print a warning if the raw UDP receive gets a quantum of data that is greater
than that of a single UDP datagram.
Remove unnecessary argument from net_checksum(). Initializing a nonzero
checksum value is not very helpful in practice.
Define a function net_checksum_add() that, for two sequences of bytes A and B
that return checksums CS(A) and CS(B), will calculate the checksum CS(AB) of
the concatenated value AB given the checksums of the individual parts CS(A)
and CS(B).
overflow when given ridiculously large data lengths. In practice, undefined
behavior would never occur with the previous function since it would have
required IP packets >128KiB bytes in length and the maximum length for an
IP packet is 64KiB.
The new checksum function is also a bit more flexible (allowing a starting
checksum value != 0), clearly is endian independent, and does no typesystem
abuse. It's boringly correct standard C.
Use C99 structure initializers for forming raw UDP packets for send.
Rename raw_packet() to send_dhcp_raw() and strip of unnecessary arguments.
Rename kernel_packet() to send_dhcp_cooked() and strip of unnecessary
arguments.
Remove the ugly bcast_raw_packet() wrapper hack.
- Use SO_DONTROUTE for dhcp listen and send sockets (both raw and udp).
More paranoia against packets being sent to incorrect interfaces:
- Bind arp socket to a specific interface via bind().
- Use SO_BINDTODEVICE for udp send sockets. It was already used for udp
listen sockets.
Flatten indentation in arp_(open|close)_fd().
Use C99 initializers in packet.c.
Add more error message prints to packet.c.
- Use AF_PACKET and SOCK_RAW rather than the decade-deprecated
SOCK_PACKET interface.
- Separate out socket creation code into a subfunction.
- Use C99 initializers for packet and address structures.
- Cosmetic cleanups.
check was overzealous and would drop valid packets. Now the minimal
packet size that is tolerated is 32 bytes.
24 bytes would be enough for the client IP, but I very much doubt that any
server would leave out the non-optional fields of siaddr and giaddr as well as
chaddr. We already tolerate elided chaddr with a cut-off of 32 bytes, which is
dubious enough.
Handle EAGAIN and EWOULDBLOCK more gracefully when dealing with safe_read().
All occurrences of safe_read() should only be invoked on fds that have signaled
ready-to-read state via the epoll() mechanism, so this change should not
result in any observable difference, but it is best to be safe.
Additionally, a constant stack variable is converted to an equivalent
macro define for cleanliness.
Finally, print the error type encountered if reading data from an ARP response
fails with a read error.