diff options
Diffstat (limited to 'networking/udhcp/packet.c')
-rw-r--r-- | networking/udhcp/packet.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 0abe851a4..c3890229f 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c | |||
@@ -39,7 +39,7 @@ void udhcp_init_header(struct dhcpMessage *packet, char type) | |||
39 | 39 | ||
40 | 40 | ||
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 */ |
42 | int udhcp_get_packet(struct dhcpMessage *packet, int fd) | 42 | int udhcp_recv_packet(struct dhcpMessage *packet, int fd) |
43 | { | 43 | { |
44 | #if 0 | 44 | #if 0 |
45 | static const char broken_vendors[][8] = { | 45 | static const char broken_vendors[][8] = { |
@@ -111,7 +111,7 @@ uint16_t udhcp_checksum(void *addr, int count) | |||
111 | /* Make sure that the left-over byte is added correctly both | 111 | /* Make sure that the left-over byte is added correctly both |
112 | * with little and big endian hosts */ | 112 | * with little and big endian hosts */ |
113 | uint16_t tmp = 0; | 113 | uint16_t tmp = 0; |
114 | *(uint8_t *) (&tmp) = * (uint8_t *) source; | 114 | *(uint8_t*)&tmp = *(uint8_t*)source; |
115 | sum += tmp; | 115 | sum += tmp; |
116 | } | 116 | } |
117 | /* Fold 32-bit sum to 16 bits */ | 117 | /* Fold 32-bit sum to 16 bits */ |
@@ -123,7 +123,7 @@ uint16_t udhcp_checksum(void *addr, int count) | |||
123 | 123 | ||
124 | 124 | ||
125 | /* Construct a ip/udp header for a packet, and specify the source and dest hardware address */ | 125 | /* Construct a ip/udp header for a packet, and specify the source and dest hardware address */ |
126 | int udhcp_raw_packet(struct dhcpMessage *payload, | 126 | int udhcp_send_raw_packet(struct dhcpMessage *payload, |
127 | uint32_t source_ip, int source_port, | 127 | uint32_t source_ip, int source_port, |
128 | uint32_t dest_ip, int dest_port, const uint8_t *dest_arp, int ifindex) | 128 | uint32_t dest_ip, int dest_port, const uint8_t *dest_arp, int ifindex) |
129 | { | 129 | { |
@@ -132,6 +132,11 @@ int udhcp_raw_packet(struct dhcpMessage *payload, | |||
132 | struct sockaddr_ll dest; | 132 | struct sockaddr_ll dest; |
133 | struct udp_dhcp_packet packet; | 133 | struct udp_dhcp_packet packet; |
134 | 134 | ||
135 | enum { | ||
136 | IP_UPD_DHCP_SIZE = sizeof(struct udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, | ||
137 | UPD_DHCP_SIZE = IP_UPD_DHCP_SIZE - offsetof(struct udp_dhcp_packet, udp), | ||
138 | }; | ||
139 | |||
135 | fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); | 140 | fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); |
136 | if (fd < 0) { | 141 | if (fd < 0) { |
137 | bb_perror_msg("socket"); | 142 | bb_perror_msg("socket"); |
@@ -140,6 +145,7 @@ int udhcp_raw_packet(struct dhcpMessage *payload, | |||
140 | 145 | ||
141 | memset(&dest, 0, sizeof(dest)); | 146 | memset(&dest, 0, sizeof(dest)); |
142 | memset(&packet, 0, sizeof(packet)); | 147 | memset(&packet, 0, sizeof(packet)); |
148 | packet.data = *payload; /* struct copy */ | ||
143 | 149 | ||
144 | dest.sll_family = AF_PACKET; | 150 | dest.sll_family = AF_PACKET; |
145 | dest.sll_protocol = htons(ETH_P_IP); | 151 | dest.sll_protocol = htons(ETH_P_IP); |
@@ -157,19 +163,19 @@ int udhcp_raw_packet(struct dhcpMessage *payload, | |||
157 | packet.ip.daddr = dest_ip; | 163 | packet.ip.daddr = dest_ip; |
158 | packet.udp.source = htons(source_port); | 164 | packet.udp.source = htons(source_port); |
159 | packet.udp.dest = htons(dest_port); | 165 | packet.udp.dest = htons(dest_port); |
160 | packet.udp.len = htons(sizeof(packet.udp) + sizeof(struct dhcpMessage)); /* cheat on the psuedo-header */ | 166 | /* size, excluding IP header: */ |
167 | packet.udp.len = htons(UPD_DHCP_SIZE); | ||
168 | /* for UDP checksumming, ip.len is set to UDP packet len */ | ||
161 | packet.ip.tot_len = packet.udp.len; | 169 | packet.ip.tot_len = packet.udp.len; |
162 | memcpy(&(packet.data), payload, sizeof(struct dhcpMessage)); | 170 | packet.udp.check = udhcp_checksum(&packet, IP_UPD_DHCP_SIZE); |
163 | packet.udp.check = udhcp_checksum(&packet, sizeof(struct udp_dhcp_packet)); | 171 | /* but for sending, it is set to IP packet len */ |
164 | 172 | packet.ip.tot_len = htons(IP_UPD_DHCP_SIZE); | |
165 | packet.ip.tot_len = htons(sizeof(struct udp_dhcp_packet)); | ||
166 | packet.ip.ihl = sizeof(packet.ip) >> 2; | 173 | packet.ip.ihl = sizeof(packet.ip) >> 2; |
167 | packet.ip.version = IPVERSION; | 174 | packet.ip.version = IPVERSION; |
168 | packet.ip.ttl = IPDEFTTL; | 175 | packet.ip.ttl = IPDEFTTL; |
169 | packet.ip.check = udhcp_checksum(&(packet.ip), sizeof(packet.ip)); | 176 | packet.ip.check = udhcp_checksum(&packet.ip, sizeof(packet.ip)); |
170 | 177 | ||
171 | result = sendto(fd, &packet, sizeof(struct udp_dhcp_packet), 0, | 178 | result = sendto(fd, &packet, IP_UPD_DHCP_SIZE, 0, (struct sockaddr *) &dest, sizeof(dest)); |
172 | (struct sockaddr *) &dest, sizeof(dest)); | ||
173 | if (result <= 0) { | 179 | if (result <= 0) { |
174 | bb_perror_msg("sendto"); | 180 | bb_perror_msg("sendto"); |
175 | } | 181 | } |
@@ -179,13 +185,17 @@ int udhcp_raw_packet(struct dhcpMessage *payload, | |||
179 | 185 | ||
180 | 186 | ||
181 | /* Let the kernel do all the work for packet generation */ | 187 | /* Let the kernel do all the work for packet generation */ |
182 | int udhcp_kernel_packet(struct dhcpMessage *payload, | 188 | int udhcp_send_kernel_packet(struct dhcpMessage *payload, |
183 | uint32_t source_ip, int source_port, | 189 | uint32_t source_ip, int source_port, |
184 | uint32_t dest_ip, int dest_port) | 190 | uint32_t dest_ip, int dest_port) |
185 | { | 191 | { |
186 | int fd, result; | 192 | int fd, result; |
187 | struct sockaddr_in client; | 193 | struct sockaddr_in client; |
188 | 194 | ||
195 | enum { | ||
196 | DHCP_SIZE = sizeof(struct dhcpMessage) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, | ||
197 | }; | ||
198 | |||
189 | fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); | 199 | fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); |
190 | if (fd < 0) | 200 | if (fd < 0) |
191 | return -1; | 201 | return -1; |
@@ -212,7 +222,7 @@ int udhcp_kernel_packet(struct dhcpMessage *payload, | |||
212 | return -1; | 222 | return -1; |
213 | } | 223 | } |
214 | 224 | ||
215 | result = write(fd, payload, sizeof(struct dhcpMessage)); | 225 | result = write(fd, payload, DHCP_SIZE); |
216 | close(fd); | 226 | close(fd); |
217 | return result; | 227 | return result; |
218 | } | 228 | } |