diff options
author | KUMAAN <9maaan@gmail.com> | 2011-08-23 14:59:19 +0900 |
---|---|---|
committer | maximilian attems <max@stro.at> | 2012-05-22 10:55:16 +0200 |
commit | f41c1d74c6a8e3d463e7e4291b112b367eb8b097 (patch) | |
tree | fff5ca4e9f0a64c673082bd7a6455572380ecf33 | |
parent | 2f1c2933bc4cceb4766c4a7aedebe12c82be775d (diff) | |
download | klibc-f41c1d74c6a8e3d463e7e4291b112b367eb8b097.tar.gz |
[klibc] ipconfig: Append padding if DHCP packet length < 300 octets
This patch appends padding to DHCP packet for its length to be 300 octets,
if its length is shorter than 300 octets.
dhclient in ISC DHCP 4.1.1-P1 also does so. Some bad DHCP servers ignore
short DHCP packet which dhclient doesn't send.
Signed-off-by: KUMAAN <9maaan@gmail.com>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: maximilian attems <max@stro.at>
-rw-r--r-- | usr/kinit/ipconfig/bootp_packet.h | 3 | ||||
-rw-r--r-- | usr/kinit/ipconfig/dhcp_proto.c | 18 |
2 files changed, 20 insertions, 1 deletions
diff --git a/usr/kinit/ipconfig/bootp_packet.h b/usr/kinit/ipconfig/bootp_packet.h index 1ef505e4075e72..1d5bd0dfc9dd5b 100644 --- a/usr/kinit/ipconfig/bootp_packet.h +++ b/usr/kinit/ipconfig/bootp_packet.h @@ -38,4 +38,7 @@ struct bootp_hdr { /* larger size for backward compatibility of ipconfig */ #define BOOTP_EXTS_SIZE 1500 +/* minimum length of BOOTP/DHCP packet on sending */ +#define BOOTP_MIN_LEN 300 + #endif /* BOOTP_PACKET_H */ diff --git a/usr/kinit/ipconfig/dhcp_proto.c b/usr/kinit/ipconfig/dhcp_proto.c index 0c907e9466a842..ebf79cc0b5f710 100644 --- a/usr/kinit/ipconfig/dhcp_proto.c +++ b/usr/kinit/ipconfig/dhcp_proto.c @@ -50,7 +50,7 @@ static uint8_t dhcp_end[] = { /* Both iovecs below have to have the same structure, since dhcp_send() pokes at the internals */ -#define DHCP_IOV_LEN 7 +#define DHCP_IOV_LEN 8 static struct iovec dhcp_discover_iov[DHCP_IOV_LEN] = { /* [0] = ip + udp header */ @@ -60,6 +60,7 @@ static struct iovec dhcp_discover_iov[DHCP_IOV_LEN] = { /* [4] = optional vendor class */ /* [5] = optional hostname */ /* [6] = {dhcp_end, sizeof(dhcp_end)} */ + /* [7] = optional padding */ }; static struct iovec dhcp_request_iov[DHCP_IOV_LEN] = { @@ -70,6 +71,7 @@ static struct iovec dhcp_request_iov[DHCP_IOV_LEN] = { /* [4] = optional vendor class */ /* [5] = optional hostname */ /* [6] = {dhcp_end, sizeof(dhcp_end)} */ + /* [7] = optional padding */ }; /* @@ -187,7 +189,10 @@ static int dhcp_send(struct netdev *dev, struct iovec *vec) { struct bootp_hdr bootp; char dhcp_hostname[SYS_NMLN+2]; + uint8_t padding[BOOTP_MIN_LEN - sizeof(struct bootp_hdr)]; + int padding_len; int i = 4; + int j; memset(&bootp, 0, sizeof(struct bootp_hdr)); @@ -232,6 +237,17 @@ static int dhcp_send(struct netdev *dev, struct iovec *vec) vec[i].iov_base = dhcp_end; vec[i].iov_len = sizeof(dhcp_end); + /* Append padding if DHCP packet length is shorter than BOOTP_MIN_LEN */ + padding_len = sizeof(padding); + for (j = 2; j <= i; j++) + padding_len -= vec[j].iov_len; + if (padding_len > 0) { + memset(padding, 0, padding_len); + i++; + vec[i].iov_base = padding; + vec[i].iov_len = padding_len; + } + return packet_send(dev, vec, i + 1); } |