Changeset a35b458 in mainline for uspace/srv/net/inetsrv
- Timestamp:
- 2018-03-02T20:10:49Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- uspace/srv/net/inetsrv
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/inetsrv/addrobj.c
r3061bc1 ra35b458 113 113 { 114 114 fibril_mutex_lock(&addr_list_lock); 115 115 116 116 list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) { 117 117 switch (find) { … … 134 134 } 135 135 } 136 136 137 137 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: Not found"); 138 138 fibril_mutex_unlock(&addr_list_lock); 139 139 140 140 return NULL; 141 141 } -
uspace/srv/net/inetsrv/icmpv6.c
r3061bc1 ra35b458 50 50 { 51 51 log_msg(LOG_DEFAULT, LVL_DEBUG, "icmpv6_recv_echo_request()"); 52 52 53 53 if (dgram->size < sizeof(icmpv6_message_t)) 54 54 return EINVAL; 55 55 56 56 icmpv6_message_t *request = (icmpv6_message_t *) dgram->data; 57 57 size_t size = dgram->size; 58 58 59 59 addr128_t src_v6; 60 60 ip_ver_t src_ver = inet_addr_get(&dgram->src, NULL, &src_v6); 61 61 62 62 addr128_t dest_v6; 63 63 ip_ver_t dest_ver = inet_addr_get(&dgram->dest, NULL, &dest_v6); 64 64 65 65 if ((src_ver != dest_ver) || (src_ver != ip_v6)) 66 66 return EINVAL; 67 67 68 68 icmpv6_message_t *reply = calloc(1, size); 69 69 if (reply == NULL) 70 70 return ENOMEM; 71 71 72 72 memcpy(reply, request, size); 73 73 74 74 reply->type = ICMPV6_ECHO_REPLY; 75 75 reply->code = 0; 76 76 reply->checksum = 0; 77 77 78 78 inet_dgram_t rdgram; 79 79 80 80 inet_get_srcaddr(&dgram->src, 0, &rdgram.src); 81 81 rdgram.dest = dgram->src; … … 84 84 rdgram.data = reply; 85 85 rdgram.size = size; 86 86 87 87 icmpv6_phdr_t phdr; 88 88 89 89 host2addr128_t_be(dest_v6, phdr.src_addr); 90 90 host2addr128_t_be(src_v6, phdr.dest_addr); … … 92 92 memset(phdr.zeroes, 0, 3); 93 93 phdr.next = IP_PROTO_ICMPV6; 94 94 95 95 uint16_t cs_phdr = 96 96 inet_checksum_calc(INET_CHECKSUM_INIT, &phdr, 97 97 sizeof(icmpv6_phdr_t)); 98 98 99 99 uint16_t cs_all = inet_checksum_calc(cs_phdr, reply, size); 100 100 101 101 reply->checksum = host2uint16_t_be(cs_all); 102 102 103 103 errno_t rc = inet_route_packet(&rdgram, IP_PROTO_ICMPV6, 104 104 INET6_HOP_LIMIT_MAX, 0); 105 105 106 106 free(reply); 107 107 108 108 return rc; 109 109 } … … 112 112 { 113 113 log_msg(LOG_DEFAULT, LVL_DEBUG, "icmpv6_recv_echo_reply()"); 114 114 115 115 if (dgram->size < sizeof(icmpv6_message_t)) 116 116 return EINVAL; 117 117 118 118 inetping_sdu_t sdu; 119 119 120 120 sdu.src = dgram->src; 121 121 sdu.dest = dgram->dest; 122 122 123 123 icmpv6_message_t *reply = (icmpv6_message_t *) dgram->data; 124 124 125 125 sdu.seq_no = uint16_t_be2host(reply->un.echo.seq_no); 126 126 sdu.data = reply + sizeof(icmpv6_message_t); 127 127 sdu.size = dgram->size - sizeof(icmpv6_message_t); 128 128 129 129 uint16_t ident = uint16_t_be2host(reply->un.echo.ident); 130 130 131 131 return inetping_recv(ident, &sdu); 132 132 } … … 135 135 { 136 136 log_msg(LOG_DEFAULT, LVL_DEBUG, "icmpv6_recv()"); 137 137 138 138 if (dgram->size < 1) 139 139 return EINVAL; 140 140 141 141 uint8_t type = *(uint8_t *) dgram->data; 142 142 143 143 switch (type) { 144 144 case ICMPV6_ECHO_REQUEST: … … 153 153 break; 154 154 } 155 155 156 156 return EINVAL; 157 157 } … … 163 163 if (rdata == NULL) 164 164 return ENOMEM; 165 165 166 166 icmpv6_message_t *request = (icmpv6_message_t *) rdata; 167 167 168 168 request->type = ICMPV6_ECHO_REQUEST; 169 169 request->code = 0; … … 171 171 request->un.echo.ident = host2uint16_t_be(ident); 172 172 request->un.echo.seq_no = host2uint16_t_be(sdu->seq_no); 173 173 174 174 memcpy(rdata + sizeof(icmpv6_message_t), sdu->data, sdu->size); 175 175 176 176 inet_dgram_t dgram; 177 177 178 178 dgram.src = sdu->src; 179 179 dgram.dest = sdu->dest; … … 182 182 dgram.data = rdata; 183 183 dgram.size = rsize; 184 184 185 185 icmpv6_phdr_t phdr; 186 186 187 187 assert(sdu->src.version == ip_v6); 188 188 assert(sdu->dest.version == ip_v6); 189 189 190 190 host2addr128_t_be(sdu->src.addr6, phdr.src_addr); 191 191 host2addr128_t_be(sdu->dest.addr6, phdr.dest_addr); … … 193 193 memset(phdr.zeroes, 0, 3); 194 194 phdr.next = IP_PROTO_ICMPV6; 195 195 196 196 uint16_t cs_phdr = 197 197 inet_checksum_calc(INET_CHECKSUM_INIT, &phdr, 198 198 sizeof(icmpv6_phdr_t)); 199 199 200 200 uint16_t cs_all = inet_checksum_calc(cs_phdr, rdata, rsize); 201 201 202 202 request->checksum = host2uint16_t_be(cs_all); 203 203 204 204 errno_t rc = inet_route_packet(&dgram, IP_PROTO_ICMPV6, 205 205 INET6_HOP_LIMIT_MAX, 0); 206 206 207 207 free(rdata); 208 208 209 209 return rc; 210 210 } -
uspace/srv/net/inetsrv/inet_link.c
r3061bc1 ra35b458 154 154 if (ilink->svc_name != NULL) 155 155 free(ilink->svc_name); 156 156 157 157 free(ilink); 158 158 } … … 197 197 goto error; 198 198 } 199 199 200 200 /* 201 201 * Get the MAC address of the link. If the link has a MAC … … 221 221 222 222 inet_addrobj_t *addr = NULL; 223 223 224 224 /* XXX FIXME Cannot rely on loopback being the first IP link service!! */ 225 225 if (first_link) { 226 226 addr = inet_addrobj_new(); 227 227 228 228 inet_naddr(&addr->naddr, 127, 0, 0, 1, 24); 229 229 first_link = false; 230 230 } 231 231 232 232 if (addr != NULL) { 233 233 addr->ilink = ilink; 234 234 addr->name = str_dup("v4a"); 235 235 236 236 rc = inet_addrobj_add(addr); 237 237 if (rc == EOK) { … … 249 249 } 250 250 } 251 251 252 252 inet_addrobj_t *addr6 = NULL; 253 253 254 254 if (first_link6) { 255 255 addr6 = inet_addrobj_new(); 256 256 257 257 inet_naddr6(&addr6->naddr, 0, 0, 0, 0, 0, 0, 0, 1, 128); 258 258 first_link6 = false; 259 259 } else if (ilink->mac_valid) { 260 260 addr6 = inet_addrobj_new(); 261 261 262 262 addr128_t link_local; 263 263 inet_link_local_node_ip(ilink->mac, link_local); 264 264 265 265 inet_naddr_set6(link_local, 64, &addr6->naddr); 266 266 } 267 267 268 268 if (addr6 != NULL) { 269 269 addr6->ilink = ilink; 270 270 addr6->name = str_dup("v6a"); 271 271 272 272 rc = inet_addrobj_add(addr6); 273 273 if (rc == EOK) { … … 285 285 } 286 286 } 287 287 288 288 log_msg(LOG_DEFAULT, LVL_DEBUG, "Configured link '%s'.", ilink->svc_name); 289 289 return EOK; 290 290 291 291 error: 292 292 if (ilink->iplink != NULL) 293 293 iplink_close(ilink->iplink); 294 294 295 295 inet_link_delete(ilink); 296 296 return rc; … … 319 319 if (src_ver != ip_v4) 320 320 return EINVAL; 321 321 322 322 addr32_t dest_v4; 323 323 ip_ver_t dest_ver = inet_addr_get(&dgram->dest, &dest_v4, NULL); 324 324 if (dest_ver != ip_v4) 325 325 return EINVAL; 326 326 327 327 /* 328 328 * Fill packet structure. Fragmentation is performed by 329 329 * inet_pdu_encode(). 330 330 */ 331 331 332 332 iplink_sdu_t sdu; 333 333 334 334 sdu.src = lsrc; 335 335 sdu.dest = ldest; 336 336 337 337 inet_packet_t packet; 338 338 339 339 packet.src = dgram->src; 340 340 packet.dest = dgram->dest; … … 342 342 packet.proto = proto; 343 343 packet.ttl = ttl; 344 344 345 345 /* Allocate identifier */ 346 346 fibril_mutex_lock(&ip_ident_lock); 347 347 packet.ident = ++ip_ident; 348 348 fibril_mutex_unlock(&ip_ident_lock); 349 349 350 350 packet.df = df; 351 351 packet.data = dgram->data; 352 352 packet.size = dgram->size; 353 353 354 354 errno_t rc; 355 355 size_t offs = 0; 356 356 357 357 do { 358 358 /* Encode one fragment */ 359 359 360 360 size_t roffs; 361 361 rc = inet_pdu_encode(&packet, src_v4, dest_v4, offs, ilink->def_mtu, … … 363 363 if (rc != EOK) 364 364 return rc; 365 365 366 366 /* Send the PDU */ 367 367 rc = iplink_send(ilink->iplink, &sdu); 368 368 369 369 free(sdu.data); 370 370 offs = roffs; 371 371 } while (offs < packet.size); 372 372 373 373 return rc; 374 374 } … … 394 394 if (src_ver != ip_v6) 395 395 return EINVAL; 396 396 397 397 addr128_t dest_v6; 398 398 ip_ver_t dest_ver = inet_addr_get(&dgram->dest, NULL, &dest_v6); 399 399 if (dest_ver != ip_v6) 400 400 return EINVAL; 401 401 402 402 iplink_sdu6_t sdu6; 403 403 addr48(ldest, sdu6.dest); 404 404 405 405 /* 406 406 * Fill packet structure. Fragmentation is performed by 407 407 * inet_pdu_encode6(). 408 408 */ 409 409 410 410 inet_packet_t packet; 411 411 412 412 packet.src = dgram->src; 413 413 packet.dest = dgram->dest; … … 415 415 packet.proto = proto; 416 416 packet.ttl = ttl; 417 417 418 418 /* Allocate identifier */ 419 419 fibril_mutex_lock(&ip_ident_lock); 420 420 packet.ident = ++ip_ident; 421 421 fibril_mutex_unlock(&ip_ident_lock); 422 422 423 423 packet.df = df; 424 424 packet.data = dgram->data; 425 425 packet.size = dgram->size; 426 426 427 427 errno_t rc; 428 428 size_t offs = 0; 429 429 430 430 do { 431 431 /* Encode one fragment */ 432 432 433 433 size_t roffs; 434 434 rc = inet_pdu_encode6(&packet, src_v6, dest_v6, offs, ilink->def_mtu, … … 436 436 if (rc != EOK) 437 437 return rc; 438 438 439 439 /* Send the PDU */ 440 440 rc = iplink_send6(ilink->iplink, &sdu6); 441 441 442 442 free(sdu6.data); 443 443 offs = roffs; 444 444 } while (offs < packet.size); 445 445 446 446 return rc; 447 447 } -
uspace/srv/net/inetsrv/inetcfg.c
r3061bc1 ra35b458 257 257 { 258 258 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_create_static_srv()"); 259 259 260 260 sysarg_t link_id = IPC_GET_ARG1(*icall); 261 261 262 262 ipc_callid_t callid; 263 263 size_t size; … … 267 267 return; 268 268 } 269 269 270 270 if (size != sizeof(inet_naddr_t)) { 271 271 async_answer_0(callid, EINVAL); … … 273 273 return; 274 274 } 275 275 276 276 inet_naddr_t naddr; 277 277 errno_t rc = async_data_write_finalize(callid, &naddr, size); … … 281 281 return; 282 282 } 283 283 284 284 char *name; 285 285 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN, … … 289 289 return; 290 290 } 291 291 292 292 sysarg_t addr_id = 0; 293 293 rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id); … … 312 312 { 313 313 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_srv()"); 314 314 315 315 sysarg_t addr_id = IPC_GET_ARG1(*icall); 316 316 317 317 inet_addr_info_t ainfo; 318 318 319 319 inet_naddr_any(&ainfo.naddr); 320 320 ainfo.ilink = 0; 321 321 ainfo.name = NULL; 322 322 323 323 errno_t rc = inetcfg_addr_get(addr_id, &ainfo); 324 324 if (rc != EOK) { … … 326 326 return; 327 327 } 328 328 329 329 ipc_callid_t callid; 330 330 size_t size; … … 334 334 return; 335 335 } 336 336 337 337 if (size != sizeof(inet_naddr_t)) { 338 338 async_answer_0(callid, EINVAL); … … 340 340 return; 341 341 } 342 342 343 343 rc = async_data_read_finalize(callid, &ainfo.naddr, size); 344 344 if (rc != EOK) { … … 347 347 return; 348 348 } 349 349 350 350 if (!async_data_read_receive(&callid, &size)) { 351 351 async_answer_0(callid, EREFUSED); … … 353 353 return; 354 354 } 355 355 356 356 rc = async_data_read_finalize(callid, ainfo.name, 357 357 min(size, str_size(ainfo.name))); 358 358 free(ainfo.name); 359 360 if (rc != EOK) { 361 async_answer_0(callid, rc); 362 async_answer_0(iid, rc); 363 return; 364 } 365 359 360 if (rc != EOK) { 361 async_answer_0(callid, rc); 362 async_answer_0(iid, rc); 363 return; 364 } 365 366 366 async_answer_1(iid, rc, ainfo.ilink); 367 367 } … … 584 584 return; 585 585 } 586 586 587 587 if (size != sizeof(inet_naddr_t)) { 588 588 async_answer_0(callid, EINVAL); … … 590 590 return; 591 591 } 592 592 593 593 inet_naddr_t dest; 594 594 errno_t rc = async_data_write_finalize(callid, &dest, size); … … 598 598 return; 599 599 } 600 600 601 601 if (!async_data_write_receive(&callid, &size)) { 602 602 async_answer_0(callid, EINVAL); … … 604 604 return; 605 605 } 606 606 607 607 if (size != sizeof(inet_addr_t)) { 608 608 async_answer_0(callid, EINVAL); … … 610 610 return; 611 611 } 612 612 613 613 inet_addr_t router; 614 614 rc = async_data_write_finalize(callid, &router, size); … … 618 618 return; 619 619 } 620 620 621 621 char *name; 622 622 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN, … … 626 626 return; 627 627 } 628 628 629 629 sysarg_t sroute_id = 0; 630 630 rc = inetcfg_sroute_create(name, &dest, &router, &sroute_id); … … 649 649 { 650 650 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_srv()"); 651 651 652 652 sysarg_t sroute_id = IPC_GET_ARG1(*icall); 653 653 654 654 inet_sroute_info_t srinfo; 655 655 656 656 inet_naddr_any(&srinfo.dest); 657 657 inet_addr_any(&srinfo.router); 658 658 srinfo.name = NULL; 659 659 660 660 errno_t rc = inetcfg_sroute_get(sroute_id, &srinfo); 661 661 if (rc != EOK) { … … 663 663 return; 664 664 } 665 665 666 666 ipc_callid_t callid; 667 667 size_t size; … … 671 671 return; 672 672 } 673 673 674 674 if (size != sizeof(inet_naddr_t)) { 675 675 async_answer_0(callid, EINVAL); … … 677 677 return; 678 678 } 679 679 680 680 rc = async_data_read_finalize(callid, &srinfo.dest, size); 681 681 if (rc != EOK) { … … 684 684 return; 685 685 } 686 686 687 687 if (!async_data_read_receive(&callid, &size)) { 688 688 async_answer_0(callid, EREFUSED); … … 690 690 return; 691 691 } 692 692 693 693 if (size != sizeof(inet_addr_t)) { 694 694 async_answer_0(callid, EINVAL); … … 696 696 return; 697 697 } 698 698 699 699 rc = async_data_read_finalize(callid, &srinfo.router, size); 700 700 if (rc != EOK) { … … 703 703 return; 704 704 } 705 705 706 706 if (!async_data_read_receive(&callid, &size)) { 707 707 async_answer_0(callid, EREFUSED); … … 709 709 return; 710 710 } 711 711 712 712 rc = async_data_read_finalize(callid, srinfo.name, 713 713 min(size, str_size(srinfo.name))); 714 714 free(srinfo.name); 715 715 716 716 async_answer_0(iid, rc); 717 717 } -
uspace/srv/net/inetsrv/inetsrv.c
r3061bc1 ra35b458 87 87 { 88 88 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_init()"); 89 89 90 90 port_id_t port; 91 91 errno_t rc = async_create_port(INTERFACE_INET, … … 93 93 if (rc != EOK) 94 94 return rc; 95 95 96 96 rc = async_create_port(INTERFACE_INETCFG, 97 97 inet_cfg_conn, NULL, &port); 98 98 if (rc != EOK) 99 99 return rc; 100 100 101 101 rc = async_create_port(INTERFACE_INETPING, 102 102 inetping_conn, NULL, &port); 103 103 if (rc != EOK) 104 104 return rc; 105 105 106 106 rc = loc_server_register(NAME); 107 107 if (rc != EOK) { … … 109 109 return EEXIST; 110 110 } 111 111 112 112 service_id_t sid; 113 113 rc = loc_service_register(SERVICE_NAME_INET, &sid); … … 116 116 return EEXIST; 117 117 } 118 118 119 119 return EOK; 120 120 } … … 234 234 { 235 235 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()"); 236 236 237 237 uint8_t tos = IPC_GET_ARG1(*icall); 238 238 239 239 ipc_callid_t callid; 240 240 size_t size; … … 244 244 return; 245 245 } 246 246 247 247 if (size != sizeof(inet_addr_t)) { 248 248 async_answer_0(callid, EINVAL); … … 250 250 return; 251 251 } 252 252 253 253 inet_addr_t remote; 254 254 errno_t rc = async_data_write_finalize(callid, &remote, size); … … 257 257 async_answer_0(iid, rc); 258 258 } 259 259 260 260 inet_addr_t local; 261 261 rc = inet_get_srcaddr(&remote, tos, &local); … … 264 264 return; 265 265 } 266 266 267 267 if (!async_data_read_receive(&callid, &size)) { 268 268 async_answer_0(callid, EREFUSED); … … 270 270 return; 271 271 } 272 272 273 273 if (size != sizeof(inet_addr_t)) { 274 274 async_answer_0(callid, EINVAL); … … 276 276 return; 277 277 } 278 278 279 279 rc = async_data_read_finalize(callid, &local, size); 280 280 if (rc != EOK) { … … 283 283 return; 284 284 } 285 285 286 286 async_answer_0(iid, rc); 287 287 } … … 291 291 { 292 292 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_send_srv()"); 293 293 294 294 inet_dgram_t dgram; 295 295 296 296 dgram.iplink = IPC_GET_ARG1(*icall); 297 297 dgram.tos = IPC_GET_ARG2(*icall); 298 298 299 299 uint8_t ttl = IPC_GET_ARG3(*icall); 300 300 int df = IPC_GET_ARG4(*icall); 301 301 302 302 ipc_callid_t callid; 303 303 size_t size; … … 307 307 return; 308 308 } 309 309 310 310 if (size != sizeof(inet_addr_t)) { 311 311 async_answer_0(callid, EINVAL); … … 313 313 return; 314 314 } 315 315 316 316 errno_t rc = async_data_write_finalize(callid, &dgram.src, size); 317 317 if (rc != EOK) { … … 319 319 async_answer_0(iid, rc); 320 320 } 321 321 322 322 if (!async_data_write_receive(&callid, &size)) { 323 323 async_answer_0(callid, EREFUSED); … … 325 325 return; 326 326 } 327 327 328 328 if (size != sizeof(inet_addr_t)) { 329 329 async_answer_0(callid, EINVAL); … … 331 331 return; 332 332 } 333 333 334 334 rc = async_data_write_finalize(callid, &dgram.dest, size); 335 335 if (rc != EOK) { … … 337 337 async_answer_0(iid, rc); 338 338 } 339 339 340 340 rc = async_data_write_accept(&dgram.data, false, 0, 0, 0, 341 341 &dgram.size); … … 344 344 return; 345 345 } 346 346 347 347 rc = inet_send(client, &dgram, client->protocol, ttl, df); 348 348 349 349 free(dgram.data); 350 350 async_answer_0(iid, rc); -
uspace/srv/net/inetsrv/ndp.c
r3061bc1 ra35b458 68 68 inet_dgram_t dgram; 69 69 ndp_pdu_encode(packet, &dgram); 70 70 71 71 inet_link_send_dgram6(link, packet->target_hw_addr, &dgram, 72 72 IP_PROTO_ICMPV6, INET6_HOP_LIMIT_MAX, 0); 73 73 74 74 free(dgram.data); 75 75 76 76 return EOK; 77 77 } … … 86 86 { 87 87 log_msg(LOG_DEFAULT, LVL_DEBUG, "ndp_received()"); 88 88 89 89 ndp_packet_t packet; 90 90 errno_t rc = ndp_pdu_decode(dgram, &packet); 91 91 if (rc != EOK) 92 92 return rc; 93 93 94 94 inet_addr_t sender; 95 95 inet_addr_set6(packet.sender_proto_addr, &sender); 96 96 97 97 inet_addr_t target; 98 98 inet_addr_set6(packet.target_proto_addr, &target); 99 99 100 100 inet_addrobj_t *laddr; 101 101 102 102 log_msg(LOG_DEFAULT, LVL_DEBUG, "NDP PDU decoded; opcode: %d", 103 103 packet.opcode); 104 104 105 105 switch (packet.opcode) { 106 106 case ICMPV6_NEIGHBOUR_SOLICITATION: … … 111 111 if (rc != EOK) 112 112 return rc; 113 113 114 114 ndp_packet_t reply; 115 115 116 116 reply.opcode = ICMPV6_NEIGHBOUR_ADVERTISEMENT; 117 117 addr48(laddr->ilink->mac, reply.sender_hw_addr); … … 119 119 addr48(packet.sender_hw_addr, reply.target_hw_addr); 120 120 addr128(packet.sender_proto_addr, reply.target_proto_addr); 121 121 122 122 ndp_send_packet(laddr->ilink, &reply); 123 123 } 124 124 125 125 break; 126 126 case ICMPV6_NEIGHBOUR_ADVERTISEMENT: … … 129 129 return ntrans_add(packet.sender_proto_addr, 130 130 packet.sender_hw_addr); 131 131 132 132 break; 133 133 case ICMPV6_ROUTER_ADVERTISEMENT: … … 136 136 return ENOTSUP; 137 137 } 138 138 139 139 return EOK; 140 140 } … … 159 159 return EOK; 160 160 } 161 161 162 162 errno_t rc = ntrans_lookup(ip_addr, mac_addr); 163 163 if (rc == EOK) 164 164 return EOK; 165 165 166 166 ndp_packet_t packet; 167 167 168 168 packet.opcode = ICMPV6_NEIGHBOUR_SOLICITATION; 169 169 addr48(ilink->mac, packet.sender_hw_addr); … … 172 172 addr48_solicited_node(ip_addr, packet.target_hw_addr); 173 173 ndp_solicited_node_ip(ip_addr, packet.target_proto_addr); 174 174 175 175 rc = ndp_send_packet(ilink, &packet); 176 176 if (rc != EOK) 177 177 return rc; 178 178 179 179 (void) ntrans_wait_timeout(NDP_REQUEST_TIMEOUT); 180 180 181 181 return ntrans_lookup(ip_addr, mac_addr); 182 182 } -
uspace/srv/net/inetsrv/ntrans.c
r3061bc1 ra35b458 142 142 return ENOENT; 143 143 } 144 144 145 145 fibril_mutex_unlock(&ntrans_list_lock); 146 146 addr48(ntrans->mac_addr, mac_addr); … … 162 162 timeout); 163 163 fibril_mutex_unlock(&ntrans_list_lock); 164 164 165 165 return rc; 166 166 } -
uspace/srv/net/inetsrv/pdu.c
r3061bc1 ra35b458 107 107 /* Upper bound for fragment offset field */ 108 108 size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l + 1); 109 109 110 110 /* Verify that total size of datagram is within reasonable bounds */ 111 111 if (packet->size > FRAG_OFFS_UNIT * fragoff_limit) 112 112 return ELIMIT; 113 113 114 114 size_t hdr_size = sizeof(ip_header_t); 115 115 if (hdr_size >= mtu) 116 116 return EINVAL; 117 117 118 118 assert(hdr_size % 4 == 0); 119 119 assert(offs % FRAG_OFFS_UNIT == 0); 120 120 assert(offs / FRAG_OFFS_UNIT < fragoff_limit); 121 121 122 122 /* Value for the fragment offset field */ 123 123 uint16_t foff = offs / FRAG_OFFS_UNIT; 124 124 125 125 /* Amount of space in the PDU available for payload */ 126 126 size_t spc_avail = mtu - hdr_size; 127 127 spc_avail -= (spc_avail % FRAG_OFFS_UNIT); 128 128 129 129 /* Amount of data (payload) to transfer */ 130 130 size_t xfer_size = min(packet->size - offs, spc_avail); 131 131 132 132 /* Total PDU size */ 133 133 size_t size = hdr_size + xfer_size; 134 134 135 135 /* Offset of remaining payload */ 136 136 size_t rem_offs = offs + xfer_size; 137 137 138 138 /* Flags */ 139 139 uint16_t flags_foff = … … 141 141 (rem_offs < packet->size ? BIT_V(uint16_t, FF_FLAG_MF) : 0) + 142 142 (foff << FF_FRAGOFF_l); 143 143 144 144 void *data = calloc(size, 1); 145 145 if (data == NULL) 146 146 return ENOMEM; 147 147 148 148 /* Encode header fields */ 149 149 ip_header_t *hdr = (ip_header_t *) data; 150 150 151 151 hdr->ver_ihl = 152 152 (4 << VI_VERSION_l) | (hdr_size / sizeof(uint32_t)); … … 160 160 hdr->src_addr = host2uint32_t_be(src); 161 161 hdr->dest_addr = host2uint32_t_be(dest); 162 162 163 163 /* Compute checksum */ 164 164 uint16_t chksum = inet_checksum_calc(INET_CHECKSUM_INIT, 165 165 (void *) hdr, hdr_size); 166 166 hdr->chksum = host2uint16_t_be(chksum); 167 167 168 168 /* Copy payload */ 169 169 memcpy((uint8_t *) data + hdr_size, packet->data + offs, xfer_size); 170 170 171 171 *rdata = data; 172 172 *rsize = size; 173 173 *roffs = rem_offs; 174 174 175 175 return EOK; 176 176 } … … 200 200 if (mtu < 1280) 201 201 return ELIMIT; 202 202 203 203 /* Upper bound for fragment offset field */ 204 204 size_t fragoff_limit = 1 << (OF_FRAGOFF_h - OF_FRAGOFF_l); 205 205 206 206 /* Verify that total size of datagram is within reasonable bounds */ 207 207 if (offs + packet->size > FRAG_OFFS_UNIT * fragoff_limit) 208 208 return ELIMIT; 209 209 210 210 /* Determine whether we need the Fragment extension header */ 211 211 bool fragment; … … 214 214 else 215 215 fragment = true; 216 216 217 217 size_t hdr_size; 218 218 if (fragment) … … 220 220 else 221 221 hdr_size = sizeof(ip6_header_t); 222 222 223 223 if (hdr_size >= mtu) 224 224 return EINVAL; 225 225 226 226 static_assert(sizeof(ip6_header_t) % 8 == 0); 227 227 assert(hdr_size % 8 == 0); 228 228 assert(offs % FRAG_OFFS_UNIT == 0); 229 229 assert(offs / FRAG_OFFS_UNIT < fragoff_limit); 230 230 231 231 /* Value for the fragment offset field */ 232 232 uint16_t foff = offs / FRAG_OFFS_UNIT; 233 233 234 234 /* Amount of space in the PDU available for payload */ 235 235 size_t spc_avail = mtu - hdr_size; 236 236 spc_avail -= (spc_avail % FRAG_OFFS_UNIT); 237 237 238 238 /* Amount of data (payload) to transfer */ 239 239 size_t xfer_size = min(packet->size - offs, spc_avail); 240 240 241 241 /* Total PDU size */ 242 242 size_t size = hdr_size + xfer_size; 243 243 244 244 /* Offset of remaining payload */ 245 245 size_t rem_offs = offs + xfer_size; 246 246 247 247 /* Flags */ 248 248 uint16_t offsmf = 249 249 (rem_offs < packet->size ? BIT_V(uint16_t, OF_FLAG_M) : 0) + 250 250 (foff << OF_FRAGOFF_l); 251 251 252 252 void *data = calloc(size, 1); 253 253 if (data == NULL) 254 254 return ENOMEM; 255 255 256 256 /* Encode header fields */ 257 257 ip6_header_t *hdr6 = (ip6_header_t *) data; 258 258 259 259 hdr6->ver_tc = (6 << (VI_VERSION_l)); 260 260 memset(hdr6->tc_fl, 0, 3); 261 261 hdr6->hop_limit = packet->ttl; 262 262 263 263 host2addr128_t_be(src, hdr6->src_addr); 264 264 host2addr128_t_be(dest, hdr6->dest_addr); 265 265 266 266 /* Optionally encode Fragment extension header fields */ 267 267 if (fragment) { 268 268 assert(offsmf != 0); 269 269 270 270 hdr6->payload_len = host2uint16_t_be(packet->size + 271 271 sizeof(ip6_header_fragment_t)); 272 272 hdr6->next = IP6_NEXT_FRAGMENT; 273 273 274 274 ip6_header_fragment_t *hdr6f = (ip6_header_fragment_t *) 275 275 (hdr6 + 1); 276 276 277 277 hdr6f->next = packet->proto; 278 278 hdr6f->reserved = 0; … … 281 281 } else { 282 282 assert(offsmf == 0); 283 283 284 284 hdr6->payload_len = host2uint16_t_be(packet->size); 285 285 hdr6->next = packet->proto; 286 286 } 287 287 288 288 /* Copy payload */ 289 289 memcpy((uint8_t *) data + hdr_size, packet->data + offs, xfer_size); 290 290 291 291 *rdata = data; 292 292 *rsize = size; 293 293 *roffs = rem_offs; 294 294 295 295 return EOK; 296 296 } … … 312 312 { 313 313 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_pdu_decode()"); 314 314 315 315 if (size < sizeof(ip_header_t)) { 316 316 log_msg(LOG_DEFAULT, LVL_DEBUG, "PDU too short (%zu)", size); 317 317 return EINVAL; 318 318 } 319 319 320 320 ip_header_t *hdr = (ip_header_t *) data; 321 321 322 322 uint8_t version = BIT_RANGE_EXTRACT(uint8_t, VI_VERSION_h, 323 323 VI_VERSION_l, hdr->ver_ihl); … … 326 326 return EINVAL; 327 327 } 328 328 329 329 size_t tot_len = uint16_t_be2host(hdr->tot_len); 330 330 if (tot_len < sizeof(ip_header_t)) { … … 332 332 return EINVAL; 333 333 } 334 334 335 335 if (tot_len > size) { 336 336 log_msg(LOG_DEFAULT, LVL_DEBUG, "Total Length = %zu > PDU size = %zu", … … 338 338 return EINVAL; 339 339 } 340 340 341 341 uint16_t ident = uint16_t_be2host(hdr->id); 342 342 uint16_t flags_foff = uint16_t_be2host(hdr->flags_foff); … … 344 344 flags_foff); 345 345 /* XXX Checksum */ 346 346 347 347 inet_addr_set(uint32_t_be2host(hdr->src_addr), &packet->src); 348 348 inet_addr_set(uint32_t_be2host(hdr->dest_addr), &packet->dest); … … 351 351 packet->ttl = hdr->ttl; 352 352 packet->ident = ident; 353 353 354 354 packet->df = (flags_foff & BIT_V(uint16_t, FF_FLAG_DF)) != 0; 355 355 packet->mf = (flags_foff & BIT_V(uint16_t, FF_FLAG_MF)) != 0; 356 356 packet->offs = foff * FRAG_OFFS_UNIT; 357 357 358 358 /* XXX IP options */ 359 359 size_t data_offs = sizeof(uint32_t) * 360 360 BIT_RANGE_EXTRACT(uint8_t, VI_IHL_h, VI_IHL_l, hdr->ver_ihl); 361 361 362 362 packet->size = tot_len - data_offs; 363 363 packet->data = calloc(packet->size, 1); … … 366 366 return ENOMEM; 367 367 } 368 368 369 369 memcpy(packet->data, (uint8_t *) data + data_offs, packet->size); 370 370 packet->link_id = link_id; 371 371 372 372 return EOK; 373 373 } … … 389 389 { 390 390 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_pdu_decode6()"); 391 391 392 392 if (size < sizeof(ip6_header_t)) { 393 393 log_msg(LOG_DEFAULT, LVL_DEBUG, "PDU too short (%zu)", size); 394 394 return EINVAL; 395 395 } 396 396 397 397 ip6_header_t *hdr6 = (ip6_header_t *) data; 398 398 399 399 uint8_t version = BIT_RANGE_EXTRACT(uint8_t, VI_VERSION_h, 400 400 VI_VERSION_l, hdr6->ver_tc); … … 403 403 return EINVAL; 404 404 } 405 405 406 406 size_t payload_len = uint16_t_be2host(hdr6->payload_len); 407 407 if (payload_len + sizeof(ip6_header_t) > size) { … … 410 410 return EINVAL; 411 411 } 412 412 413 413 uint32_t ident; 414 414 uint16_t offsmf; … … 416 416 uint16_t next; 417 417 size_t data_offs = sizeof(ip6_header_t); 418 418 419 419 /* Fragment extension header */ 420 420 if (hdr6->next == IP6_NEXT_FRAGMENT) { 421 421 ip6_header_fragment_t *hdr6f = (ip6_header_fragment_t *) 422 422 (hdr6 + 1); 423 423 424 424 ident = uint32_t_be2host(hdr6f->id); 425 425 offsmf = uint16_t_be2host(hdr6f->offsmf); … … 435 435 next = hdr6->next; 436 436 } 437 437 438 438 addr128_t src; 439 439 addr128_t dest; 440 440 441 441 addr128_t_be2host(hdr6->src_addr, src); 442 442 inet_addr_set6(src, &packet->src); 443 443 444 444 addr128_t_be2host(hdr6->dest_addr, dest); 445 445 inet_addr_set6(dest, &packet->dest); 446 446 447 447 packet->tos = 0; 448 448 packet->proto = next; 449 449 packet->ttl = hdr6->hop_limit; 450 450 packet->ident = ident; 451 451 452 452 packet->df = 1; 453 453 packet->mf = (offsmf & BIT_V(uint16_t, OF_FLAG_M)) != 0; 454 454 packet->offs = foff * FRAG_OFFS_UNIT; 455 455 456 456 packet->size = payload_len; 457 457 packet->data = calloc(packet->size, 1); … … 460 460 return ENOMEM; 461 461 } 462 462 463 463 memcpy(packet->data, (uint8_t *) data + data_offs, packet->size); 464 464 packet->link_id = link_id; … … 480 480 dgram->tos = 0; 481 481 dgram->size = sizeof(icmpv6_message_t) + sizeof(ndp_message_t); 482 482 483 483 dgram->data = calloc(1, dgram->size); 484 484 if (dgram->data == NULL) 485 485 return ENOMEM; 486 486 487 487 icmpv6_message_t *icmpv6 = (icmpv6_message_t *) dgram->data; 488 488 489 489 icmpv6->type = ndp->opcode; 490 490 icmpv6->code = 0; 491 491 memset(icmpv6->un.ndp.reserved, 0, 3); 492 492 493 493 ndp_message_t *message = (ndp_message_t *) (icmpv6 + 1); 494 494 495 495 if (ndp->opcode == ICMPV6_NEIGHBOUR_SOLICITATION) { 496 496 host2addr128_t_be(ndp->solicited_ip, message->target_address); … … 502 502 icmpv6->un.ndp.flags = NDP_FLAG_OVERRIDE | NDP_FLAG_SOLICITED; 503 503 } 504 504 505 505 message->length = 1; 506 506 addr48(ndp->sender_hw_addr, message->mac); 507 507 508 508 icmpv6_phdr_t phdr; 509 509 510 510 host2addr128_t_be(ndp->sender_proto_addr, phdr.src_addr); 511 511 host2addr128_t_be(ndp->target_proto_addr, phdr.dest_addr); … … 513 513 memset(phdr.zeroes, 0, 3); 514 514 phdr.next = IP_PROTO_ICMPV6; 515 515 516 516 uint16_t cs_phdr = 517 517 inet_checksum_calc(INET_CHECKSUM_INIT, &phdr, 518 518 sizeof(icmpv6_phdr_t)); 519 519 520 520 uint16_t cs_all = inet_checksum_calc(cs_phdr, dgram->data, 521 521 dgram->size); 522 522 523 523 icmpv6->checksum = host2uint16_t_be(cs_all); 524 524 525 525 return EOK; 526 526 } … … 541 541 if (src_ver != ip_v6) 542 542 return EINVAL; 543 543 544 544 if (dgram->size < sizeof(icmpv6_message_t) + sizeof(ndp_message_t)) 545 545 return EINVAL; 546 546 547 547 icmpv6_message_t *icmpv6 = (icmpv6_message_t *) dgram->data; 548 548 549 549 ndp->opcode = icmpv6->type; 550 550 551 551 ndp_message_t *message = (ndp_message_t *) (icmpv6 + 1); 552 552 553 553 addr128_t_be2host(message->target_address, ndp->target_proto_addr); 554 554 addr48(message->mac, ndp->sender_hw_addr); 555 555 556 556 return EOK; 557 557 } -
uspace/srv/net/inetsrv/sroute.c
r3061bc1 ra35b458 96 96 { 97 97 ip_ver_t addr_ver = inet_addr_get(addr, NULL, NULL); 98 98 99 99 inet_sroute_t *best = NULL; 100 100 uint8_t best_bits = 0; 101 102 fibril_mutex_lock(&sroute_list_lock); 103 101 102 fibril_mutex_lock(&sroute_list_lock); 103 104 104 list_foreach(sroute_list, sroute_list, inet_sroute_t, sroute) { 105 105 uint8_t dest_bits; 106 106 ip_ver_t dest_ver = inet_naddr_get(&sroute->dest, NULL, NULL, 107 107 &dest_bits); 108 108 109 109 /* Skip comparison with different address family */ 110 110 if (addr_ver != dest_ver) 111 111 continue; 112 112 113 113 /* Look for the most specific route */ 114 114 if ((best != NULL) && (best_bits >= dest_bits)) 115 115 continue; 116 116 117 117 if (inet_naddr_compare_mask(&sroute->dest, addr)) { 118 118 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find: found candidate %p", 119 119 sroute); 120 120 121 121 best = sroute; 122 122 best_bits = dest_bits; 123 123 } 124 124 } 125 125 126 126 if (best == NULL) 127 127 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find: Not found"); 128 129 fibril_mutex_unlock(&sroute_list_lock); 130 128 129 fibril_mutex_unlock(&sroute_list_lock); 130 131 131 return best; 132 132 }
Note:
See TracChangeset
for help on using the changeset viewer.
