aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-12-24 17:32:22 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-12-24 17:32:22 +0000
commit8e5b6f58a27d840cabf491634e956407d147ddb6 (patch)
tree86c65a2ce32290b19212c6d95600ae3a7eb046c0
parent299c5c379e006ce2c3a39c42a323f297e4a4fb18 (diff)
downloadbusybox-w32-8e5b6f58a27d840cabf491634e956407d147ddb6.tar.gz
busybox-w32-8e5b6f58a27d840cabf491634e956407d147ddb6.tar.bz2
busybox-w32-8e5b6f58a27d840cabf491634e956407d147ddb6.zip
Makefile: change version to 1.10.0.svn
udhcpc: make UDP packet sending the same as raw sending in regards to error messages. Minor code size shrink. Total size grows due to added messages: text data bss dec hex filename 770312 683 7244 778239 bdfff busybox_old 770327 683 7244 778254 be00e busybox_unstripped
-rw-r--r--Makefile4
-rw-r--r--networking/udhcp/clientpacket.c25
-rw-r--r--networking/udhcp/dhcpc.c2
-rw-r--r--networking/udhcp/packet.c73
4 files changed, 57 insertions, 47 deletions
diff --git a/Makefile b/Makefile
index 618b51898..eabc21b2c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
1VERSION = 1 1VERSION = 1
2PATCHLEVEL = 9 2PATCHLEVEL = 10
3SUBLEVEL = 0 3SUBLEVEL = 0
4EXTRAVERSION = 4EXTRAVERSION = .svn
5NAME = Unnamed 5NAME = Unnamed
6 6
7# *DOCUMENTATION* 7# *DOCUMENTATION*
diff --git a/networking/udhcp/clientpacket.c b/networking/udhcp/clientpacket.c
index 03473109f..b8190ba43 100644
--- a/networking/udhcp/clientpacket.c
+++ b/networking/udhcp/clientpacket.c
@@ -167,39 +167,40 @@ int send_release(uint32_t server, uint32_t ciaddr)
167} 167}
168 168
169 169
170/* return -1 on errors that are fatal for the socket, -2 for those that aren't */ 170/* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */
171int get_raw_packet(struct dhcpMessage *payload, int fd) 171int get_raw_packet(struct dhcpMessage *payload, int fd)
172{ 172{
173 int bytes; 173 int bytes;
174 struct udp_dhcp_packet packet; 174 struct udp_dhcp_packet packet;
175 uint16_t check; 175 uint16_t check;
176 176
177 memset(&packet, 0, sizeof(struct udp_dhcp_packet)); 177 memset(&packet, 0, sizeof(packet));
178 bytes = read(fd, &packet, sizeof(struct udp_dhcp_packet)); 178 bytes = safe_read(fd, &packet, sizeof(packet));
179 if (bytes < 0) { 179 if (bytes < 0) {
180 DEBUG("Cannot read on raw listening socket - ignoring"); 180 DEBUG("Cannot read on raw listening socket - ignoring");
181 sleep(1); /* possible down interface, looping condition */ 181 sleep(1); /* possible down interface, looping condition */
182 return -1; 182 return bytes; /* returns -1 */
183 } 183 }
184 184
185 if (bytes < (int) (sizeof(struct iphdr) + sizeof(struct udphdr))) { 185 if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) {
186 DEBUG("Message too short, ignoring"); 186 DEBUG("Packet is too short, ignoring");
187 return -2; 187 return -2;
188 } 188 }
189 189
190 if (bytes < ntohs(packet.ip.tot_len)) { 190 if (bytes < ntohs(packet.ip.tot_len)) {
191 DEBUG("Truncated packet"); 191 /* packet is bigger than sizeof(packet), we did partial read */
192 DEBUG("Oversized packet, ignoring");
192 return -2; 193 return -2;
193 } 194 }
194 195
195 /* ignore any extra garbage bytes */ 196 /* ignore any extra garbage bytes */
196 bytes = ntohs(packet.ip.tot_len); 197 bytes = ntohs(packet.ip.tot_len);
197 198
198 /* Make sure its the right packet for us, and that it passes sanity checks */ 199 /* make sure its the right packet for us, and that it passes sanity checks */
199 if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION 200 if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION
200 || packet.ip.ihl != (sizeof(packet.ip) >> 2) 201 || packet.ip.ihl != (sizeof(packet.ip) >> 2)
201 || packet.udp.dest != htons(CLIENT_PORT) 202 || packet.udp.dest != htons(CLIENT_PORT)
202 || bytes > (int) sizeof(struct udp_dhcp_packet) 203 /* || bytes > (int) sizeof(packet) - can't happen */
203 || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip)) 204 || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip))
204 ) { 205 ) {
205 DEBUG("Unrelated/bogus packet"); 206 DEBUG("Unrelated/bogus packet");
@@ -211,12 +212,12 @@ int get_raw_packet(struct dhcpMessage *payload, int fd)
211 packet.ip.check = 0; 212 packet.ip.check = 0;
212 if (check != udhcp_checksum(&packet.ip, sizeof(packet.ip))) { 213 if (check != udhcp_checksum(&packet.ip, sizeof(packet.ip))) {
213 DEBUG("Bad IP header checksum, ignoring"); 214 DEBUG("Bad IP header checksum, ignoring");
214 return -1; 215 return -2;
215 } 216 }
216 217
217 /* verify UDP checksum. IP header has to be modified for this */ 218 /* verify UDP checksum. IP header has to be modified for this */
218 memset(&packet.ip, 0, offsetof(struct iphdr, protocol)); 219 memset(&packet.ip, 0, offsetof(struct iphdr, protocol));
219 /* fields which are not memset: protocol, check, saddr, daddr */ 220 /* ip.xx fields which are not memset: protocol, check, saddr, daddr */
220 packet.ip.tot_len = packet.udp.len; /* yes, this is needed */ 221 packet.ip.tot_len = packet.udp.len; /* yes, this is needed */
221 check = packet.udp.check; 222 check = packet.udp.check;
222 packet.udp.check = 0; 223 packet.udp.check = 0;
@@ -228,7 +229,7 @@ int get_raw_packet(struct dhcpMessage *payload, int fd)
228 memcpy(payload, &packet.data, bytes - (sizeof(packet.ip) + sizeof(packet.udp))); 229 memcpy(payload, &packet.data, bytes - (sizeof(packet.ip) + sizeof(packet.udp)));
229 230
230 if (payload->cookie != htonl(DHCP_MAGIC)) { 231 if (payload->cookie != htonl(DHCP_MAGIC)) {
231 bb_error_msg("received bogus message (bad magic) - ignoring"); 232 bb_error_msg("received bogus message (bad magic), ignoring");
232 return -2; 233 return -2;
233 } 234 }
234 DEBUG("Got valid DHCP packet"); 235 DEBUG("Got valid DHCP packet");
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 3de389f7b..d76a62c5a 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -454,7 +454,7 @@ int udhcpc_main(int argc, char **argv)
454 len = udhcp_recv_packet(&packet, sockfd); 454 len = udhcp_recv_packet(&packet, sockfd);
455 else len = get_raw_packet(&packet, sockfd); 455 else len = get_raw_packet(&packet, sockfd);
456 456
457 if (len == -1 && errno != EINTR) { 457 if (len == -1) { /* error is severe, reopen socket */
458 DEBUG("error on read, %s, reopening socket", strerror(errno)); 458 DEBUG("error on read, %s, reopening socket", strerror(errno));
459 change_listen_mode(listen_mode); /* just close and reopen */ 459 change_listen_mode(listen_mode); /* just close and reopen */
460 } 460 }
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index 22c18deaf..443fea6dd 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -41,20 +41,14 @@ void udhcp_init_header(struct dhcpMessage *packet, char type)
41/* read a packet from socket fd, return -1 on read error, -2 on packet error */ 41/* read a packet from socket fd, return -1 on read error, -2 on packet error */
42int udhcp_recv_packet(struct dhcpMessage *packet, int fd) 42int udhcp_recv_packet(struct dhcpMessage *packet, int fd)
43{ 43{
44#if 0
45 static const char broken_vendors[][8] = {
46 "MSFT 98",
47 ""
48 };
49#endif
50 int bytes; 44 int bytes;
51 unsigned char *vendor; 45 unsigned char *vendor;
52 46
53 memset(packet, 0, sizeof(*packet)); 47 memset(packet, 0, sizeof(*packet));
54 bytes = read(fd, packet, sizeof(*packet)); 48 bytes = safe_read(fd, packet, sizeof(*packet));
55 if (bytes < 0) { 49 if (bytes < 0) {
56 DEBUG("cannot read on listening socket, ignoring"); 50 DEBUG("cannot read on listening socket, ignoring");
57 return -1; 51 return bytes; /* returns -1 */
58 } 52 }
59 53
60 if (packet->cookie != htonl(DHCP_MAGIC)) { 54 if (packet->cookie != htonl(DHCP_MAGIC)) {
@@ -67,6 +61,10 @@ int udhcp_recv_packet(struct dhcpMessage *packet, int fd)
67 vendor = get_option(packet, DHCP_VENDOR); 61 vendor = get_option(packet, DHCP_VENDOR);
68 if (vendor) { 62 if (vendor) {
69#if 0 63#if 0
64 static const char broken_vendors[][8] = {
65 "MSFT 98",
66 ""
67 };
70 int i; 68 int i;
71 for (i = 0; broken_vendors[i][0]; i++) { 69 for (i = 0; broken_vendors[i][0]; i++) {
72 if (vendor[OPT_LEN - 2] == (uint8_t)strlen(broken_vendors[i]) 70 if (vendor[OPT_LEN - 2] == (uint8_t)strlen(broken_vendors[i])
@@ -127,10 +125,11 @@ int udhcp_send_raw_packet(struct dhcpMessage *payload,
127 uint32_t source_ip, int source_port, 125 uint32_t source_ip, int source_port,
128 uint32_t dest_ip, int dest_port, const uint8_t *dest_arp, int ifindex) 126 uint32_t dest_ip, int dest_port, const uint8_t *dest_arp, int ifindex)
129{ 127{
130 int fd;
131 int result;
132 struct sockaddr_ll dest; 128 struct sockaddr_ll dest;
133 struct udp_dhcp_packet packet; 129 struct udp_dhcp_packet packet;
130 int fd;
131 int result = -1;
132 const char *msg;
134 133
135 enum { 134 enum {
136 IP_UPD_DHCP_SIZE = sizeof(struct udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, 135 IP_UPD_DHCP_SIZE = sizeof(struct udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS,
@@ -139,8 +138,8 @@ int udhcp_send_raw_packet(struct dhcpMessage *payload,
139 138
140 fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); 139 fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
141 if (fd < 0) { 140 if (fd < 0) {
142 bb_perror_msg("socket"); 141 msg = "socket(%s)";
143 return -1; 142 goto ret_msg;
144 } 143 }
145 144
146 memset(&dest, 0, sizeof(dest)); 145 memset(&dest, 0, sizeof(dest));
@@ -152,10 +151,9 @@ int udhcp_send_raw_packet(struct dhcpMessage *payload,
152 dest.sll_ifindex = ifindex; 151 dest.sll_ifindex = ifindex;
153 dest.sll_halen = 6; 152 dest.sll_halen = 6;
154 memcpy(dest.sll_addr, dest_arp, 6); 153 memcpy(dest.sll_addr, dest_arp, 6);
155 if (bind(fd, (struct sockaddr *)&dest, sizeof(struct sockaddr_ll)) < 0) { 154 if (bind(fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) {
156 bb_perror_msg("bind"); 155 msg = "bind(%s)";
157 close(fd); 156 goto ret_close;
158 return -1;
159 } 157 }
160 158
161 packet.ip.protocol = IPPROTO_UDP; 159 packet.ip.protocol = IPPROTO_UDP;
@@ -179,11 +177,15 @@ int udhcp_send_raw_packet(struct dhcpMessage *payload,
179 * If you need to change this: last byte of the packet is 177 * If you need to change this: last byte of the packet is
180 * packet.data.options[end_option(packet.data.options)] 178 * packet.data.options[end_option(packet.data.options)]
181 */ 179 */
182 result = sendto(fd, &packet, IP_UPD_DHCP_SIZE, 0, (struct sockaddr *) &dest, sizeof(dest)); 180 result = sendto(fd, &packet, IP_UPD_DHCP_SIZE, 0,
183 if (result <= 0) { 181 (struct sockaddr *) &dest, sizeof(dest));
184 bb_perror_msg("sendto"); 182 msg = "sendto";
185 } 183 ret_close:
186 close(fd); 184 close(fd);
185 if (result < 0) {
186 ret_msg:
187 bb_perror_msg(msg, "PACKET");
188 }
187 return result; 189 return result;
188} 190}
189 191
@@ -193,41 +195,48 @@ int udhcp_send_kernel_packet(struct dhcpMessage *payload,
193 uint32_t source_ip, int source_port, 195 uint32_t source_ip, int source_port,
194 uint32_t dest_ip, int dest_port) 196 uint32_t dest_ip, int dest_port)
195{ 197{
196 int fd, result;
197 struct sockaddr_in client; 198 struct sockaddr_in client;
199 int fd;
200 int result = -1;
201 const char *msg;
198 202
199 enum { 203 enum {
200 DHCP_SIZE = sizeof(struct dhcpMessage) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, 204 DHCP_SIZE = sizeof(struct dhcpMessage) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS,
201 }; 205 };
202 206
203 fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 207 fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
204 if (fd < 0) 208 if (fd < 0) {
205 return -1; 209 msg = "socket(%s)";
206 210 goto ret_msg;
211 }
207 setsockopt_reuseaddr(fd); 212 setsockopt_reuseaddr(fd);
208 213
209 memset(&client, 0, sizeof(client)); 214 memset(&client, 0, sizeof(client));
210 client.sin_family = AF_INET; 215 client.sin_family = AF_INET;
211 client.sin_port = htons(source_port); 216 client.sin_port = htons(source_port);
212 client.sin_addr.s_addr = source_ip; 217 client.sin_addr.s_addr = source_ip;
213
214 if (bind(fd, (struct sockaddr *)&client, sizeof(client)) == -1) { 218 if (bind(fd, (struct sockaddr *)&client, sizeof(client)) == -1) {
215 close(fd); 219 msg = "bind(%s)";
216 return -1; 220 goto ret_close;
217 } 221 }
218 222
219 memset(&client, 0, sizeof(client)); 223 memset(&client, 0, sizeof(client));
220 client.sin_family = AF_INET; 224 client.sin_family = AF_INET;
221 client.sin_port = htons(dest_port); 225 client.sin_port = htons(dest_port);
222 client.sin_addr.s_addr = dest_ip; 226 client.sin_addr.s_addr = dest_ip;
223 227 if (connect(fd, (struct sockaddr *)&client, sizeof(client)) == -1) {
224 if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) { 228 msg = "connect";
225 close(fd); 229 goto ret_close;
226 return -1;
227 } 230 }
228 231
229 /* Currently we send full-sized DHCP packets (see above) */ 232 /* Currently we send full-sized DHCP packets (see above) */
230 result = write(fd, payload, DHCP_SIZE); 233 result = safe_write(fd, payload, DHCP_SIZE);
234 msg = "write";
235 ret_close:
231 close(fd); 236 close(fd);
237 if (result < 0) {
238 ret_msg:
239 bb_perror_msg(msg, "UDP");
240 }
232 return result; 241 return result;
233} 242}