mirror of
https://github.com/sheumann/hush.git
synced 2025-01-10 16:29:44 +00:00
udhcp: add inline docs; small code shrink
function old new delta send_packet 103 87 -16 udhcpc_main 2359 2323 -36
This commit is contained in:
parent
7d9399e8dc
commit
739e30fbc3
@ -78,6 +78,23 @@ static void add_param_req_option(struct dhcpMessage *packet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RFC 2131
|
||||||
|
* 4.4.4 Use of broadcast and unicast
|
||||||
|
*
|
||||||
|
* The DHCP client broadcasts DHCPDISCOVER, DHCPREQUEST and DHCPINFORM
|
||||||
|
* messages, unless the client knows the address of a DHCP server.
|
||||||
|
* The client unicasts DHCPRELEASE messages to the server. Because
|
||||||
|
* the client is declining the use of the IP address supplied by the server,
|
||||||
|
* the client broadcasts DHCPDECLINE messages.
|
||||||
|
*
|
||||||
|
* When the DHCP client knows the address of a DHCP server, in either
|
||||||
|
* INIT or REBOOTING state, the client may use that address
|
||||||
|
* in the DHCPDISCOVER or DHCPREQUEST rather than the IP broadcast address.
|
||||||
|
* The client may also use unicast to send DHCPINFORM messages
|
||||||
|
* to a known DHCP server. If the client receives no response to DHCP
|
||||||
|
* messages sent to the IP address of a known DHCP server, the DHCP
|
||||||
|
* client reverts to using the IP broadcast address.
|
||||||
|
*/
|
||||||
|
|
||||||
static int raw_bcast_from_client_config_ifindex(struct dhcpMessage *packet)
|
static int raw_bcast_from_client_config_ifindex(struct dhcpMessage *packet)
|
||||||
{
|
{
|
||||||
@ -90,7 +107,6 @@ static int raw_bcast_from_client_config_ifindex(struct dhcpMessage *packet)
|
|||||||
|
|
||||||
#if ENABLE_FEATURE_UDHCPC_ARPING
|
#if ENABLE_FEATURE_UDHCPC_ARPING
|
||||||
/* Broadcast a DHCP decline message */
|
/* Broadcast a DHCP decline message */
|
||||||
//FIXME: maybe it should be unicast?
|
|
||||||
int FAST_FUNC send_decline(uint32_t xid, uint32_t server, uint32_t requested)
|
int FAST_FUNC send_decline(uint32_t xid, uint32_t server, uint32_t requested)
|
||||||
{
|
{
|
||||||
struct dhcpMessage packet;
|
struct dhcpMessage packet;
|
||||||
@ -128,7 +144,9 @@ int FAST_FUNC send_discover(uint32_t xid, uint32_t requested)
|
|||||||
|
|
||||||
|
|
||||||
/* Broadcasts a DHCP request message */
|
/* Broadcasts a DHCP request message */
|
||||||
//FIXME: maybe it should be unicast?
|
/* RFC 2131 3.1 paragraph 3:
|
||||||
|
* "The client _broadcasts_ a DHCPREQUEST message..."
|
||||||
|
*/
|
||||||
int FAST_FUNC send_select(uint32_t xid, uint32_t server, uint32_t requested)
|
int FAST_FUNC send_select(uint32_t xid, uint32_t server, uint32_t requested)
|
||||||
{
|
{
|
||||||
struct dhcpMessage packet;
|
struct dhcpMessage packet;
|
||||||
|
@ -27,21 +27,23 @@ extern const uint8_t MAC_BCAST_ADDR[6]; /* six all-ones */
|
|||||||
#define DHCP_OPTIONS_BUFSIZE 308
|
#define DHCP_OPTIONS_BUFSIZE 308
|
||||||
|
|
||||||
struct dhcpMessage {
|
struct dhcpMessage {
|
||||||
uint8_t op;
|
uint8_t op; /* 1 = BOOTREQUEST, 2 = BOOTREPLY */
|
||||||
uint8_t htype;
|
uint8_t htype; /* hardware address type. 1 = 10mb ethernet */
|
||||||
uint8_t hlen;
|
uint8_t hlen; /* hardware address length */
|
||||||
uint8_t hops;
|
uint8_t hops; /* used by relay agents only */
|
||||||
uint32_t xid;
|
uint32_t xid; /* unique id */
|
||||||
uint16_t secs;
|
uint16_t secs; /* elapsed since client began acquisition/renewal */
|
||||||
uint16_t flags;
|
uint16_t flags; /* only one flag so far: */
|
||||||
uint32_t ciaddr;
|
#define BROADCAST_FLAG 0x8000 /* "I need broadcast replies" */
|
||||||
uint32_t yiaddr;
|
uint32_t ciaddr; /* client IP (if client is in BOUND, RENEW or REBINDING state) */
|
||||||
uint32_t siaddr;
|
uint32_t yiaddr; /* 'your' (client) IP address */
|
||||||
uint32_t giaddr;
|
uint32_t siaddr; /* IP address of next server to use in bootstrap,
|
||||||
uint8_t chaddr[16];
|
* returned in DHCPOFFER, DHCPACK by server */
|
||||||
uint8_t sname[64];
|
uint32_t giaddr; /* relay agent IP address */
|
||||||
uint8_t file[128];
|
uint8_t chaddr[16];/* link-layer client hardware address (MAC) */
|
||||||
uint32_t cookie;
|
uint8_t sname[64]; /* server host name (ASCIZ) */
|
||||||
|
uint8_t file[128]; /* boot file name (ASCIZ) */
|
||||||
|
uint32_t cookie; /* fixed first four option bytes (99,130,83,99 dec) */
|
||||||
uint8_t options[DHCP_OPTIONS_BUFSIZE + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS];
|
uint8_t options[DHCP_OPTIONS_BUFSIZE + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS];
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* select() didn't timeout, something did happen. */
|
/* select() didn't timeout, something did happen. */
|
||||||
/* Is is a packet? */
|
/* Is it a packet? */
|
||||||
if (listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) {
|
if (listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) {
|
||||||
int len;
|
int len;
|
||||||
/* A packet is ready, read it */
|
/* A packet is ready, read it */
|
||||||
@ -474,7 +474,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (packet.xid != xid) {
|
if (packet.xid != xid) {
|
||||||
DEBUG("Ignoring XID %x (our xid is %x)",
|
DEBUG("Ignoring xid %x (our xid is %x)",
|
||||||
(unsigned)packet.xid, (unsigned)xid);
|
(unsigned)packet.xid, (unsigned)xid);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -524,17 +524,24 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
bb_error_msg("no lease time with ACK, using 1 hour lease");
|
bb_error_msg("no lease time with ACK, using 1 hour lease");
|
||||||
lease_seconds = 60 * 60;
|
lease_seconds = 60 * 60;
|
||||||
} else {
|
} else {
|
||||||
/* can be misaligned, thus memcpy */
|
/* it IS unaligned sometimes, don't "optimize" */
|
||||||
memcpy(&lease_seconds, temp, 4);
|
lease_seconds = get_unaligned_u32p((uint32_t*)temp);
|
||||||
lease_seconds = ntohl(lease_seconds);
|
lease_seconds = ntohl(lease_seconds);
|
||||||
lease_seconds &= 0x0fffffff; /* paranoia: must not be prone to overflows */
|
lease_seconds &= 0x0fffffff; /* paranoia: must not be prone to overflows */
|
||||||
if (lease_seconds < 10) /* and not too small */
|
if (lease_seconds < 10) /* and not too small */
|
||||||
lease_seconds = 10;
|
lease_seconds = 10;
|
||||||
}
|
}
|
||||||
//FIXME: why do we check ARP only after we've got DHCPACK?
|
|
||||||
//Shouldn't we do it immediately after DHCPOFFER?
|
|
||||||
#if ENABLE_FEATURE_UDHCPC_ARPING
|
#if ENABLE_FEATURE_UDHCPC_ARPING
|
||||||
if (opt & OPT_a) {
|
if (opt & OPT_a) {
|
||||||
|
/* RFC 2131 3.1 paragraph 5:
|
||||||
|
* "The client receives the DHCPACK message with configuration
|
||||||
|
* parameters. The client SHOULD perform a final check on the
|
||||||
|
* parameters (e.g., ARP for allocated network address), and notes
|
||||||
|
* the duration of the lease specified in the DHCPACK message. At this
|
||||||
|
* point, the client is configured. If the client detects that the
|
||||||
|
* address is already in use (e.g., through the use of ARP),
|
||||||
|
* the client MUST send a DHCPDECLINE message to the server and restarts
|
||||||
|
* the configuration process..." */
|
||||||
if (!arpping(packet.yiaddr,
|
if (!arpping(packet.yiaddr,
|
||||||
(uint32_t) 0,
|
(uint32_t) 0,
|
||||||
client_config.arp,
|
client_config.arp,
|
||||||
@ -542,8 +549,6 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
) {
|
) {
|
||||||
bb_info_msg("offered address is in use "
|
bb_info_msg("offered address is in use "
|
||||||
"(got ARP reply), declining");
|
"(got ARP reply), declining");
|
||||||
//NB: not clear whether it should be unicast or bcast.
|
|
||||||
//Currently it is a bcast. Why?
|
|
||||||
send_decline(xid, server_addr, packet.yiaddr);
|
send_decline(xid, server_addr, packet.yiaddr);
|
||||||
|
|
||||||
if (state != REQUESTING)
|
if (state != REQUESTING)
|
||||||
|
@ -78,16 +78,14 @@ enum {
|
|||||||
#define ETH_10MB 1
|
#define ETH_10MB 1
|
||||||
#define ETH_10MB_LEN 6
|
#define ETH_10MB_LEN 6
|
||||||
|
|
||||||
#define DHCPDISCOVER 1
|
#define DHCPDISCOVER 1 /* client -> server */
|
||||||
#define DHCPOFFER 2
|
#define DHCPOFFER 2 /* client <- server */
|
||||||
#define DHCPREQUEST 3
|
#define DHCPREQUEST 3 /* client -> server */
|
||||||
#define DHCPDECLINE 4
|
#define DHCPDECLINE 4 /* client -> server */
|
||||||
#define DHCPACK 5
|
#define DHCPACK 5 /* client <- server */
|
||||||
#define DHCPNAK 6
|
#define DHCPNAK 6 /* client <- server */
|
||||||
#define DHCPRELEASE 7
|
#define DHCPRELEASE 7 /* client -> server */
|
||||||
#define DHCPINFORM 8
|
#define DHCPINFORM 8 /* client -> server */
|
||||||
|
|
||||||
#define BROADCAST_FLAG 0x8000
|
|
||||||
|
|
||||||
#define OPTION_FIELD 0
|
#define OPTION_FIELD 0
|
||||||
#define FILE_FIELD 1
|
#define FILE_FIELD 1
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
void FAST_FUNC udhcp_init_header(struct dhcpMessage *packet, char type)
|
void FAST_FUNC udhcp_init_header(struct dhcpMessage *packet, char type)
|
||||||
{
|
{
|
||||||
memset(packet, 0, sizeof(struct dhcpMessage));
|
memset(packet, 0, sizeof(struct dhcpMessage));
|
||||||
packet->op = BOOTREQUEST;
|
packet->op = BOOTREQUEST; /* if client to a server */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DHCPOFFER:
|
case DHCPOFFER:
|
||||||
case DHCPACK:
|
case DHCPACK:
|
||||||
case DHCPNAK:
|
case DHCPNAK:
|
||||||
packet->op = BOOTREPLY;
|
packet->op = BOOTREPLY; /* if server to client */
|
||||||
}
|
}
|
||||||
packet->htype = ETH_10MB;
|
packet->htype = ETH_10MB;
|
||||||
packet->hlen = ETH_10MB_LEN;
|
packet->hlen = ETH_10MB_LEN;
|
||||||
@ -65,7 +65,7 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcpMessage *packet, int fd)
|
|||||||
if (vendor[OPT_LEN - 2] == (uint8_t)strlen(broken_vendors[i])
|
if (vendor[OPT_LEN - 2] == (uint8_t)strlen(broken_vendors[i])
|
||||||
&& !strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - 2])
|
&& !strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - 2])
|
||||||
) {
|
) {
|
||||||
DEBUG("broken client (%s), forcing broadcast",
|
DEBUG("broken client (%s), forcing broadcast replies",
|
||||||
broken_vendors[i]);
|
broken_vendors[i]);
|
||||||
packet->flags |= htons(BROADCAST_FLAG);
|
packet->flags |= htons(BROADCAST_FLAG);
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcpMessage *packet, int fd)
|
|||||||
if (vendor[OPT_LEN - 2] == (uint8_t)(sizeof("MSFT 98")-1)
|
if (vendor[OPT_LEN - 2] == (uint8_t)(sizeof("MSFT 98")-1)
|
||||||
&& memcmp(vendor, "MSFT 98", sizeof("MSFT 98")-1) == 0
|
&& memcmp(vendor, "MSFT 98", sizeof("MSFT 98")-1) == 0
|
||||||
) {
|
) {
|
||||||
DEBUG("broken client (%s), forcing broadcast", "MSFT 98");
|
DEBUG("broken client (%s), forcing broadcast replies", "MSFT 98");
|
||||||
packet->flags |= htons(BROADCAST_FLAG);
|
packet->flags |= htons(BROADCAST_FLAG);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,7 +50,7 @@ static int send_packet_to_client(struct dhcpMessage *payload, int force_broadcas
|
|||||||
DEBUG("unicasting packet to client ciaddr");
|
DEBUG("unicasting packet to client ciaddr");
|
||||||
ciaddr = payload->ciaddr;
|
ciaddr = payload->ciaddr;
|
||||||
chaddr = payload->chaddr;
|
chaddr = payload->chaddr;
|
||||||
} else if (ntohs(payload->flags) & BROADCAST_FLAG) {
|
} else if (payload->flags & htons(BROADCAST_FLAG)) {
|
||||||
DEBUG("broadcasting packet to client (requested)");
|
DEBUG("broadcasting packet to client (requested)");
|
||||||
ciaddr = INADDR_BROADCAST;
|
ciaddr = INADDR_BROADCAST;
|
||||||
chaddr = MAC_BCAST_ADDR;
|
chaddr = MAC_BCAST_ADDR;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user