Changeset a35b458 in mainline for uspace/srv/net
- 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
- Files:
-
- 19 edited
-
dhcp/dhcp.c (modified) (3 diffs)
-
dnsrsrv/dns_msg.c (modified) (2 diffs)
-
dnsrsrv/dnsrsrv.c (modified) (15 diffs)
-
dnsrsrv/query.c (modified) (11 diffs)
-
ethip/arp.c (modified) (4 diffs)
-
ethip/ethip.c (modified) (15 diffs)
-
ethip/ethip.h (modified) (1 diff)
-
ethip/ethip_nic.c (modified) (17 diffs)
-
inetsrv/addrobj.c (modified) (2 diffs)
-
inetsrv/icmpv6.c (modified) (10 diffs)
-
inetsrv/inet_link.c (modified) (11 diffs)
-
inetsrv/inetcfg.c (modified) (27 diffs)
-
inetsrv/inetsrv.c (modified) (20 diffs)
-
inetsrv/ndp.c (modified) (8 diffs)
-
inetsrv/ntrans.c (modified) (2 diffs)
-
inetsrv/pdu.c (modified) (24 diffs)
-
inetsrv/sroute.c (modified) (1 diff)
-
loopip/loopip.c (modified) (14 diffs)
-
slip/slip.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/dhcp/dhcp.c
r3061bc1 ra35b458 430 430 431 431 dlink->retries_left = dhcp_discover_retries; 432 432 433 433 if ((dlink->timeout->state == fts_not_set) || 434 434 (dlink->timeout->state == fts_fired)) 435 435 fibril_timer_set(dlink->timeout, dhcp_discover_timeout_val, 436 436 dhcpsrv_discover_timeout, dlink); 437 437 438 438 return rc; 439 439 } … … 507 507 { 508 508 log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcpsrv_link_add(%zu)", link_id); 509 509 510 510 dhcp_link_t *dlink = dhcpsrv_link_find(link_id); 511 511 512 512 if (dlink == NULL) { 513 513 log_msg(LOG_DEFAULT, LVL_NOTE, "Link %zu doesn't exist", … … 515 515 return EINVAL; 516 516 } 517 517 518 518 return dhcp_discover_proc(dlink); 519 519 } -
uspace/srv/net/dnsrsrv/dns_msg.c
r3061bc1 ra35b458 298 298 { 299 299 assert(buf_size >= 4); 300 300 301 301 uint32_t w = ((uint32_t) buf[0] << 24) + 302 302 ((uint32_t) buf[1] << 16) + 303 303 ((uint32_t) buf[2] << 8) + 304 304 buf[3]; 305 305 306 306 return w; 307 307 } … … 311 311 { 312 312 assert(buf_size >= 16); 313 313 314 314 addr128_t_be2host(buf, addr); 315 315 } -
uspace/srv/net/dnsrsrv/dnsrsrv.c
r3061bc1 ra35b458 90 90 { 91 91 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()"); 92 92 93 93 ip_ver_t ver = IPC_GET_ARG1(*icall); 94 94 95 95 char *name; 96 96 errno_t rc = async_data_write_accept((void **) &name, true, 0, … … 100 100 return; 101 101 } 102 102 103 103 dns_host_info_t *hinfo; 104 104 rc = dns_name2host(name, &hinfo, ver); … … 107 107 return; 108 108 } 109 109 110 110 ipc_callid_t callid; 111 111 size_t size; … … 115 115 return; 116 116 } 117 117 118 118 if (size != sizeof(inet_addr_t)) { 119 119 async_answer_0(callid, EINVAL); … … 121 121 return; 122 122 } 123 123 124 124 rc = async_data_read_finalize(callid, &hinfo->addr, size); 125 125 if (rc != EOK) { … … 128 128 return; 129 129 } 130 130 131 131 if (!async_data_read_receive(&callid, &size)) { 132 132 async_answer_0(callid, EREFUSED); … … 134 134 return; 135 135 } 136 136 137 137 size_t act_size = str_size(hinfo->cname); 138 138 if (act_size > size) { … … 141 141 return; 142 142 } 143 143 144 144 rc = async_data_read_finalize(callid, hinfo->cname, act_size); 145 145 if (rc != EOK) 146 146 async_answer_0(callid, rc); 147 147 148 148 async_answer_0(iid, rc); 149 149 150 150 dns_hostinfo_destroy(hinfo); 151 151 } … … 155 155 { 156 156 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()"); 157 157 158 158 ipc_callid_t callid; 159 159 size_t size; … … 163 163 return; 164 164 } 165 165 166 166 if (size != sizeof(inet_addr_t)) { 167 167 async_answer_0(callid, EINVAL); … … 169 169 return; 170 170 } 171 171 172 172 // FIXME locking 173 173 174 174 errno_t rc = async_data_read_finalize(callid, &dns_server_addr, size); 175 175 if (rc != EOK) 176 176 async_answer_0(callid, rc); 177 177 178 178 async_answer_0(iid, rc); 179 179 } … … 183 183 { 184 184 log_msg(LOG_DEFAULT, LVL_DEBUG, "dnsr_set_srvaddr_srv()"); 185 185 186 186 ipc_callid_t callid; 187 187 size_t size; … … 191 191 return; 192 192 } 193 193 194 194 if (size != sizeof(inet_addr_t)) { 195 195 async_answer_0(callid, EINVAL); … … 197 197 return; 198 198 } 199 199 200 200 // FIXME locking 201 201 202 202 errno_t rc = async_data_write_finalize(callid, &dns_server_addr, size); 203 203 if (rc != EOK) { … … 205 205 async_answer_0(iid, rc); 206 206 } 207 207 208 208 async_answer_0(iid, rc); 209 209 } -
uspace/srv/net/dnsrsrv/query.c
r3061bc1 ra35b458 54 54 if (sname == NULL) 55 55 return ENOMEM; 56 56 57 57 char *qname = str_dup(name); 58 58 if (qname == NULL) { … … 60 60 return ENOMEM; 61 61 } 62 62 63 63 dns_question_t *question = calloc(1, sizeof(dns_question_t)); 64 64 if (question == NULL) { … … 67 67 return ENOMEM; 68 68 } 69 69 70 70 question->qname = qname; 71 71 question->qtype = qtype; 72 72 question->qclass = DC_IN; 73 73 74 74 dns_message_t *msg = dns_message_new(); 75 75 if (msg == NULL) { … … 79 79 return ENOMEM; 80 80 } 81 81 82 82 msg->id = msg_id++; 83 83 msg->qr = QR_QUERY; … … 87 87 msg->rd = true; 88 88 msg->ra = false; 89 89 90 90 list_append(&question->msg, &msg->question); 91 91 92 92 log_msg(LOG_DEFAULT, LVL_DEBUG, "dns_name_query: send DNS request"); 93 93 dns_message_t *amsg; … … 98 98 return rc; 99 99 } 100 100 101 101 list_foreach(amsg->answer, msg, dns_rr_t, rr) { 102 102 log_msg(LOG_DEFAULT, LVL_DEBUG, " - '%s' %u/%u, dsize %zu", 103 103 rr->name, rr->rtype, rr->rclass, rr->rdata_size); 104 104 105 105 if ((rr->rtype == DTYPE_CNAME) && (rr->rclass == DC_IN) && 106 106 (str_cmp(rr->name, sname) == 0)) { 107 107 108 108 log_msg(LOG_DEFAULT, LVL_DEBUG, "decode cname (%p, %zu, %zu)", 109 109 amsg->pdu.data, amsg->pdu.size, rr->roff); 110 110 111 111 char *cname; 112 112 size_t eoff; … … 114 114 if (rc != EOK) { 115 115 assert((rc == EINVAL) || (rc == ENOMEM)); 116 116 117 117 log_msg(LOG_DEFAULT, LVL_DEBUG, "error decoding cname"); 118 118 119 119 dns_message_destroy(msg); 120 120 dns_message_destroy(amsg); 121 121 free(sname); 122 122 123 123 return rc; 124 124 } 125 125 126 126 log_msg(LOG_DEFAULT, LVL_DEBUG, "name = '%s' " 127 127 "cname = '%s'", sname, cname); 128 128 129 129 /* Continue looking for the more canonical name */ 130 130 free(sname); 131 131 sname = cname; 132 132 } 133 133 134 134 if ((qtype == DTYPE_A) && (rr->rtype == DTYPE_A) && 135 135 (rr->rclass == DC_IN) && (rr->rdata_size == sizeof(addr32_t)) && 136 136 (str_cmp(rr->name, sname) == 0)) { 137 137 138 138 info->cname = str_dup(rr->name); 139 139 if (info->cname == NULL) { … … 141 141 dns_message_destroy(amsg); 142 142 free(sname); 143 143 144 144 return ENOMEM; 145 145 } 146 146 147 147 inet_addr_set(dns_uint32_t_decode(rr->rdata, rr->rdata_size), 148 148 &info->addr); 149 149 150 150 dns_message_destroy(msg); 151 151 dns_message_destroy(amsg); 152 152 free(sname); 153 153 154 154 return EOK; 155 155 } 156 156 157 157 if ((qtype == DTYPE_AAAA) && (rr->rtype == DTYPE_AAAA) && 158 158 (rr->rclass == DC_IN) && (rr->rdata_size == sizeof(addr128_t)) && 159 159 (str_cmp(rr->name, sname) == 0)) { 160 160 161 161 info->cname = str_dup(rr->name); 162 162 if (info->cname == NULL) { … … 164 164 dns_message_destroy(amsg); 165 165 free(sname); 166 166 167 167 return ENOMEM; 168 168 } 169 169 170 170 addr128_t addr; 171 171 dns_addr128_t_decode(rr->rdata, rr->rdata_size, addr); 172 172 173 173 inet_addr_set6(addr, &info->addr); 174 174 175 175 dns_message_destroy(msg); 176 176 dns_message_destroy(amsg); 177 177 free(sname); 178 178 179 179 return EOK; 180 180 } 181 181 } 182 182 183 183 log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname); 184 184 185 185 dns_message_destroy(msg); 186 186 dns_message_destroy(amsg); 187 187 free(sname); 188 188 189 189 return EIO; 190 190 } … … 195 195 if (info == NULL) 196 196 return ENOMEM; 197 197 198 198 errno_t rc; 199 199 200 200 switch (ver) { 201 201 case ip_any: 202 202 rc = dns_name_query(name, DTYPE_AAAA, info); 203 203 204 204 if (rc != EOK) 205 205 rc = dns_name_query(name, DTYPE_A, info); 206 206 207 207 break; 208 208 case ip_v4: … … 215 215 rc = EINVAL; 216 216 } 217 217 218 218 if (rc == EOK) 219 219 *rinfo = info; 220 220 else 221 221 free(info); 222 222 223 223 return rc; 224 224 } -
uspace/srv/net/ethip/arp.c
r3061bc1 ra35b458 55 55 { 56 56 log_msg(LOG_DEFAULT, LVL_DEBUG, "arp_received()"); 57 57 58 58 arp_eth_packet_t packet; 59 59 errno_t rc = arp_pdu_decode(frame->data, frame->size, &packet); 60 60 if (rc != EOK) 61 61 return; 62 62 63 63 log_msg(LOG_DEFAULT, LVL_DEBUG, "ARP PDU decoded, opcode=%d, tpa=%x", 64 64 packet.opcode, packet.target_proto_addr); 65 65 66 66 inet_addr_t addr; 67 67 inet_addr_set(packet.target_proto_addr, &addr); 68 68 69 69 ethip_link_addr_t *laddr = ethip_nic_addr_find(nic, &addr); 70 70 if (laddr == NULL) 71 71 return; 72 72 73 73 addr32_t laddr_v4; 74 74 ip_ver_t laddr_ver = inet_addr_get(&laddr->addr, &laddr_v4, NULL); 75 75 if (laddr_ver != ip_v4) 76 76 return; 77 77 78 78 log_msg(LOG_DEFAULT, LVL_DEBUG, "Request/reply to my address"); 79 79 80 80 (void) atrans_add(packet.sender_proto_addr, 81 81 packet.sender_hw_addr); 82 82 83 83 if (packet.opcode == aop_request) { 84 84 arp_eth_packet_t reply; 85 85 86 86 reply.opcode = aop_reply; 87 87 addr48(nic->mac_addr, reply.sender_hw_addr); … … 89 89 addr48(packet.sender_hw_addr, reply.target_hw_addr); 90 90 reply.target_proto_addr = packet.sender_proto_addr; 91 91 92 92 arp_send_packet(nic, &reply); 93 93 } … … 106 106 if (rc == EOK) 107 107 return EOK; 108 108 109 109 arp_eth_packet_t packet; 110 110 111 111 packet.opcode = aop_request; 112 112 addr48(nic->mac_addr, packet.sender_hw_addr); … … 114 114 addr48(addr48_broadcast, packet.target_hw_addr); 115 115 packet.target_proto_addr = ip_addr; 116 116 117 117 rc = arp_send_packet(nic, &packet); 118 118 if (rc != EOK) 119 119 return rc; 120 120 121 121 return atrans_lookup_timeout(ip_addr, ARP_REQUEST_TIMEOUT, mac_addr); 122 122 } -
uspace/srv/net/ethip/ethip.c
r3061bc1 ra35b458 80 80 { 81 81 async_set_fallback_port_handler(ethip_client_conn, NULL); 82 82 83 83 errno_t rc = loc_server_register(NAME); 84 84 if (rc != EOK) { … … 86 86 return rc; 87 87 } 88 88 89 89 rc = ethip_nic_discovery_start(); 90 90 if (rc != EOK) 91 91 return rc; 92 92 93 93 return EOK; 94 94 } … … 173 173 { 174 174 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_send()"); 175 175 176 176 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 177 177 eth_frame_t frame; 178 178 179 179 errno_t rc = arp_translate(nic, sdu->src, sdu->dest, frame.dest); 180 180 if (rc != EOK) { … … 183 183 return rc; 184 184 } 185 185 186 186 addr48(nic->mac_addr, frame.src); 187 187 frame.etype_len = ETYPE_IP; 188 188 frame.data = sdu->data; 189 189 frame.size = sdu->size; 190 190 191 191 void *data; 192 192 size_t size; … … 194 194 if (rc != EOK) 195 195 return rc; 196 196 197 197 rc = ethip_nic_send(nic, data, size); 198 198 free(data); 199 199 200 200 return rc; 201 201 } … … 204 204 { 205 205 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_send6()"); 206 206 207 207 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 208 208 eth_frame_t frame; 209 209 210 210 addr48(sdu->dest, frame.dest); 211 211 addr48(nic->mac_addr, frame.src); … … 213 213 frame.data = sdu->data; 214 214 frame.size = sdu->size; 215 215 216 216 void *data; 217 217 size_t size; … … 219 219 if (rc != EOK) 220 220 return rc; 221 221 222 222 rc = ethip_nic_send(nic, data, size); 223 223 free(data); 224 224 225 225 return rc; 226 226 } … … 230 230 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_received(): srv=%p", srv); 231 231 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 232 232 233 233 log_msg(LOG_DEFAULT, LVL_DEBUG, " - eth_pdu_decode"); 234 234 235 235 eth_frame_t frame; 236 236 errno_t rc = eth_pdu_decode(data, size, &frame); … … 239 239 return rc; 240 240 } 241 241 242 242 iplink_recv_sdu_t sdu; 243 243 244 244 switch (frame.etype_len) { 245 245 case ETYPE_ARP: … … 264 264 frame.etype_len); 265 265 } 266 266 267 267 free(frame.data); 268 268 return rc; … … 279 279 { 280 280 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_get_mac48()"); 281 281 282 282 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 283 283 addr48(nic->mac_addr, *mac); 284 284 285 285 return EOK; 286 286 } … … 289 289 { 290 290 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_set_mac48()"); 291 291 292 292 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 293 293 addr48(*mac, nic->mac_addr); 294 294 295 295 return EOK; 296 296 } … … 299 299 { 300 300 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 301 301 302 302 return ethip_nic_addr_add(nic, addr); 303 303 } … … 306 306 { 307 307 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 308 308 309 309 return ethip_nic_addr_remove(nic, addr); 310 310 } -
uspace/srv/net/ethip/ethip.h
r3061bc1 ra35b458 62 62 /** MAC address */ 63 63 addr48_t mac_addr; 64 64 65 65 /** 66 66 * List of IP addresses configured on this link -
uspace/srv/net/ethip/ethip_nic.c
r3061bc1 ra35b458 112 112 return NULL; 113 113 } 114 114 115 115 link_initialize(&nic->link); 116 116 list_initialize(&nic->addr_list); 117 117 118 118 return nic; 119 119 } … … 127 127 return NULL; 128 128 } 129 129 130 130 link_initialize(&laddr->link); 131 131 laddr->addr = *addr; 132 132 133 133 return laddr; 134 134 } … … 138 138 if (nic->svc_name != NULL) 139 139 free(nic->svc_name); 140 140 141 141 free(nic); 142 142 } … … 151 151 bool in_list = false; 152 152 nic_address_t nic_address; 153 153 154 154 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_open()"); 155 155 ethip_nic_t *nic = ethip_nic_new(); 156 156 if (nic == NULL) 157 157 return ENOMEM; 158 158 159 159 errno_t rc = loc_service_get_name(sid, &nic->svc_name); 160 160 if (rc != EOK) { … … 162 162 goto error; 163 163 } 164 164 165 165 nic->sess = loc_service_connect(sid, INTERFACE_DDF, 0); 166 166 if (nic->sess == NULL) { … … 168 168 goto error; 169 169 } 170 170 171 171 nic->svc_id = sid; 172 172 173 173 rc = nic_callback_create(nic->sess, ethip_nic_cb_conn, nic); 174 174 if (rc != EOK) { … … 192 192 goto error; 193 193 } 194 194 195 195 addr48(nic_address.address, nic->mac_addr); 196 196 … … 216 216 if (in_list) 217 217 list_remove(&nic->link); 218 218 219 219 if (nic->sess != NULL) 220 220 async_hangup(nic->sess); 221 221 222 222 ethip_nic_delete(nic); 223 223 return rc; … … 332 332 return rc; 333 333 } 334 334 335 335 return ethip_nic_check_new(); 336 336 } … … 371 371 { 372 372 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_setup_multicast()"); 373 373 374 374 /* Count the number of multicast addresses */ 375 375 376 376 size_t count = 0; 377 377 378 378 list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) { 379 379 ip_ver_t ver = inet_addr_get(&laddr->addr, NULL, NULL); … … 381 381 count++; 382 382 } 383 383 384 384 if (count == 0) 385 385 return nic_multicast_set_mode(nic->sess, NIC_MULTICAST_BLOCKED, 386 386 NULL, 0); 387 387 388 388 nic_address_t *mac_list = calloc(count, sizeof(nic_address_t)); 389 389 if (mac_list == NULL) 390 390 return ENOMEM; 391 391 392 392 /* Create the multicast MAC list */ 393 393 394 394 size_t i = 0; 395 395 396 396 list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) { 397 397 addr128_t v6; … … 399 399 if (ver != ip_v6) 400 400 continue; 401 401 402 402 assert(i < count); 403 403 404 404 addr48_t mac; 405 405 addr48_solicited_node(v6, mac); 406 406 407 407 /* Avoid duplicate addresses in the list */ 408 408 409 409 bool found = false; 410 410 411 411 for (size_t j = 0; j < i; j++) { 412 412 if (addr48_compare(mac_list[j].address, mac)) { … … 415 415 } 416 416 } 417 417 418 418 if (!found) { 419 419 addr48(mac, mac_list[i].address); … … 422 422 count--; 423 423 } 424 424 425 425 /* Setup the multicast MAC list */ 426 426 427 427 errno_t rc = nic_multicast_set_mode(nic->sess, NIC_MULTICAST_LIST, 428 428 mac_list, count); 429 429 430 430 free(mac_list); 431 431 return rc; … … 435 435 { 436 436 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_add()"); 437 437 438 438 ethip_link_addr_t *laddr = ethip_nic_addr_new(addr); 439 439 if (laddr == NULL) 440 440 return ENOMEM; 441 441 442 442 list_append(&laddr->link, &nic->addr_list); 443 443 444 444 return ethip_nic_setup_multicast(nic); 445 445 } … … 448 448 { 449 449 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_remove()"); 450 450 451 451 ethip_link_addr_t *laddr = ethip_nic_addr_find(nic, addr); 452 452 if (laddr == NULL) 453 453 return ENOENT; 454 454 455 455 list_remove(&laddr->link); 456 456 ethip_link_addr_delete(laddr); 457 457 458 458 return ethip_nic_setup_multicast(nic); 459 459 } … … 463 463 { 464 464 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_find()"); 465 465 466 466 list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) { 467 467 if (inet_addr_compare(addr, &laddr->addr)) 468 468 return laddr; 469 469 } 470 470 471 471 return NULL; 472 472 } -
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 } -
uspace/srv/net/loopip/loopip.c
r3061bc1 ra35b458 77 77 typedef struct { 78 78 link_t link; 79 79 80 80 /* XXX Version should be part of SDU */ 81 81 ip_ver_t ver; … … 90 90 rqueue_entry_t *rqe = 91 91 list_get_instance(link, rqueue_entry_t, link); 92 92 93 93 (void) iplink_ev_recv(&loopip_iplink, &rqe->sdu, rqe->ver); 94 94 95 95 free(rqe->sdu.data); 96 96 free(rqe); 97 97 } 98 98 99 99 return 0; 100 100 } … … 103 103 { 104 104 async_set_fallback_port_handler(loopip_client_conn, NULL); 105 105 106 106 errno_t rc = loc_server_register(NAME); 107 107 if (rc != EOK) { … … 109 109 return rc; 110 110 } 111 111 112 112 iplink_srv_init(&loopip_iplink); 113 113 loopip_iplink.ops = &loopip_iplink_ops; 114 114 loopip_iplink.arg = NULL; 115 115 116 116 prodcons_initialize(&loopip_rcv_queue); 117 117 118 118 const char *svc_name = "net/loopback"; 119 119 service_id_t sid; … … 124 124 return rc; 125 125 } 126 126 127 127 category_id_t iplink_cat; 128 128 rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING); … … 131 131 return rc; 132 132 } 133 133 134 134 rc = loc_service_add_to_cat(sid, iplink_cat); 135 135 if (rc != EOK) { … … 138 138 return rc; 139 139 } 140 140 141 141 fid_t fid = fibril_create(loopip_recv_fibril, NULL); 142 142 if (fid == 0) 143 143 return ENOMEM; 144 144 145 145 fibril_add_ready(fid); 146 146 147 147 return EOK; 148 148 } … … 169 169 { 170 170 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_send()"); 171 171 172 172 rqueue_entry_t *rqe = calloc(1, sizeof(rqueue_entry_t)); 173 173 if (rqe == NULL) 174 174 return ENOMEM; 175 175 176 176 /* 177 177 * Clone SDU … … 183 183 return ENOMEM; 184 184 } 185 185 186 186 memcpy(rqe->sdu.data, sdu->data, sdu->size); 187 187 rqe->sdu.size = sdu->size; 188 188 189 189 /* 190 190 * Insert to receive queue 191 191 */ 192 192 prodcons_produce(&loopip_rcv_queue, &rqe->link); 193 193 194 194 return EOK; 195 195 } … … 198 198 { 199 199 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip6_send()"); 200 200 201 201 rqueue_entry_t *rqe = calloc(1, sizeof(rqueue_entry_t)); 202 202 if (rqe == NULL) 203 203 return ENOMEM; 204 204 205 205 /* 206 206 * Clone SDU … … 212 212 return ENOMEM; 213 213 } 214 214 215 215 memcpy(rqe->sdu.data, sdu->data, sdu->size); 216 216 rqe->sdu.size = sdu->size; 217 217 218 218 /* 219 219 * Insert to receive queue 220 220 */ 221 221 prodcons_produce(&loopip_rcv_queue, &rqe->link); 222 222 223 223 return EOK; 224 224 } … … 250 250 { 251 251 printf("%s: HelenOS loopback IP link provider\n", NAME); 252 252 253 253 errno_t rc = log_init(NAME); 254 254 if (rc != EOK) { … … 256 256 return rc; 257 257 } 258 258 259 259 rc = loopip_init(); 260 260 if (rc != EOK) { … … 262 262 return rc; 263 263 } 264 264 265 265 printf("%s: Accepting connections.\n", NAME); 266 266 task_retval(0); 267 267 async_manager(); 268 268 269 269 /* Not reached */ 270 270 return 0; -
uspace/srv/net/slip/slip.c
r3061bc1 ra35b458 129 129 { 130 130 log_msg(LOG_DEFAULT, LVL_DEBUG, "slip_send()"); 131 131 132 132 chardev_t *chardev = (chardev_t *) srv->arg; 133 133 uint8_t *data = sdu->data; 134 134 135 135 /* 136 136 * Strictly speaking, this is not prescribed by the RFC, but the RFC … … 139 139 */ 140 140 write_buffered(chardev, SLIP_END); 141 141 142 142 for (size_t i = 0; i < sdu->size; i++) { 143 143 switch (data[i]) { … … 155 155 } 156 156 } 157 157 158 158 write_buffered(chardev, SLIP_END); 159 159 write_flush(chardev); 160 160 161 161 return EOK; 162 162 } … … 165 165 { 166 166 log_msg(LOG_DEFAULT, LVL_DEBUG, "slip_send6()"); 167 167 168 168 return ENOTSUP; 169 169 } … … 272 272 break; 273 273 } 274 274 275 275 } 276 276
Note:
See TracChangeset
for help on using the changeset viewer.
