aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKUMAAN <9maaan@gmail.com>2011-08-23 14:59:19 +0900
committermaximilian attems <max@stro.at>2012-05-22 10:55:16 +0200
commitf41c1d74c6a8e3d463e7e4291b112b367eb8b097 (patch)
treefff5ca4e9f0a64c673082bd7a6455572380ecf33
parent2f1c2933bc4cceb4766c4a7aedebe12c82be775d (diff)
downloadklibc-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.h3
-rw-r--r--usr/kinit/ipconfig/dhcp_proto.c18
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);
}