aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/packet.c')
-rw-r--r--networking/udhcp/packet.c57
1 files changed, 14 insertions, 43 deletions
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index 4d5ff0676..33c9585cf 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -81,7 +81,6 @@ void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet)
81int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) 81int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd)
82{ 82{
83 int bytes; 83 int bytes;
84 unsigned char *vendor;
85 84
86 memset(packet, 0, sizeof(*packet)); 85 memset(packet, 0, sizeof(*packet));
87 bytes = safe_read(fd, packet, sizeof(*packet)); 86 bytes = safe_read(fd, packet, sizeof(*packet));
@@ -90,42 +89,15 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd)
90 return bytes; /* returns -1 */ 89 return bytes; /* returns -1 */
91 } 90 }
92 91
93 if (packet->cookie != htonl(DHCP_MAGIC)) { 92 if (bytes < offsetof(struct dhcp_packet, options)
93 || packet->cookie != htonl(DHCP_MAGIC)
94 ) {
94 bb_info_msg("Packet with bad magic, ignoring"); 95 bb_info_msg("Packet with bad magic, ignoring");
95 return -2; 96 return -2;
96 } 97 }
97 log1("Received a packet"); 98 log1("Received a packet");
98 udhcp_dump_packet(packet); 99 udhcp_dump_packet(packet);
99 100
100 if (packet->op == BOOTREQUEST) {
101 vendor = udhcp_get_option(packet, DHCP_VENDOR);
102 if (vendor) {
103#if 0
104 static const char broken_vendors[][8] = {
105 "MSFT 98",
106 ""
107 };
108 int i;
109 for (i = 0; broken_vendors[i][0]; i++) {
110 if (vendor[OPT_LEN - OPT_DATA] == (uint8_t)strlen(broken_vendors[i])
111 && strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - OPT_DATA]) == 0
112 ) {
113 log1("Broken client (%s), forcing broadcast replies",
114 broken_vendors[i]);
115 packet->flags |= htons(BROADCAST_FLAG);
116 }
117 }
118#else
119 if (vendor[OPT_LEN - OPT_DATA] == (uint8_t)(sizeof("MSFT 98")-1)
120 && memcmp(vendor, "MSFT 98", sizeof("MSFT 98")-1) == 0
121 ) {
122 log1("Broken client (%s), forcing broadcast replies", "MSFT 98");
123 packet->flags |= htons(BROADCAST_FLAG);
124 }
125#endif
126 }
127 }
128
129 return bytes; 101 return bytes;
130} 102}
131 103
@@ -210,7 +182,7 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
210 uint32_t source_nip, int source_port, 182 uint32_t source_nip, int source_port,
211 uint32_t dest_nip, int dest_port) 183 uint32_t dest_nip, int dest_port)
212{ 184{
213 struct sockaddr_in client; 185 struct sockaddr_in sa;
214 unsigned padding; 186 unsigned padding;
215 int fd; 187 int fd;
216 int result = -1; 188 int result = -1;
@@ -223,26 +195,25 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
223 } 195 }
224 setsockopt_reuseaddr(fd); 196 setsockopt_reuseaddr(fd);
225 197
226 memset(&client, 0, sizeof(client)); 198 memset(&sa, 0, sizeof(sa));
227 client.sin_family = AF_INET; 199 sa.sin_family = AF_INET;
228 client.sin_port = htons(source_port); 200 sa.sin_port = htons(source_port);
229 client.sin_addr.s_addr = source_nip; 201 sa.sin_addr.s_addr = source_nip;
230 if (bind(fd, (struct sockaddr *)&client, sizeof(client)) == -1) { 202 if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
231 msg = "bind(%s)"; 203 msg = "bind(%s)";
232 goto ret_close; 204 goto ret_close;
233 } 205 }
234 206
235 memset(&client, 0, sizeof(client)); 207 memset(&sa, 0, sizeof(sa));
236 client.sin_family = AF_INET; 208 sa.sin_family = AF_INET;
237 client.sin_port = htons(dest_port); 209 sa.sin_port = htons(dest_port);
238 client.sin_addr.s_addr = dest_nip; 210 sa.sin_addr.s_addr = dest_nip;
239 if (connect(fd, (struct sockaddr *)&client, sizeof(client)) == -1) { 211 if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
240 msg = "connect"; 212 msg = "connect";
241 goto ret_close; 213 goto ret_close;
242 } 214 }
243 215
244 udhcp_dump_packet(dhcp_pkt); 216 udhcp_dump_packet(dhcp_pkt);
245
246 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options); 217 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options);
247 result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding); 218 result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding);
248 msg = "write"; 219 msg = "write";