Changeset fab2746 in mainline for uspace/lib/c/generic/inet
- Timestamp:
- 2015-04-08T21:25:30Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 99ea91b2
- Parents:
- ba0eac5
- Location:
- uspace/lib/c/generic/inet
- Files:
-
- 1 added
- 1 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/inet/addr.c
rba0eac5 rfab2746 36 36 #include <errno.h> 37 37 #include <unistd.h> 38 #include <net/socket_codes.h>39 38 #include <inet/addr.h> 40 #include <net/inet.h>41 39 #include <stdio.h> 42 40 #include <malloc.h> … … 44 42 45 43 #define INET_PREFIXSTRSIZE 5 44 45 #define INET6_ADDRSTRLEN (8 * 4 + 7 + 1) 46 46 47 47 #if !(defined(__BE__) ^ defined(__LE__)) … … 178 178 naddr->addr6[15] = h & 0xff; 179 179 naddr->prefix = prefix; 180 }181 182 /** Determine address version.183 *184 * @param text Address in common notation.185 * @param af Place to store address version.186 *187 * @return EOK on success, EINVAL if input is not in valid format.188 *189 */190 static int inet_addr_version(const char *text, ip_ver_t *ver)191 {192 char *dot = str_chr(text, '.');193 if (dot != NULL) {194 *ver = ip_v4;195 return EOK;196 }197 198 char *collon = str_chr(text, ':');199 if (collon != NULL) {200 *ver = ip_v6;201 return EOK;202 }203 204 return EINVAL;205 }206 207 static int ipver_af(ip_ver_t ver)208 {209 switch (ver) {210 case ip_any:211 return AF_NONE;212 case ip_v4:213 return AF_INET;214 case ip_v6:215 return AF_INET6;216 default:217 assert(false);218 return EINVAL;219 }220 }221 222 ip_ver_t ipver_from_af(int af)223 {224 switch (af) {225 case AF_NONE:226 return ip_any;227 case AF_INET:228 return ip_v4;229 case AF_INET6:230 return ip_v6;231 default:232 assert(false);233 return EINVAL;234 }235 180 } 236 181 … … 343 288 } 344 289 290 static int inet_addr_parse_v4(const char *str, inet_addr_t *raddr, 291 int *prefix) 292 { 293 uint32_t a = 0; 294 uint8_t b; 295 char *cur = (char *)str; 296 size_t i = 0; 297 298 while (i < 4) { 299 int rc = str_uint8_t(cur, (const char **)&cur, 10, false, &b); 300 if (rc != EOK) 301 return rc; 302 303 a = (a << 8) + b; 304 305 i++; 306 307 if (*cur == 0) 308 break; 309 310 if (*cur != '.') 311 return EINVAL; 312 313 if (i < 4) 314 cur++; 315 } 316 317 if (prefix != NULL) { 318 *prefix = strtoul(cur, &cur, 10); 319 if (*prefix > 32) 320 return EINVAL; 321 } 322 323 if (i != 4 || (*cur != 0)) 324 return EINVAL; 325 326 raddr->version = ip_v4; 327 raddr->addr = a; 328 329 return EOK; 330 } 331 332 static int inet_addr_parse_v6(const char *str, inet_addr_t *raddr, int *prefix) 333 { 334 /* XXX */ 335 return EINVAL; 336 } 337 345 338 /** Parse node address. 346 339 * … … 353 346 int inet_addr_parse(const char *text, inet_addr_t *addr) 354 347 { 355 int rc = inet_addr_version(text, &addr->version); 356 if (rc != EOK) 357 return rc; 358 359 uint8_t buf[16]; 360 rc = inet_pton(ipver_af(addr->version), text, buf); 361 if (rc != EOK) 362 return rc; 363 364 switch (addr->version) { 365 case ip_v4: 366 addr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | 367 buf[3]; 368 break; 369 case ip_v6: 370 memcpy(addr->addr6, buf, 16); 371 break; 372 default: 373 return EINVAL; 374 } 375 376 return EOK; 348 int rc; 349 350 rc = inet_addr_parse_v4(text, addr, NULL); 351 if (rc == EOK) 352 return EOK; 353 354 rc = inet_addr_parse_v6(text, addr, NULL); 355 if (rc == EOK) 356 return EOK; 357 358 return EINVAL; 377 359 } 378 360 … … 387 369 int inet_naddr_parse(const char *text, inet_naddr_t *naddr) 388 370 { 389 char *slash = str_chr(text, '/'); 390 if (slash == NULL) 391 return EINVAL; 392 393 *slash = 0; 394 395 int rc = inet_addr_version(text, &naddr->version); 396 if (rc != EOK) 397 return rc; 398 399 uint8_t buf[16]; 400 rc = inet_pton(ipver_af(naddr->version), text, buf); 401 *slash = '/'; 402 403 if (rc != EOK) 404 return rc; 405 406 slash++; 407 uint8_t prefix; 408 409 switch (naddr->version) { 410 case ip_v4: 411 prefix = strtoul(slash, &slash, 10); 412 if (prefix > 32) 371 int rc; 372 inet_addr_t addr; 373 int prefix; 374 375 rc = inet_addr_parse_v4(text, &addr, &prefix); 376 if (rc == EOK) { 377 inet_addr_naddr(&addr, prefix, naddr); 378 return EOK; 379 } 380 381 rc = inet_addr_parse_v6(text, &addr, &prefix); 382 if (rc == EOK) { 383 inet_addr_naddr(&addr, prefix, naddr); 384 return EOK; 385 } 386 387 return EINVAL; 388 } 389 390 static int inet_ntop6(const uint8_t *data, char *address, size_t length) 391 { 392 /* Check output buffer size */ 393 if (length < INET6_ADDRSTRLEN) 394 return ENOMEM; 395 396 /* Find the longest zero subsequence */ 397 398 uint16_t zeroes[8]; 399 uint16_t bioctets[8]; 400 401 for (size_t i = 8; i > 0; i--) { 402 size_t j = i - 1; 403 404 bioctets[j] = (data[j << 1] << 8) | data[(j << 1) + 1]; 405 406 if (bioctets[j] == 0) { 407 zeroes[j] = 1; 408 if (j < 7) 409 zeroes[j] += zeroes[j + 1]; 410 } else 411 zeroes[j] = 0; 412 } 413 414 size_t wildcard_pos = (size_t) -1; 415 size_t wildcard_size = 0; 416 417 for (size_t i = 0; i < 8; i++) { 418 if (zeroes[i] > wildcard_size) { 419 wildcard_pos = i; 420 wildcard_size = zeroes[i]; 421 } 422 } 423 424 char *cur = address; 425 size_t rest = length; 426 bool tail_zero = false; 427 int ret; 428 429 for (size_t i = 0; i < 8; i++) { 430 if ((i == wildcard_pos) && (wildcard_size > 1)) { 431 ret = snprintf(cur, rest, ":"); 432 i += wildcard_size - 1; 433 tail_zero = true; 434 } else if (i == 0) { 435 ret = snprintf(cur, rest, "%" PRIx16, bioctets[i]); 436 tail_zero = false; 437 } else { 438 ret = snprintf(cur, rest, ":%" PRIx16, bioctets[i]); 439 tail_zero = false; 440 } 441 442 if (ret < 0) 413 443 return EINVAL; 414 444 415 naddr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | 416 buf[3]; 417 naddr->prefix = prefix; 418 419 break; 420 case ip_v6: 421 prefix = strtoul(slash, &slash, 10); 422 if (prefix > 128) 445 cur += ret; 446 rest -= ret; 447 } 448 449 if (tail_zero) { 450 ret = snprintf(cur, rest, ":"); 451 if (ret < 0) 423 452 return EINVAL; 424 425 memcpy(naddr->addr6, buf, 16);426 naddr->prefix = prefix;427 428 break;429 default:430 return ENOTSUP;431 453 } 432 454 433 455 return EOK; 434 456 } 457 435 458 436 459 /** Format node address. … … 462 485 return ENOMEM; 463 486 464 return inet_ntop (AF_INET6,addr->addr6, *bufp, INET6_ADDRSTRLEN);487 return inet_ntop6(addr->addr6, *bufp, INET6_ADDRSTRLEN); 465 488 default: 489 asprintf(bufp, "<ver=%d>", addr->version); 466 490 return ENOTSUP; 467 491 } … … 503 527 return ENOMEM; 504 528 505 rc = inet_ntop (AF_INET6,naddr->addr6, *bufp,529 rc = inet_ntop6(naddr->addr6, *bufp, 506 530 INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE); 507 531 if (rc != EOK) { … … 586 610 } 587 611 588 void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr)589 {590 addr->version = ip_v4;591 addr->addr = uint32_t_be2host(sockaddr_in->sin_addr.s_addr);592 }593 594 612 void inet_addr_set6(addr128_t v6, inet_addr_t *addr) 595 613 { … … 605 623 } 606 624 607 void inet_sockaddr_in6_addr(const sockaddr_in6_t *sockaddr_in6,608 inet_addr_t *addr)609 {610 addr->version = ip_v6;611 addr128_t_be2host(sockaddr_in6->sin6_addr.s6_addr, addr->addr6);612 }613 614 uint16_t inet_addr_sockaddr_in(const inet_addr_t *addr,615 sockaddr_in_t *sockaddr_in, sockaddr_in6_t *sockaddr_in6)616 {617 switch (addr->version) {618 case ip_v4:619 if (sockaddr_in != NULL) {620 sockaddr_in->sin_family = AF_INET;621 sockaddr_in->sin_addr.s_addr = host2uint32_t_be(addr->addr);622 }623 break;624 case ip_v6:625 if (sockaddr_in6 != NULL) {626 sockaddr_in6->sin6_family = AF_INET6;627 host2addr128_t_be(addr->addr6, sockaddr_in6->sin6_addr.s6_addr);628 }629 break;630 default:631 assert(false);632 break;633 }634 635 return ipver_af(addr->version);636 }637 638 int inet_addr_sockaddr(const inet_addr_t *addr, uint16_t port,639 sockaddr_t **nsockaddr, socklen_t *naddrlen)640 {641 sockaddr_in_t *sa4;642 sockaddr_in6_t *sa6;643 644 switch (addr->version) {645 case ip_v4:646 sa4 = calloc(1, sizeof(sockaddr_in_t));647 if (sa4 == NULL)648 return ENOMEM;649 650 sa4->sin_family = AF_INET;651 sa4->sin_port = host2uint16_t_be(port);652 sa4->sin_addr.s_addr = host2uint32_t_be(addr->addr);653 if (nsockaddr != NULL)654 *nsockaddr = (sockaddr_t *)sa4;655 if (naddrlen != NULL)656 *naddrlen = sizeof(*sa4);657 break;658 case ip_v6:659 sa6 = calloc(1, sizeof(sockaddr_in6_t));660 if (sa6 == NULL)661 return ENOMEM;662 663 sa6->sin6_family = AF_INET6;664 sa6->sin6_port = host2uint16_t_be(port);665 host2addr128_t_be(addr->addr6, sa6->sin6_addr.s6_addr);666 if (nsockaddr != NULL)667 *nsockaddr = (sockaddr_t *)sa6;668 if (naddrlen != NULL)669 *naddrlen = sizeof(*sa6);670 break;671 default:672 assert(false);673 break;674 }675 676 return EOK;677 }678 679 625 /** @} 680 626 */ -
uspace/lib/c/generic/inet/endpoint.c
rba0eac5 rfab2746 1 1 /* 2 * Copyright (c) 201 1Jiri Svoboda2 * Copyright (c) 2015 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup tcp29 /** @addtogroup libc 30 30 * @{ 31 31 */ 32 /** @file Socket provider32 /** @file Internet endpoint 33 33 */ 34 34 35 #i fndef SOCK_H36 # define SOCK_H35 #include <inet/endpoint.h> 36 #include <mem.h> 37 37 38 #include <async.h> 38 void inet_ep_init(inet_ep_t *ep) 39 { 40 memset(ep, 0, sizeof(*ep)); 41 } 39 42 40 extern int tcp_sock_init(void); 41 42 #endif 43 void inet_ep2_init(inet_ep2_t *ep2) 44 { 45 memset(ep2, 0, sizeof(*ep2)); 46 } 43 47 44 48 /** @} -
uspace/lib/c/generic/inet/tcp.c
rba0eac5 rfab2746 1 1 /* 2 * Copyright (c) 20 09 Lukas Mejdrech2 * Copyright (c) 2015 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 28 28 29 29 /** @addtogroup libc 30 * @{ 30 * @{ 31 */ 32 /** @file UDP API 31 33 */ 32 34 33 /** @file 34 * Socket application program interface (API). 35 * This is a part of the network application library. 36 * Based on the BSD socket interface. 37 */ 35 #include <errno.h> 36 #include <inet/endpoint.h> 37 #include <inet/tcp.h> 38 38 39 #ifndef LIBC_SOCKET_H_ 40 #define LIBC_SOCKET_H_ 39 int tcp_create(tcp_t **rtcp) 40 { 41 return 0; 42 } 41 43 42 #include <net/socket_codes.h> 43 #include <net/in.h> 44 #include <net/in6.h> 45 #include <net/inet.h> 46 #include <errno.h> 47 #include <byteorder.h> 44 void tcp_destroy(tcp_t *tcp) 45 { 46 } 48 47 49 /** @name Socket application programming interface 50 */ 51 /*@{*/ 48 int tcp_conn_create(tcp_t *tcp, inet_ep2_t *epp, tcp_cb_t *cb, void *arg, 49 tcp_conn_t **rconn) 50 { 51 return 0; 52 } 52 53 53 extern int socket(int, int, int); 54 extern int bind(int, const struct sockaddr *, socklen_t); 55 extern int listen(int, int); 56 extern int accept(int, struct sockaddr *, socklen_t *); 57 extern int connect(int, const struct sockaddr *, socklen_t); 58 extern int closesocket(int); 59 extern int send(int, const void *, size_t, int); 60 extern int sendto(int, const void *, size_t, int, const struct sockaddr *, 61 socklen_t); 62 extern ssize_t recv(int, void *, size_t, int); 63 extern ssize_t recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); 64 extern int getsockopt(int, int, int, void *, size_t *); 65 extern int setsockopt(int, int, int, const void *, size_t); 54 void tcp_conn_destroy(tcp_conn_t *conn) 55 { 56 } 66 57 67 /*@}*/ 58 void *tcp_conn_userptr(tcp_conn_t *conn) 59 { 60 return NULL; 61 } 68 62 69 #endif 63 int tcp_listener_create(tcp_t *tcp, inet_ep_t *ep, tcp_listen_cb_t *lcb, 64 void *larg, tcp_cb_t *cb, void *arg, tcp_listener_t **rlst) 65 { 66 return 0; 67 } 68 69 void tcp_listener_destroy(tcp_listener_t *lst) 70 { 71 } 72 73 void *tcp_listener_userptr(tcp_listener_t *lst) 74 { 75 return NULL; 76 } 77 78 79 int tcp_conn_wait_connected(tcp_conn_t *conn) 80 { 81 return 0; 82 } 83 84 int tcp_conn_send(tcp_conn_t *conn, const void *data, size_t bytes) 85 { 86 return 0; 87 } 88 89 int tcp_conn_send_fin(tcp_conn_t *conn) 90 { 91 return 0; 92 } 93 94 int tcp_conn_push(tcp_conn_t *conn) 95 { 96 return 0; 97 } 98 99 void tcp_conn_reset(tcp_conn_t *conn) 100 { 101 } 102 103 104 int tcp_conn_recv(tcp_conn_t *conn, void *buf, size_t bsize, size_t *nrecv) 105 { 106 return 0; 107 } 108 109 int tcp_conn_recv_wait(tcp_conn_t *conn, void *buf, size_t bsize, size_t *nrecv) 110 { 111 return 0; 112 } 113 70 114 71 115 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.