Changeset 44c9ef4 in mainline
- Timestamp:
- 2013-07-18T17:14:32Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0aa70f4
- Parents:
- 34c1bba
- Location:
- uspace/srv/net/inetsrv
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/inetsrv/inet_std.h
r34c1bba r44c9ef4 39 39 40 40 #include <sys/types.h> 41 42 #define IP6_NEXT_FRAGMENT 44 41 43 42 44 /** IPv4 Datagram header (fixed part) */ … … 90 92 }; 91 93 92 /** Bits in ip6_ frag_header_t.offsmf */94 /** Bits in ip6_header_fragment_t.offsmf */ 93 95 enum flags_offsmt_bits { 94 96 /** More fragments */ -
uspace/srv/net/inetsrv/pdu.c
r34c1bba r44c9ef4 114 114 115 115 size_t hdr_size = sizeof(ip_header_t); 116 117 size_t data_offs = ROUND_UP(hdr_size, 4); 118 116 if (hdr_size >= mtu) 117 return EINVAL; 118 119 assert(hdr_size % 4 == 0); 119 120 assert(offs % FRAG_OFFS_UNIT == 0); 120 121 assert(offs / FRAG_OFFS_UNIT < fragoff_limit); … … 122 123 /* Value for the fragment offset field */ 123 124 uint16_t foff = offs / FRAG_OFFS_UNIT; 124 125 if (hdr_size >= mtu)126 return EINVAL;127 125 128 126 /* Amount of space in the PDU available for payload */ … … 170 168 171 169 /* Copy payload */ 172 memcpy((uint8_t *) data + data_offs, packet->data + offs, xfer_size);170 memcpy((uint8_t *) data + hdr_size, packet->data + offs, xfer_size); 173 171 174 172 *rdata = data; … … 194 192 * @param rdata Place to store pointer to allocated data buffer 195 193 * @param rsize Place to store size of allocated data buffer 196 * @param roffs Place to store offset of remaning data194 * @param roffs Place to store offset of remaning data 197 195 * 198 196 */ … … 200 198 size_t offs, size_t mtu, void **rdata, size_t *rsize, size_t *roffs) 201 199 { 200 /* IPv6 mandates a minimal MTU of 1280 bytes */ 201 if (mtu < 1280) 202 return ELIMIT; 203 202 204 /* Upper bound for fragment offset field */ 203 size_t fragoff_limit = 1 << ( FF_FRAGOFF_h - FF_FRAGOFF_l);205 size_t fragoff_limit = 1 << (OF_FRAGOFF_h - OF_FRAGOFF_l); 204 206 205 207 /* Verify that total size of datagram is within reasonable bounds */ … … 207 209 return ELIMIT; 208 210 209 size_t hdr_size = sizeof(ip6_header_t); 210 211 size_t data_offs = ROUND_UP(hdr_size, 4); 212 211 /* Determine whether we need the Fragment extension header */ 212 bool fragment; 213 if (offs == 0) 214 fragment = (packet->size + sizeof(ip6_header_t) > mtu); 215 else 216 fragment = true; 217 218 size_t hdr_size; 219 if (fragment) 220 hdr_size = sizeof(ip6_header_t) + sizeof(ip6_header_fragment_t); 221 else 222 hdr_size = sizeof(ip6_header_t); 223 224 if (hdr_size >= mtu) 225 return EINVAL; 226 227 assert(sizeof(ip6_header_t) % 8 == 0); 228 assert(hdr_size % 8 == 0); 213 229 assert(offs % FRAG_OFFS_UNIT == 0); 214 230 assert(offs / FRAG_OFFS_UNIT < fragoff_limit); 215 231 216 #if 0217 // FIXME TODO fragmentation218 219 232 /* Value for the fragment offset field */ 220 233 uint16_t foff = offs / FRAG_OFFS_UNIT; 221 #endif222 223 if (hdr_size >= mtu)224 return EINVAL;225 234 226 235 /* Amount of space in the PDU available for payload */ … … 237 246 size_t rem_offs = offs + xfer_size; 238 247 239 #if 0240 // FIXME TODO fragmentation241 242 248 /* Flags */ 243 uint16_t flags_foff = 244 (packet->df ? BIT_V(uint16_t, FF_FLAG_DF) : 0) + 245 (rem_offs < packet->size ? BIT_V(uint16_t, FF_FLAG_MF) : 0) + 246 (foff << FF_FRAGOFF_l); 247 #endif 249 uint16_t offsmf = 250 (rem_offs < packet->size ? BIT_V(uint16_t, OF_FLAG_M) : 0) + 251 (foff << OF_FRAGOFF_l); 248 252 249 253 void *data = calloc(size, 1); … … 256 260 hdr6->ver_tc = (6 << (VI_VERSION_l)); 257 261 memset(hdr6->tc_fl, 0, 3); 258 hdr6->payload_len = host2uint16_t_be(packet->size);259 hdr6->next = packet->proto;260 262 hdr6->hop_limit = packet->ttl; 261 263 … … 263 265 host2addr128_t_be(dest, hdr6->dest_addr); 264 266 267 /* Optionally encode Fragment extension header fields */ 268 if (fragment) { 269 assert(offsmf != 0); 270 271 hdr6->payload_len = host2uint16_t_be(packet->size + 272 sizeof(ip6_header_fragment_t)); 273 hdr6->next = IP6_NEXT_FRAGMENT; 274 275 ip6_header_fragment_t *hdr6f = (ip6_header_fragment_t *) 276 (hdr6 + 1); 277 278 hdr6f->next = packet->proto; 279 hdr6f->reserved = 0; 280 hdr6f->offsmf = host2uint16_t_be(offsmf); 281 hdr6f->id = host2uint32_t_be(packet->ident); 282 } else { 283 assert(offsmf == 0); 284 285 hdr6->payload_len = host2uint16_t_be(packet->size); 286 hdr6->next = packet->proto; 287 } 288 265 289 /* Copy payload */ 266 memcpy((uint8_t *) data + data_offs, packet->data + offs, xfer_size);290 memcpy((uint8_t *) data + hdr_size, packet->data + offs, xfer_size); 267 291 268 292 *rdata = data; … … 378 402 size_t payload_len = uint16_t_be2host(hdr6->payload_len); 379 403 if (payload_len + sizeof(ip6_header_t) > size) { 380 log_msg(LOG_DEFAULT, LVL_DEBUG, " TotalLength = %zu > PDU size = %zu",404 log_msg(LOG_DEFAULT, LVL_DEBUG, "Payload Length = %zu > PDU size = %zu", 381 405 payload_len + sizeof(ip6_header_t), size); 382 406 return EINVAL; 383 407 } 384 408 385 #if 0 386 // FIXME TODO fragmentation 387 388 uint16_t ident = uint16_t_be2host(hdr->id); 389 uint16_t flags_foff = uint16_t_be2host(hdr->flags_foff); 390 uint16_t foff = BIT_RANGE_EXTRACT(uint16_t, FF_FRAGOFF_h, FF_FRAGOFF_l, 391 flags_foff); 392 #endif 393 394 /* XXX Checksum */ 409 uint32_t ident; 410 uint16_t offsmf; 411 uint16_t foff; 412 uint16_t next; 413 size_t data_offs = sizeof(ip6_header_t); 414 415 /* Fragment extension header */ 416 if (hdr6->next == IP6_NEXT_FRAGMENT) { 417 ip6_header_fragment_t *hdr6f = (ip6_header_fragment_t *) 418 (hdr6 + 1); 419 420 ident = uint32_t_be2host(hdr6f->id); 421 offsmf = uint16_t_be2host(hdr6f->offsmf); 422 foff = BIT_RANGE_EXTRACT(uint16_t, OF_FRAGOFF_h, OF_FRAGOFF_l, 423 offsmf); 424 next = hdr6f->next; 425 data_offs += sizeof(ip6_header_fragment_t); 426 payload_len -= sizeof(ip6_header_fragment_t); 427 } else { 428 ident = 0; 429 offsmf = 0; 430 foff = 0; 431 next = hdr6->next; 432 } 395 433 396 434 addr128_t src; … … 404 442 405 443 packet->tos = 0; 406 packet->proto = hdr6->next;444 packet->proto = next; 407 445 packet->ttl = hdr6->hop_limit; 408 409 #if 0410 // FIXME TODO fragmentation411 412 446 packet->ident = ident; 413 packet->df = (flags_foff & BIT_V(uint16_t, FF_FLAG_DF)) != 0; 414 packet->mf = (flags_foff & BIT_V(uint16_t, FF_FLAG_MF)) != 0; 447 448 packet->df = 1; 449 packet->mf = (offsmf & BIT_V(uint16_t, OF_FLAG_M)) != 0; 415 450 packet->offs = foff * FRAG_OFFS_UNIT; 416 417 /* XXX IP options */418 size_t data_offs = sizeof(uint32_t) *419 BIT_RANGE_EXTRACT(uint8_t, VI_IHL_h, VI_IHL_l, hdr->ver_ihl);420 #endif421 422 packet->ident = 0;423 packet->df = 0;424 packet->mf = 0;425 packet->offs = 0;426 451 427 452 packet->size = payload_len; … … 432 457 } 433 458 434 memcpy(packet->data, (uint8_t *) data + sizeof(ip6_header_t), packet->size);459 memcpy(packet->data, (uint8_t *) data + data_offs, packet->size); 435 460 436 461 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.