Changeset a17356fd in mainline
- Timestamp:
- 2013-07-12T15:33:20Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bb9b0c6
- Parents:
- f5f79cd
- Location:
- uspace
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/iplink.c
rf5f79cd ra17356fd 86 86 87 87 ipc_call_t answer; 88 aid_t req = async_send_0(exch, IPLINK_SEND, &answer); 89 90 int rc = async_data_write_start(exch, &sdu->src, sizeof(inet_addr_t)); 88 aid_t req = async_send_2(exch, IPLINK_SEND, (sysarg_t) sdu->src, 89 (sysarg_t) sdu->dest, &answer); 90 91 int rc = async_data_write_start(exch, sdu->data, sdu->size); 92 93 async_exchange_end(exch); 94 95 if (rc != EOK) { 96 async_forget(req); 97 return rc; 98 } 99 100 sysarg_t retval; 101 async_wait_for(req, &retval); 102 103 return (int) retval; 104 } 105 106 int iplink_send6(iplink_t *iplink, iplink_sdu6_t *sdu) 107 { 108 async_exch_t *exch = async_exchange_begin(iplink->sess); 109 110 ipc_call_t answer; 111 aid_t req = async_send_0(exch, IPLINK_SEND6, &answer); 112 113 int rc = async_data_write_start(exch, &sdu->dest, sizeof(addr48_t)); 91 114 if (rc != EOK) { 92 115 async_exchange_end(exch); … … 95 118 } 96 119 97 rc = async_data_write_start(exch, &sdu->dest, sizeof(inet_addr_t));98 if (rc != EOK) {99 async_exchange_end(exch);100 async_forget(req);101 return rc;102 }103 104 120 rc = async_data_write_start(exch, sdu->data, sdu->size); 105 121 … … 119 135 int iplink_get_mtu(iplink_t *iplink, size_t *rmtu) 120 136 { 137 async_exch_t *exch = async_exchange_begin(iplink->sess); 138 121 139 sysarg_t mtu; 122 async_exch_t *exch = async_exchange_begin(iplink->sess);123 124 140 int rc = async_req_0_1(exch, IPLINK_GET_MTU, &mtu); 125 async_exchange_end(exch); 126 141 142 async_exchange_end(exch); 143 127 144 if (rc != EOK) 128 145 return rc; 129 146 130 147 *rmtu = mtu; 131 148 return EOK; 149 } 150 151 int iplink_get_mac48(iplink_t *iplink, addr48_t *mac) 152 { 153 async_exch_t *exch = async_exchange_begin(iplink->sess); 154 155 ipc_call_t answer; 156 aid_t req = async_send_0(exch, IPLINK_GET_MAC48, &answer); 157 158 int rc = async_data_read_start(exch, mac, sizeof(addr48_t)); 159 160 loc_exchange_end(exch); 161 162 if (rc != EOK) { 163 async_forget(req); 164 return rc; 165 } 166 167 sysarg_t retval; 168 async_wait_for(req, &retval); 169 170 return (int) retval; 132 171 } 133 172 -
uspace/lib/c/generic/iplink_srv.c
rf5f79cd ra17356fd 50 50 } 51 51 52 static void iplink_get_mac48_srv(iplink_srv_t *srv, ipc_callid_t iid, 53 ipc_call_t *icall) 54 { 55 addr48_t mac; 56 int rc = srv->ops->get_mac48(srv, &mac); 57 if (rc != EOK) { 58 async_answer_0(iid, rc); 59 return; 60 } 61 62 ipc_callid_t callid; 63 size_t size; 64 if (!async_data_read_receive(&callid, &size)) { 65 async_answer_0(callid, EREFUSED); 66 async_answer_0(iid, EREFUSED); 67 return; 68 } 69 70 if (size != sizeof(addr48_t)) { 71 async_answer_0(callid, EINVAL); 72 async_answer_0(iid, EINVAL); 73 return; 74 } 75 76 rc = async_data_read_finalize(callid, &mac, size); 77 if (rc != EOK) 78 async_answer_0(callid, rc); 79 80 async_answer_0(iid, (sysarg_t) rc); 81 } 82 52 83 static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t iid, 53 84 ipc_call_t *icall) … … 111 142 iplink_sdu_t sdu; 112 143 144 sdu.src = IPC_GET_ARG1(*icall); 145 sdu.dest = IPC_GET_ARG2(*icall); 146 147 int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, 148 &sdu.size); 149 if (rc != EOK) { 150 async_answer_0(iid, rc); 151 return; 152 } 153 154 rc = srv->ops->send(srv, &sdu); 155 free(sdu.data); 156 async_answer_0(iid, rc); 157 } 158 159 static void iplink_send6_srv(iplink_srv_t *srv, ipc_callid_t iid, 160 ipc_call_t *icall) 161 { 162 iplink_sdu6_t sdu; 163 113 164 ipc_callid_t callid; 114 165 size_t size; … … 119 170 } 120 171 121 if (size != sizeof( inet_addr_t)) {172 if (size != sizeof(addr48_t)) { 122 173 async_answer_0(callid, EINVAL); 123 174 async_answer_0(iid, EINVAL); … … 125 176 } 126 177 127 int rc = async_data_write_finalize(callid, &sdu. src, size);178 int rc = async_data_write_finalize(callid, &sdu.dest, size); 128 179 if (rc != EOK) { 129 180 async_answer_0(callid, (sysarg_t) rc); … … 131 182 } 132 183 133 if (!async_data_write_receive(&callid, &size)) {134 async_answer_0(callid, EREFUSED);135 async_answer_0(iid, EREFUSED);136 return;137 }138 139 if (size != sizeof(inet_addr_t)) {140 async_answer_0(callid, EINVAL);141 async_answer_0(iid, EINVAL);142 return;143 }144 145 rc = async_data_write_finalize(callid, &sdu.dest, size);146 if (rc != EOK) {147 async_answer_0(callid, (sysarg_t) rc);148 async_answer_0(iid, (sysarg_t) rc);149 }150 151 184 rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, 152 185 &sdu.size); 153 if (rc != EOK) 154 return; 155 156 rc = srv->ops->send(srv, &sdu); 186 if (rc != EOK) { 187 async_answer_0(iid, rc); 188 return; 189 } 190 191 rc = srv->ops->send6(srv, &sdu); 157 192 free(sdu.data); 158 193 async_answer_0(iid, rc); … … 170 205 int iplink_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 171 206 { 172 iplink_srv_t *srv = (iplink_srv_t *) arg;207 iplink_srv_t *srv = (iplink_srv_t *) arg; 173 208 int rc; 174 209 … … 214 249 iplink_get_mtu_srv(srv, callid, &call); 215 250 break; 251 case IPLINK_GET_MAC48: 252 iplink_get_mac48_srv(srv, callid, &call); 253 break; 216 254 case IPLINK_SEND: 217 255 iplink_send_srv(srv, callid, &call); 256 break; 257 case IPLINK_SEND6: 258 iplink_send6_srv(srv, callid, &call); 218 259 break; 219 260 case IPLINK_ADDR_ADD: -
uspace/lib/c/include/inet/iplink.h
rf5f79cd ra17356fd 47 47 } iplink_t; 48 48 49 /** I nternetlink Service Data Unit */49 /** IPv4 link Service Data Unit */ 50 50 typedef struct { 51 51 /** Local source address */ 52 inet_addr_t src;52 addr32_t src; 53 53 /** Local destination address */ 54 inet_addr_t dest;54 addr32_t dest; 55 55 /** Serialized IP packet */ 56 56 void *data; … … 58 58 size_t size; 59 59 } iplink_sdu_t; 60 61 /** IPv6 link Service Data Unit */ 62 typedef struct { 63 /** Local MAC destination address */ 64 addr48_t dest; 65 /** Serialized IP packet */ 66 void *data; 67 /** Size of @c data in bytes */ 68 size_t size; 69 } iplink_sdu6_t; 60 70 61 71 /** Internet link receive Service Data Unit */ … … 74 84 extern void iplink_close(iplink_t *); 75 85 extern int iplink_send(iplink_t *, iplink_sdu_t *); 86 extern int iplink_send6(iplink_t *, iplink_sdu6_t *); 76 87 extern int iplink_addr_add(iplink_t *, inet_addr_t *); 77 88 extern int iplink_addr_remove(iplink_t *, inet_addr_t *); 78 89 extern int iplink_get_mtu(iplink_t *, size_t *); 90 extern int iplink_get_mac48(iplink_t *, addr48_t *); 79 91 80 92 #endif -
uspace/lib/c/include/inet/iplink_srv.h
rf5f79cd ra17356fd 57 57 int (*close)(iplink_srv_t *); 58 58 int (*send)(iplink_srv_t *, iplink_sdu_t *); 59 int (*send6)(iplink_srv_t *, iplink_sdu6_t *); 59 60 int (*get_mtu)(iplink_srv_t *, size_t *); 61 int (*get_mac48)(iplink_srv_t *, addr48_t *); 60 62 int (*addr_add)(iplink_srv_t *, inet_addr_t *); 61 63 int (*addr_remove)(iplink_srv_t *, inet_addr_t *); -
uspace/lib/c/include/ipc/iplink.h
rf5f79cd ra17356fd 40 40 typedef enum { 41 41 IPLINK_GET_MTU = IPC_FIRST_USER_METHOD, 42 IPLINK_GET_MAC48, 42 43 IPLINK_SEND, 44 IPLINK_SEND6, 43 45 IPLINK_ADDR_ADD, 44 46 IPLINK_ADDR_REMOVE -
uspace/srv/net/ethip/ethip.c
rf5f79cd ra17356fd 56 56 static int ethip_close(iplink_srv_t *srv); 57 57 static int ethip_send(iplink_srv_t *srv, iplink_sdu_t *sdu); 58 static int ethip_send6(iplink_srv_t *srv, iplink_sdu6_t *sdu); 58 59 static int ethip_get_mtu(iplink_srv_t *srv, size_t *mtu); 60 static int ethip_get_mac48(iplink_srv_t *srv, addr48_t *mac); 59 61 static int ethip_addr_add(iplink_srv_t *srv, inet_addr_t *addr); 60 62 static int ethip_addr_remove(iplink_srv_t *srv, inet_addr_t *addr); … … 66 68 .close = ethip_close, 67 69 .send = ethip_send, 70 .send6 = ethip_send6, 68 71 .get_mtu = ethip_get_mtu, 72 .get_mac48 = ethip_get_mac48, 69 73 .addr_add = ethip_addr_add, 70 74 .addr_remove = ethip_addr_remove … … 169 173 170 174 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 171 172 addr32_t src_v4;173 addr128_t src_v6;174 uint16_t src_af = inet_addr_get(&sdu->src, &src_v4, &src_v6);175 176 addr32_t dest_v4;177 addr128_t dest_v6;178 uint16_t dest_af = inet_addr_get(&sdu->dest, &dest_v4, &dest_v6);179 180 if (src_af != dest_af)181 return EINVAL;182 183 int rc;184 175 eth_frame_t frame; 185 176 186 switch (src_af) { 187 case AF_INET: 188 rc = arp_translate(nic, src_v4, dest_v4, frame.dest); 189 if (rc != EOK) { 190 log_msg(LOG_DEFAULT, LVL_WARN, "Failed to look up IPv4 address 0x%" 191 PRIx32, dest_v4); 192 return rc; 193 } 194 195 addr48(nic->mac_addr, frame.src); 196 frame.etype_len = ETYPE_IP; 197 frame.data = sdu->data; 198 frame.size = sdu->size; 199 200 break; 201 case AF_INET6: 202 // FIXME TODO 203 return ENOTSUP; 204 default: 205 return EINVAL; 206 } 177 int rc = arp_translate(nic, sdu->src, sdu->dest, frame.dest); 178 if (rc != EOK) { 179 log_msg(LOG_DEFAULT, LVL_WARN, "Failed to look up IPv4 address 0x%" 180 PRIx32, sdu->dest); 181 return rc; 182 } 183 184 addr48(nic->mac_addr, frame.src); 185 frame.etype_len = ETYPE_IP; 186 frame.data = sdu->data; 187 frame.size = sdu->size; 207 188 208 189 void *data; 209 190 size_t size; 210 191 rc = eth_pdu_encode(&frame, &data, &size); 192 if (rc != EOK) 193 return rc; 194 195 rc = ethip_nic_send(nic, data, size); 196 free(data); 197 198 return rc; 199 } 200 201 static int ethip_send6(iplink_srv_t *srv, iplink_sdu6_t *sdu) 202 { 203 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_send6()"); 204 205 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 206 eth_frame_t frame; 207 208 addr48(sdu->dest, frame.dest); 209 addr48(nic->mac_addr, frame.src); 210 frame.etype_len = ETYPE_IPV6; 211 frame.data = sdu->data; 212 frame.size = sdu->size; 213 214 void *data; 215 size_t size; 216 int rc = eth_pdu_encode(&frame, &data, &size); 211 217 if (rc != EOK) 212 218 return rc; … … 268 274 } 269 275 276 static int ethip_get_mac48(iplink_srv_t *srv, addr48_t *mac) 277 { 278 log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_get_mac48()"); 279 280 ethip_nic_t *nic = (ethip_nic_t *) srv->arg; 281 addr48(nic->mac_addr, *mac); 282 283 return EOK; 284 } 285 270 286 static int ethip_addr_add(iplink_srv_t *srv, inet_addr_t *addr) 271 287 { -
uspace/srv/net/inetsrv/Makefile
rf5f79cd ra17356fd 39 39 inetping.c \ 40 40 inetping6.c \ 41 ndp.c \ 42 ntrans.c \ 41 43 pdu.c \ 42 44 reass.c \ -
uspace/srv/net/inetsrv/addrobj.c
rf5f79cd ra17356fd 42 42 #include <stdlib.h> 43 43 #include <str.h> 44 #include <net/socket_codes.h> 44 45 #include "addrobj.h" 45 46 #include "inetsrv.h" 46 47 #include "inet_link.h" 48 #include "ndp.h" 47 49 48 50 static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *, inet_link_t *); … … 214 216 inet_naddr_addr(&addr->naddr, &lsrc_addr); 215 217 216 return inet_link_send_dgram(addr->ilink, &lsrc_addr, ldest, dgram, 217 proto, ttl, df); 218 addr32_t lsrc_v4; 219 addr128_t lsrc_v6; 220 uint16_t lsrc_af = inet_addr_get(&lsrc_addr, &lsrc_v4, &lsrc_v6); 221 222 addr32_t ldest_v4; 223 addr128_t ldest_v6; 224 uint16_t ldest_af = inet_addr_get(ldest, &ldest_v4, &ldest_v6); 225 226 if (lsrc_af != ldest_af) 227 return EINVAL; 228 229 int rc; 230 addr48_t ldest_mac; 231 232 switch (ldest_af) { 233 case AF_INET: 234 return inet_link_send_dgram(addr->ilink, lsrc_v4, ldest_v4, 235 dgram, proto, ttl, df); 236 case AF_INET6: 237 /* 238 * Translate local destination IPv6 address. 239 */ 240 rc = ndp_translate(lsrc_v6, ldest_v6, ldest_mac, addr->ilink); 241 if (rc != EOK) 242 return rc; 243 244 return inet_link_send_dgram6(addr->ilink, ldest_mac, dgram, 245 proto, ttl, df); 246 } 247 248 return ENOTSUP; 218 249 } 219 250 -
uspace/srv/net/inetsrv/icmpv6.c
rf5f79cd ra17356fd 47 47 #include "pdu.h" 48 48 49 static int ndp_received(inet_dgram_t *dgram)50 {51 // FIXME TODO52 return ENOTSUP;53 }54 55 49 static int icmpv6_recv_echo_request(inet_dgram_t *dgram) 56 50 { -
uspace/srv/net/inetsrv/icmpv6_std.h
rf5f79cd ra17356fd 47 47 #define INET6_HOP_LIMIT_MAX 255 48 48 49 #define NDP_FLAG_ROUTER 0x80 50 #define NDP_FLAG_OVERRIDE 0x40 51 #define NDP_FLAG_SOLICITED 0x20 52 49 53 /** ICMPv6 message type */ 50 54 enum icmpv6_type { … … 83 87 uint8_t flags; 84 88 /** Reserved bytes */ 85 uint8_t reserved 89 uint8_t reserved[3]; 86 90 } ndp; 87 91 } un; … … 91 95 typedef struct { 92 96 /** Source IPv6 address */ 93 uint8_t src_addr 97 uint8_t src_addr[16]; 94 98 /** Target IPv6 address */ 95 uint8_t dest_addr 99 uint8_t dest_addr[16]; 96 100 /** ICMPv6 length */ 97 101 uint32_t length; 98 102 /** Zeroes */ 99 uint8_t zeroes 103 uint8_t zeroes[3]; 100 104 /** Next header */ 101 105 uint8_t next; … … 105 109 typedef struct { 106 110 /** Target IPv6 address */ 107 uint8_t target_address 111 uint8_t target_address[16]; 108 112 /** Option code */ 109 113 uint8_t option; … … 111 115 uint8_t length; 112 116 /** MAC address */ 113 uint8_t mac 117 uint8_t mac[6]; 114 118 } ndp_message_t; 115 119 … … 131 135 uint32_t reserved; 132 136 /** Prefix */ 133 uint8_t prefix 137 uint8_t prefix[16]; 134 138 } ndp_prefix_t; 135 139 -
uspace/srv/net/inetsrv/inet_link.c
rf5f79cd ra17356fd 201 201 goto error; 202 202 } 203 204 /* 205 * Get the MAC address of the link. If the link has a MAC 206 * address, we assume that it supports NDP. 207 */ 208 rc = iplink_get_mac48(ilink->iplink, &ilink->mac); 209 ilink->mac_valid = (rc == EOK); 203 210 204 211 log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name); … … 298 305 } 299 306 300 /** Send datagram over Internet link */ 301 int inet_link_send_dgram(inet_link_t *ilink, inet_addr_t *lsrc, 302 inet_addr_t *ldest, inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df) 303 { 307 /** Send IPv4 datagram over Internet link */ 308 int inet_link_send_dgram(inet_link_t *ilink, addr32_t lsrc, addr32_t ldest, 309 inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df) 310 { 311 addr32_t src_v4; 312 uint16_t src_af = inet_addr_get(&dgram->src, &src_v4, NULL); 313 if (src_af != AF_INET) 314 return EINVAL; 315 316 addr32_t dest_v4; 317 uint16_t dest_af = inet_addr_get(&dgram->dest, &dest_v4, NULL); 318 if (dest_af != AF_INET) 319 return EINVAL; 320 304 321 /* 305 322 * Fill packet structure. Fragmentation is performed by 306 323 * inet_pdu_encode(). 307 324 */ 325 326 iplink_sdu_t sdu; 327 328 sdu.src = lsrc; 329 sdu.dest = ldest; 308 330 309 331 inet_packet_t packet; … … 318 340 packet.size = dgram->size; 319 341 320 iplink_sdu_t sdu;321 342 size_t offs = 0; 322 343 int rc; 323 324 sdu.src = *lsrc;325 sdu.dest = *ldest;326 344 327 345 do { 328 346 /* Encode one fragment */ 347 329 348 size_t roffs; 330 rc = inet_pdu_encode(&packet, offs, ilink->def_mtu, &sdu.data,331 &sdu. size, &roffs);349 rc = inet_pdu_encode(&packet, src_v4, dest_v4, offs, ilink->def_mtu, 350 &sdu.data, &sdu.size, &roffs); 332 351 if (rc != EOK) 333 352 return rc; … … 335 354 /* Send the PDU */ 336 355 rc = iplink_send(ilink->iplink, &sdu); 356 337 357 free(sdu.data); 338 358 offs = roffs; 359 } while (offs < packet.size); 360 361 return rc; 362 } 363 364 /** Send IPv6 datagram over Internet link */ 365 int inet_link_send_dgram6(inet_link_t *ilink, addr48_t ldest, 366 inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df) 367 { 368 addr128_t src_v6; 369 uint16_t src_af = inet_addr_get(&dgram->src, NULL, &src_v6); 370 if (src_af != AF_INET6) 371 return EINVAL; 372 373 addr128_t dest_v6; 374 uint16_t dest_af = inet_addr_get(&dgram->dest, NULL, &dest_v6); 375 if (dest_af != AF_INET6) 376 return EINVAL; 377 378 iplink_sdu6_t sdu6; 379 addr48(ldest, sdu6.dest); 380 381 /* 382 * Fill packet structure. Fragmentation is performed by 383 * inet_pdu_encode6(). 384 */ 385 386 inet_packet_t packet; 387 388 packet.src = dgram->src; 389 packet.dest = dgram->dest; 390 packet.tos = dgram->tos; 391 packet.proto = proto; 392 packet.ttl = ttl; 393 packet.df = df; 394 packet.data = dgram->data; 395 packet.size = dgram->size; 396 397 int rc; 398 size_t offs = 0; 399 400 do { 401 /* Encode one fragment */ 402 403 size_t roffs; 404 rc = inet_pdu_encode6(&packet, src_v6, dest_v6, offs, ilink->def_mtu, 405 &sdu6.data, &sdu6.size, &roffs); 406 if (rc != EOK) 407 return rc; 408 409 /* Send the PDU */ 410 rc = iplink_send6(ilink->iplink, &sdu6); 411 412 free(sdu6.data); 339 413 offs = roffs; 340 414 } while (offs < packet.size); -
uspace/srv/net/inetsrv/inet_link.h
rf5f79cd ra17356fd 42 42 43 43 extern int inet_link_discovery_start(void); 44 extern int inet_link_send_dgram(inet_link_t *, inet_addr_t *, 45 inet_addr_t *, inet_dgram_t *, uint8_t, uint8_t, int); 44 extern int inet_link_send_dgram(inet_link_t *, addr32_t, 45 addr32_t, inet_dgram_t *, uint8_t, uint8_t, int); 46 extern int inet_link_send_dgram6(inet_link_t *, addr48_t, inet_dgram_t *, 47 uint8_t, uint8_t, int); 46 48 extern inet_link_t *inet_link_get_by_id(sysarg_t); 47 49 -
uspace/srv/net/inetsrv/inetping6.c
rf5f79cd ra17356fd 109 109 aid_t req = async_send_1(exch, INETPING6_EV_RECV, sdu->seq_no, &answer); 110 110 111 int rc = async_data_write_start(exch, sdu->src, 16);111 int rc = async_data_write_start(exch, sdu->src, sizeof(addr128_t)); 112 112 if (rc != EOK) { 113 113 async_exchange_end(exch); … … 116 116 } 117 117 118 rc = async_data_write_start(exch, sdu->dest, 16);118 rc = async_data_write_start(exch, sdu->dest, sizeof(addr128_t)); 119 119 if (rc != EOK) { 120 120 async_exchange_end(exch); -
uspace/srv/net/inetsrv/inetsrv.h
rf5f79cd ra17356fd 141 141 iplink_t *iplink; 142 142 size_t def_mtu; 143 addr48_t mac; 144 bool mac_valid; 143 145 } inet_link_t; 144 146 -
uspace/srv/net/inetsrv/pdu.c
rf5f79cd ra17356fd 88 88 } 89 89 90 /** Encode I nternetPDU.90 /** Encode IPv4 PDU. 91 91 * 92 92 * Encode internet packet into PDU (serialized form). Will encode a … … 96 96 * be set in the header, otherwise the offset will equal @a packet->size. 97 97 * 98 * @param packet Packet to encode 99 * @param offs Offset into packet payload (in bytes) 100 * @param mtu MTU (Maximum Transmission Unit) in bytes 101 * @param rdata Place to store pointer to allocated data buffer 102 * @param rsize Place to store size of allocated data buffer 103 * @param roffs Place to store offset of remaning data 104 */ 105 int inet_pdu_encode(inet_packet_t *packet, size_t offs, size_t mtu, 106 void **rdata, size_t *rsize, size_t *roffs) 107 { 108 addr32_t src_v4; 109 addr128_t src_v6; 110 uint16_t src_af = inet_addr_get(&packet->src, &src_v4, &src_v6); 111 112 addr32_t dest_v4; 113 addr128_t dest_v6; 114 uint16_t dest_af = inet_addr_get(&packet->dest, &dest_v4, &dest_v6); 115 116 if (src_af != dest_af) 117 return EINVAL; 118 98 * @param packet Packet to encode 99 * @param src Source address 100 * @param dest Destination address 101 * @param offs Offset into packet payload (in bytes) 102 * @param mtu MTU (Maximum Transmission Unit) in bytes 103 * @param rdata Place to store pointer to allocated data buffer 104 * @param rsize Place to store size of allocated data buffer 105 * @param roffs Place to store offset of remaning data 106 * 107 */ 108 int inet_pdu_encode(inet_packet_t *packet, addr32_t src, addr32_t dest, 109 size_t offs, size_t mtu, void **rdata, size_t *rsize, size_t *roffs) 110 { 119 111 /* Upper bound for fragment offset field */ 120 112 size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l); … … 124 116 return ELIMIT; 125 117 126 size_t hdr_size; 127 128 switch (src_af) { 129 case AF_INET: 130 hdr_size = sizeof(ip_header_t); 131 break; 132 case AF_INET6: 133 hdr_size = sizeof(ip6_header_t); 134 break; 135 default: 136 assert(false); 137 } 118 size_t hdr_size = sizeof(ip_header_t); 138 119 139 120 size_t data_offs = ROUND_UP(hdr_size, 4); … … 177 158 178 159 /* Encode header fields */ 179 ip_header_t *hdr; 180 ip6_header_t *hdr6; 181 182 switch (src_af) { 183 case AF_INET: 184 hdr = (ip_header_t *) data; 185 186 hdr->ver_ihl = 187 (4 << VI_VERSION_l) | (hdr_size / sizeof(uint32_t)); 188 hdr->tos = packet->tos; 189 hdr->tot_len = host2uint16_t_be(size); 190 hdr->id = host2uint16_t_be(ident); 191 hdr->flags_foff = host2uint16_t_be(flags_foff); 192 hdr->ttl = packet->ttl; 193 hdr->proto = packet->proto; 194 hdr->chksum = 0; 195 hdr->src_addr = host2uint32_t_be(src_v4); 196 hdr->dest_addr = host2uint32_t_be(dest_v4); 197 198 /* Compute checksum */ 199 uint16_t chksum = inet_checksum_calc(INET_CHECKSUM_INIT, 200 (void *) hdr, hdr_size); 201 hdr->chksum = host2uint16_t_be(chksum); 202 203 break; 204 case AF_INET6: 205 // TODO FIXME: fragmentation 206 207 hdr6 = (ip6_header_t *) data; 208 209 hdr6->ver_tc = (6 << (VI_VERSION_l)); 210 memset(hdr6->tc_fl, 0, 3); 211 hdr6->payload_len = host2uint16_t_be(packet->size); 212 hdr6->next = packet->proto; 213 hdr6->hop_limit = packet->ttl; 214 215 host2addr128_t_be(src_v6, hdr6->src_addr); 216 host2addr128_t_be(dest_v6, hdr6->dest_addr); 217 218 break; 219 default: 220 assert(false); 221 } 160 ip_header_t *hdr = (ip_header_t *) data; 161 162 hdr->ver_ihl = 163 (4 << VI_VERSION_l) | (hdr_size / sizeof(uint32_t)); 164 hdr->tos = packet->tos; 165 hdr->tot_len = host2uint16_t_be(size); 166 hdr->id = host2uint16_t_be(ident); 167 hdr->flags_foff = host2uint16_t_be(flags_foff); 168 hdr->ttl = packet->ttl; 169 hdr->proto = packet->proto; 170 hdr->chksum = 0; 171 hdr->src_addr = host2uint32_t_be(src); 172 hdr->dest_addr = host2uint32_t_be(dest); 173 174 /* Compute checksum */ 175 uint16_t chksum = inet_checksum_calc(INET_CHECKSUM_INIT, 176 (void *) hdr, hdr_size); 177 hdr->chksum = host2uint16_t_be(chksum); 178 179 /* Copy payload */ 180 memcpy((uint8_t *) data + data_offs, packet->data + offs, xfer_size); 181 182 *rdata = data; 183 *rsize = size; 184 *roffs = rem_offs; 185 186 return EOK; 187 } 188 189 /** Encode IPv6 PDU. 190 * 191 * Encode internet packet into PDU (serialized form). Will encode a 192 * fragment of the payload starting at offset @a offs. The resulting 193 * PDU will have at most @a mtu bytes. @a *roffs will be set to the offset 194 * of remaining payload. If some data is remaining, the MF flag will 195 * be set in the header, otherwise the offset will equal @a packet->size. 196 * 197 * @param packet Packet to encode 198 * @param src Source address 199 * @param dest Destination address 200 * @param offs Offset into packet payload (in bytes) 201 * @param mtu MTU (Maximum Transmission Unit) in bytes 202 * @param rdata Place to store pointer to allocated data buffer 203 * @param rsize Place to store size of allocated data buffer 204 * @param roffs Place to store offset of remaning data 205 * 206 */ 207 int inet_pdu_encode6(inet_packet_t *packet, addr128_t src, addr128_t dest, 208 size_t offs, size_t mtu, void **rdata, size_t *rsize, size_t *roffs) 209 { 210 /* Upper bound for fragment offset field */ 211 size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l); 212 213 /* Verify that total size of datagram is within reasonable bounds */ 214 if (offs + packet->size > FRAG_OFFS_UNIT * fragoff_limit) 215 return ELIMIT; 216 217 size_t hdr_size = sizeof(ip6_header_t); 218 219 size_t data_offs = ROUND_UP(hdr_size, 4); 220 221 assert(offs % FRAG_OFFS_UNIT == 0); 222 assert(offs / FRAG_OFFS_UNIT < fragoff_limit); 223 224 #if 0 225 // FIXME TODO fragmentation 226 227 /* Value for the fragment offset field */ 228 uint16_t foff = offs / FRAG_OFFS_UNIT; 229 #endif 230 231 if (hdr_size >= mtu) 232 return EINVAL; 233 234 /* Amount of space in the PDU available for payload */ 235 size_t spc_avail = mtu - hdr_size; 236 spc_avail -= (spc_avail % FRAG_OFFS_UNIT); 237 238 /* Amount of data (payload) to transfer */ 239 size_t xfer_size = min(packet->size - offs, spc_avail); 240 241 /* Total PDU size */ 242 size_t size = hdr_size + xfer_size; 243 244 /* Offset of remaining payload */ 245 size_t rem_offs = offs + xfer_size; 246 247 #if 0 248 // FIXME TODO fragmentation 249 250 /* Flags */ 251 uint16_t flags_foff = 252 (packet->df ? BIT_V(uint16_t, FF_FLAG_DF) : 0) + 253 (rem_offs < packet->size ? BIT_V(uint16_t, FF_FLAG_MF) : 0) + 254 (foff << FF_FRAGOFF_l); 255 #endif 256 257 void *data = calloc(size, 1); 258 if (data == NULL) 259 return ENOMEM; 260 261 #if 0 262 // FIXME TODO fragmentation 263 264 /* Allocate identifier */ 265 fibril_mutex_lock(&ip_ident_lock); 266 uint16_t ident = ++ip_ident; 267 fibril_mutex_unlock(&ip_ident_lock); 268 #endif 269 270 /* Encode header fields */ 271 ip6_header_t *hdr6 = (ip6_header_t *) data; 272 273 hdr6->ver_tc = (6 << (VI_VERSION_l)); 274 memset(hdr6->tc_fl, 0, 3); 275 hdr6->payload_len = host2uint16_t_be(packet->size); 276 hdr6->next = packet->proto; 277 hdr6->hop_limit = packet->ttl; 278 279 host2addr128_t_be(src, hdr6->src_addr); 280 host2addr128_t_be(dest, hdr6->dest_addr); 222 281 223 282 /* Copy payload */ … … 257 316 if (tot_len > size) { 258 317 log_msg(LOG_DEFAULT, LVL_DEBUG, "Total Length = %zu > PDU size = %zu", 259 318 tot_len, size); 260 319 return EINVAL; 261 320 } … … 296 355 int inet_pdu_decode6(void *data, size_t size, inet_packet_t *packet) 297 356 { 298 // FIXME TODO 299 return ENOTSUP; 357 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_pdu_decode6()"); 358 359 if (size < sizeof(ip6_header_t)) { 360 log_msg(LOG_DEFAULT, LVL_DEBUG, "PDU too short (%zu)", size); 361 return EINVAL; 362 } 363 364 ip6_header_t *hdr6 = (ip6_header_t *) data; 365 366 uint8_t version = BIT_RANGE_EXTRACT(uint8_t, VI_VERSION_h, 367 VI_VERSION_l, hdr6->ver_tc); 368 if (version != 6) { 369 log_msg(LOG_DEFAULT, LVL_DEBUG, "Version (%d) != 6", version); 370 return EINVAL; 371 } 372 373 size_t payload_len = uint16_t_be2host(hdr6->payload_len); 374 if (payload_len + sizeof(ip6_header_t) > size) { 375 log_msg(LOG_DEFAULT, LVL_DEBUG, "Total Length = %zu > PDU size = %zu", 376 payload_len + sizeof(ip6_header_t), size); 377 return EINVAL; 378 } 379 380 #if 0 381 // FIXME TODO fragmentation 382 383 uint16_t ident = uint16_t_be2host(hdr->id); 384 uint16_t flags_foff = uint16_t_be2host(hdr->flags_foff); 385 uint16_t foff = BIT_RANGE_EXTRACT(uint16_t, FF_FRAGOFF_h, FF_FRAGOFF_l, 386 flags_foff); 387 #endif 388 389 /* XXX Checksum */ 390 391 addr128_t src; 392 addr128_t dest; 393 394 addr128_t_be2host(hdr6->src_addr, src); 395 inet_addr_set6(src, &packet->src); 396 397 addr128_t_be2host(hdr6->dest_addr, dest); 398 inet_addr_set6(dest, &packet->dest); 399 400 packet->tos = 0; 401 packet->proto = hdr6->next; 402 packet->ttl = hdr6->hop_limit; 403 404 #if 0 405 // FIXME TODO fragmentation 406 407 packet->ident = ident; 408 packet->df = (flags_foff & BIT_V(uint16_t, FF_FLAG_DF)) != 0; 409 packet->mf = (flags_foff & BIT_V(uint16_t, FF_FLAG_MF)) != 0; 410 packet->offs = foff * FRAG_OFFS_UNIT; 411 412 /* XXX IP options */ 413 size_t data_offs = sizeof(uint32_t) * 414 BIT_RANGE_EXTRACT(uint8_t, VI_IHL_h, VI_IHL_l, hdr->ver_ihl); 415 #endif 416 417 packet->ident = 0; 418 packet->df = 0; 419 packet->mf = 0; 420 packet->offs = 0; 421 422 packet->size = payload_len; 423 packet->data = calloc(packet->size, 1); 424 if (packet->data == NULL) { 425 log_msg(LOG_DEFAULT, LVL_WARN, "Out of memory."); 426 return ENOMEM; 427 } 428 429 memcpy(packet->data, (uint8_t *) data + sizeof(ip6_header_t), packet->size); 430 431 return EOK; 432 } 433 434 int ndp_pdu_encode(ndp_packet_t *ndp, inet_dgram_t *dgram) 435 { 436 inet_addr_set6(ndp->sender_proto_addr, &dgram->src); 437 inet_addr_set6(ndp->target_proto_addr, &dgram->dest); 438 dgram->tos = 0; 439 dgram->size = sizeof(icmpv6_message_t) + sizeof(ndp_message_t); 440 441 dgram->data = calloc(1, dgram->size); 442 if (dgram->data == NULL) 443 return ENOMEM; 444 445 icmpv6_message_t *icmpv6 = (icmpv6_message_t *) dgram->data; 446 447 icmpv6->type = ndp->opcode; 448 icmpv6->code = 0; 449 memset(icmpv6->un.ndp.reserved, 0, 3); 450 451 ndp_message_t *message = (ndp_message_t *) (icmpv6 + 1); 452 453 if (ndp->opcode == ICMPV6_NEIGHBOUR_SOLICITATION) { 454 host2addr128_t_be(ndp->solicited_ip, message->target_address); 455 message->option = 1; 456 icmpv6->un.ndp.flags = 0; 457 } else { 458 host2addr128_t_be(ndp->sender_proto_addr, message->target_address); 459 message->option = 2; 460 icmpv6->un.ndp.flags = NDP_FLAG_OVERRIDE | NDP_FLAG_SOLICITED; 461 } 462 463 message->length = 1; 464 addr48(ndp->sender_hw_addr, message->mac); 465 466 icmpv6_pseudo_header phdr; 467 468 host2addr128_t_be(ndp->sender_proto_addr, phdr.src_addr); 469 host2addr128_t_be(ndp->target_proto_addr, phdr.dest_addr); 470 phdr.length = host2uint32_t_be(dgram->size); 471 memset(phdr.zeroes, 0, 3); 472 phdr.next = IP_PROTO_ICMPV6; 473 474 uint16_t cs_phdr = 475 inet_checksum_calc(INET_CHECKSUM_INIT, &phdr, 476 sizeof(icmpv6_pseudo_header)); 477 478 uint16_t cs_all = inet_checksum_calc(cs_phdr, dgram->data, 479 dgram->size); 480 481 icmpv6->checksum = host2uint16_t_be(cs_all); 482 483 return EOK; 484 } 485 486 int ndp_pdu_decode(inet_dgram_t *dgram, ndp_packet_t *ndp) 487 { 488 uint16_t src_af = inet_addr_get(&dgram->src, NULL, 489 &ndp->sender_proto_addr); 490 if (src_af != AF_INET6) 491 return EINVAL; 492 493 if (dgram->size < sizeof(icmpv6_message_t) + sizeof(ndp_message_t)) 494 return EINVAL; 495 496 icmpv6_message_t *icmpv6 = (icmpv6_message_t *) dgram->data; 497 498 ndp->opcode = icmpv6->type; 499 500 ndp_message_t *message = (ndp_message_t *) (icmpv6 + 1); 501 502 addr128_t_be2host(message->target_address, ndp->target_proto_addr); 503 addr48(message->mac, ndp->sender_hw_addr); 504 505 return EOK; 300 506 } 301 507 -
uspace/srv/net/inetsrv/pdu.h
rf5f79cd ra17356fd 40 40 #include <sys/types.h> 41 41 #include "inetsrv.h" 42 #include "ndp.h" 42 43 43 44 #define INET_CHECKSUM_INIT 0xffff … … 45 46 extern uint16_t inet_checksum_calc(uint16_t, void *, size_t); 46 47 47 extern int inet_pdu_encode(inet_packet_t *, size_t, size_t, void **, 48 size_t *, size_t *); 48 extern int inet_pdu_encode(inet_packet_t *, addr32_t, addr32_t, size_t, size_t, 49 void **, size_t *, size_t *); 50 extern int inet_pdu_encode6(inet_packet_t *, addr128_t, addr128_t, size_t, 51 size_t, void **, size_t *, size_t *); 49 52 extern int inet_pdu_decode(void *, size_t, inet_packet_t *); 50 53 extern int inet_pdu_decode6(void *, size_t, inet_packet_t *); 54 55 extern int ndp_pdu_decode(inet_dgram_t *, ndp_packet_t *); 56 extern int ndp_pdu_encode(ndp_packet_t *, inet_dgram_t *); 51 57 52 58 #endif -
uspace/srv/net/loopip/loopip.c
rf5f79cd ra17356fd 40 40 #include <inet/iplink_srv.h> 41 41 #include <inet/addr.h> 42 #include <net/socket_codes.h> 42 43 #include <io/log.h> 43 44 #include <loc.h> … … 50 51 static int loopip_close(iplink_srv_t *srv); 51 52 static int loopip_send(iplink_srv_t *srv, iplink_sdu_t *sdu); 53 static int loopip_send6(iplink_srv_t *srv, iplink_sdu6_t *sdu); 52 54 static int loopip_get_mtu(iplink_srv_t *srv, size_t *mtu); 55 static int loopip_get_mac48(iplink_srv_t *srv, addr48_t *mac); 53 56 static int loopip_addr_add(iplink_srv_t *srv, inet_addr_t *addr); 54 57 static int loopip_addr_remove(iplink_srv_t *srv, inet_addr_t *addr); … … 60 63 .close = loopip_close, 61 64 .send = loopip_send, 65 .send6 = loopip_send6, 62 66 .get_mtu = loopip_get_mtu, 67 .get_mac48 = loopip_get_mac48, 63 68 .addr_add = loopip_addr_add, 64 69 .addr_remove = loopip_addr_remove … … 162 167 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_send()"); 163 168 164 addr32_t src_v4;165 addr128_t src_v6;166 uint16_t src_af = inet_addr_get(&sdu->src, &src_v4, &src_v6);167 168 addr32_t dest_v4;169 addr128_t dest_v6;170 uint16_t dest_af = inet_addr_get(&sdu->dest, &dest_v4, &dest_v6);171 172 if (src_af != dest_af)173 return EINVAL;174 175 169 rqueue_entry_t *rqe = calloc(1, sizeof(rqueue_entry_t)); 176 170 if (rqe == NULL) … … 180 174 * Clone SDU 181 175 */ 182 rqe->af = src_af;176 rqe->af = AF_INET; 183 177 rqe->sdu.data = malloc(sdu->size); 184 178 if (rqe->sdu.data == NULL) { … … 198 192 } 199 193 194 static int loopip_send6(iplink_srv_t *srv, iplink_sdu6_t *sdu) 195 { 196 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip6_send()"); 197 198 rqueue_entry_t *rqe = calloc(1, sizeof(rqueue_entry_t)); 199 if (rqe == NULL) 200 return ENOMEM; 201 202 /* 203 * Clone SDU 204 */ 205 rqe->af = AF_INET6; 206 rqe->sdu.data = malloc(sdu->size); 207 if (rqe->sdu.data == NULL) { 208 free(rqe); 209 return ENOMEM; 210 } 211 212 memcpy(rqe->sdu.data, sdu->data, sdu->size); 213 rqe->sdu.size = sdu->size; 214 215 /* 216 * Insert to receive queue 217 */ 218 prodcons_produce(&loopip_rcv_queue, &rqe->link); 219 220 return EOK; 221 } 222 200 223 static int loopip_get_mtu(iplink_srv_t *srv, size_t *mtu) 201 224 { … … 203 226 *mtu = 1500; 204 227 return EOK; 228 } 229 230 static int loopip_get_mac48(iplink_srv_t *src, addr48_t *mac) 231 { 232 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_get_mac48()"); 233 return ENOTSUP; 205 234 } 206 235 -
uspace/srv/net/slip/slip.c
rf5f79cd ra17356fd 58 58 static int slip_close(iplink_srv_t *); 59 59 static int slip_send(iplink_srv_t *, iplink_sdu_t *); 60 static int slip_send6(iplink_srv_t *, iplink_sdu6_t *); 60 61 static int slip_get_mtu(iplink_srv_t *, size_t *); 62 static int slip_get_mac48(iplink_srv_t *, addr48_t *); 61 63 static int slip_addr_add(iplink_srv_t *, inet_addr_t *); 62 64 static int slip_addr_remove(iplink_srv_t *, inet_addr_t *); … … 68 70 .close = slip_close, 69 71 .send = slip_send, 72 .send6 = slip_send6, 70 73 .get_mtu = slip_get_mtu, 74 .get_mac48 = slip_get_mac48, 71 75 .addr_add = slip_addr_add, 72 76 .addr_remove = slip_addr_remove … … 122 126 int slip_send(iplink_srv_t *srv, iplink_sdu_t *sdu) 123 127 { 128 log_msg(LOG_DEFAULT, LVL_DEBUG, "slip_send()"); 129 124 130 async_sess_t *sess = (async_sess_t *) srv->arg; 125 131 uint8_t *data = sdu->data; 126 unsigned i; 127 128 log_msg(LOG_DEFAULT, LVL_DEBUG, "slip_send()"); 129 132 130 133 /* 131 132 133 134 134 * Strictly speaking, this is not prescribed by the RFC, but the RFC 135 * suggests to start with sending a SLIP_END byte as a synchronization 136 * measure for dealing with previous possible noise on the line. 137 */ 135 138 write_buffered(sess, SLIP_END); 136 137 for ( i = 0; i < sdu->size; i++) {139 140 for (size_t i = 0; i < sdu->size; i++) { 138 141 switch (data[i]) { 139 142 case SLIP_END: … … 150 153 } 151 154 } 155 152 156 write_buffered(sess, SLIP_END); 153 157 write_flush(sess); 154 155 return EOK; 158 159 return EOK; 160 } 161 162 int slip_send6(iplink_srv_t *srv, iplink_sdu6_t *sdu) 163 { 164 log_msg(LOG_DEFAULT, LVL_DEBUG, "slip_send6()"); 165 166 return ENOTSUP; 156 167 } 157 168 … … 161 172 *mtu = SLIP_MTU; 162 173 return EOK; 174 } 175 176 int slip_get_mac48(iplink_srv_t *src, addr48_t *mac) 177 { 178 log_msg(LOG_DEFAULT, LVL_DEBUG, "slip_get_mac48()"); 179 return ENOTSUP; 163 180 } 164 181
Note:
See TracChangeset
for help on using the changeset viewer.