Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/networking/udhcp/packet.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/networking/udhcp/packet.c
r2725 r3232 7 7 * Licensed under GPLv2, see file LICENSE in this source tree. 8 8 */ 9 #include <netinet/in.h>10 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION11 # include <netpacket/packet.h>12 # include <net/ethernet.h>13 #else14 # include <asm/types.h>15 # include <linux/if_packet.h>16 # include <linux/if_ether.h>17 #endif18 19 9 #include "common.h" 20 10 #include "dhcpd.h" 11 #include <netinet/in.h> 12 #include <netinet/if_ether.h> 13 #include <netpacket/packet.h> 21 14 22 15 void FAST_FUNC udhcp_init_header(struct dhcp_packet *packet, char type) … … 89 82 { 90 83 int bytes; 91 unsigned char *vendor;92 84 93 85 memset(packet, 0, sizeof(*packet)); … … 98 90 } 99 91 100 if (packet->cookie != htonl(DHCP_MAGIC)) { 92 if (bytes < offsetof(struct dhcp_packet, options) 93 || packet->cookie != htonl(DHCP_MAGIC) 94 ) { 101 95 bb_info_msg("Packet with bad magic, ignoring"); 102 96 return -2; … … 105 99 udhcp_dump_packet(packet); 106 100 107 if (packet->op == BOOTREQUEST) {108 vendor = udhcp_get_option(packet, DHCP_VENDOR);109 if (vendor) {110 #if 0111 static const char broken_vendors[][8] = {112 "MSFT 98",113 ""114 };115 int i;116 for (i = 0; broken_vendors[i][0]; i++) {117 if (vendor[OPT_LEN - OPT_DATA] == (uint8_t)strlen(broken_vendors[i])118 && strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - OPT_DATA]) == 0119 ) {120 log1("Broken client (%s), forcing broadcast replies",121 broken_vendors[i]);122 packet->flags |= htons(BROADCAST_FLAG);123 }124 }125 #else126 if (vendor[OPT_LEN - OPT_DATA] == (uint8_t)(sizeof("MSFT 98")-1)127 && memcmp(vendor, "MSFT 98", sizeof("MSFT 98")-1) == 0128 ) {129 log1("Broken client (%s), forcing broadcast replies", "MSFT 98");130 packet->flags |= htons(BROADCAST_FLAG);131 }132 #endif133 }134 }135 136 101 return bytes; 137 }138 139 uint16_t FAST_FUNC udhcp_checksum(void *addr, int count)140 {141 /* Compute Internet Checksum for "count" bytes142 * beginning at location "addr".143 */144 int32_t sum = 0;145 uint16_t *source = (uint16_t *) addr;146 147 while (count > 1) {148 /* This is the inner loop */149 sum += *source++;150 count -= 2;151 }152 153 /* Add left-over byte, if any */154 if (count > 0) {155 /* Make sure that the left-over byte is added correctly both156 * with little and big endian hosts */157 uint16_t tmp = 0;158 *(uint8_t*)&tmp = *(uint8_t*)source;159 sum += tmp;160 }161 /* Fold 32-bit sum to 16 bits */162 while (sum >> 16)163 sum = (sum & 0xffff) + (sum >> 16);164 165 return ~sum;166 102 } 167 103 … … 220 156 /* for UDP checksumming, ip.len is set to UDP packet len */ 221 157 packet.ip.tot_len = packet.udp.len; 222 packet.udp.check = udhcp_checksum(&packet, IP_UDP_DHCP_SIZE - padding); 158 packet.udp.check = inet_cksum((uint16_t *)&packet, 159 IP_UDP_DHCP_SIZE - padding); 223 160 /* but for sending, it is set to IP packet len */ 224 161 packet.ip.tot_len = htons(IP_UDP_DHCP_SIZE - padding); … … 226 163 packet.ip.version = IPVERSION; 227 164 packet.ip.ttl = IPDEFTTL; 228 packet.ip.check = udhcp_checksum(&packet.ip, sizeof(packet.ip));165 packet.ip.check = inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip)); 229 166 230 167 udhcp_dump_packet(dhcp_pkt); … … 246 183 uint32_t dest_nip, int dest_port) 247 184 { 248 struct sockaddr_in client;185 struct sockaddr_in sa; 249 186 unsigned padding; 250 187 int fd; … … 259 196 setsockopt_reuseaddr(fd); 260 197 261 memset(& client, 0, sizeof(client));262 client.sin_family = AF_INET;263 client.sin_port = htons(source_port);264 client.sin_addr.s_addr = source_nip;265 if (bind(fd, (struct sockaddr *)& client, sizeof(client)) == -1) {198 memset(&sa, 0, sizeof(sa)); 199 sa.sin_family = AF_INET; 200 sa.sin_port = htons(source_port); 201 sa.sin_addr.s_addr = source_nip; 202 if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { 266 203 msg = "bind(%s)"; 267 204 goto ret_close; 268 205 } 269 206 270 memset(& client, 0, sizeof(client));271 client.sin_family = AF_INET;272 client.sin_port = htons(dest_port);273 client.sin_addr.s_addr = dest_nip;274 if (connect(fd, (struct sockaddr *)& client, sizeof(client)) == -1) {207 memset(&sa, 0, sizeof(sa)); 208 sa.sin_family = AF_INET; 209 sa.sin_port = htons(dest_port); 210 sa.sin_addr.s_addr = dest_nip; 211 if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { 275 212 msg = "connect"; 276 213 goto ret_close; … … 278 215 279 216 udhcp_dump_packet(dhcp_pkt); 280 281 217 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options); 282 218 result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding);
Note:
See TracChangeset
for help on using the changeset viewer.