From e63acdb2ff2dba1b6b8cdb21bedb3b80ec3112a3 Mon Sep 17 00:00:00 2001 From: Richard Aas Date: Fri, 3 Aug 2012 12:55:15 +0000 Subject: [PATCH] tcp/udp: IPv6 scope-id support for link-local addresses --- include/re_sa.h | 3 +++ mk/symbian/re.mmp | 1 + src/sa/mod.mk | 1 + src/sa/print.c | 39 +++++++++++++++++++++++++++++++++++++++ src/tcp/tcp.c | 37 ++++++++++++++++--------------------- src/udp/udp.c | 7 +++---- 6 files changed, 63 insertions(+), 25 deletions(-) create mode 100644 src/sa/print.c diff --git a/include/re_sa.h b/include/re_sa.h index 8801621..f351fae 100644 --- a/include/re_sa.h +++ b/include/re_sa.h @@ -57,3 +57,6 @@ bool sa_cmp(const struct sa *l, const struct sa *r, int flag); bool sa_is_linklocal(const struct sa *sa); bool sa_is_loopback(const struct sa *sa); bool sa_is_any(const struct sa *sa); + +struct re_printf; +int sa_print_addr(struct re_printf *pf, const struct sa *sa); diff --git a/mk/symbian/re.mmp b/mk/symbian/re.mmp index af46ce7..a03b317 100644 --- a/mk/symbian/re.mmp +++ b/mk/symbian/re.mmp @@ -109,6 +109,7 @@ SOURCE source.c SOURCEPATH ..\..\src\sa SOURCE ntop.c +SOURCE print.c SOURCE pton.c SOURCE sa.c diff --git a/src/sa/mod.mk b/src/sa/mod.mk index 7a39e31..a4e95e9 100644 --- a/src/sa/mod.mk +++ b/src/sa/mod.mk @@ -5,5 +5,6 @@ # SRCS += sa/ntop.c +SRCS += sa/print.c SRCS += sa/pton.c SRCS += sa/sa.c diff --git a/src/sa/print.c b/src/sa/print.c new file mode 100644 index 0000000..47f8f38 --- /dev/null +++ b/src/sa/print.c @@ -0,0 +1,39 @@ +/** + * @file sa/print.c Socket Address printing + * + * Copyright (C) 2010 Creytiv.com + */ +#ifdef HAVE_GETIFADDRS +#include +#include +#define __USE_MISC 1 /**< Use MISC code */ +#include +#endif +#include +#include +#include + + +int sa_print_addr(struct re_printf *pf, const struct sa *sa) +{ + int err; + + if (!sa) + return 0; + + err = re_hprintf(pf, "%j", sa); + +#ifdef HAVE_GETIFADDRS + if (sa_af(sa) == AF_INET6 && sa_is_linklocal(sa)) { + + char ifname[IF_NAMESIZE]; + + if (!if_indextoname(sa->u.in6.sin6_scope_id, ifname)) + return errno; + + err |= re_hprintf(pf, "%%%s", ifname); + } +#endif + + return err; +} diff --git a/src/tcp/tcp.c b/src/tcp/tcp.c index f2a5549..0d4cde6 100644 --- a/src/tcp/tcp.c +++ b/src/tcp/tcp.c @@ -566,7 +566,7 @@ int tcp_sock_alloc(struct tcp_sock **tsp, const struct sa *local, tcp_conn_h *ch, void *arg) { struct addrinfo hints, *res = NULL, *r; - char addr[NET_ADDRSTRLEN] = ""; + char addr[64] = ""; char serv[6] = "0"; struct tcp_sock *ts = NULL; int error, err; @@ -582,10 +582,9 @@ int tcp_sock_alloc(struct tcp_sock **tsp, const struct sa *local, ts->fdc = -1; if (local) { - err = sa_ntop(local, addr, sizeof(addr)); + (void)re_snprintf(addr, sizeof(addr), "%H", + sa_print_addr, local); (void)re_snprintf(serv, sizeof(serv), "%u", sa_port(local)); - if (err) - goto out; } memset(&hints, 0, sizeof(hints)); @@ -667,7 +666,7 @@ int tcp_sock_alloc(struct tcp_sock **tsp, const struct sa *local, int tcp_sock_bind(struct tcp_sock *ts, const struct sa *local) { struct addrinfo hints, *res = NULL, *r; - char addr[NET_ADDRSTRLEN] = ""; + char addr[64] = ""; char serv[NI_MAXSERV] = "0"; int error, err; @@ -675,10 +674,9 @@ int tcp_sock_bind(struct tcp_sock *ts, const struct sa *local) return EINVAL; if (local) { - err = sa_ntop(local, addr, sizeof(addr)); + (void)re_snprintf(addr, sizeof(addr), "%H", + sa_print_addr, local); (void)re_snprintf(serv, sizeof(serv), "%u", sa_port(local)); - if (err) - return err; } memset(&hints, 0, sizeof(hints)); @@ -829,7 +827,7 @@ int tcp_conn_alloc(struct tcp_conn **tcp, { struct tcp_conn *tc; struct addrinfo hints, *res = NULL, *r; - char addr[NET_ADDRSTRLEN]; + char addr[64]; char serv[NI_MAXSERV] = "0"; int error, err; @@ -847,10 +845,9 @@ int tcp_conn_alloc(struct tcp_conn **tcp, hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - err = sa_ntop(peer, addr, sizeof(addr)); + (void)re_snprintf(addr, sizeof(addr), "%H", + sa_print_addr, peer); (void)re_snprintf(serv, sizeof(serv), "%u", sa_port(peer)); - if (err) - goto out; error = getaddrinfo(addr, serv, &hints, &res); if (error) { @@ -908,7 +905,7 @@ int tcp_conn_alloc(struct tcp_conn **tcp, int tcp_conn_bind(struct tcp_conn *tc, const struct sa *local) { struct addrinfo hints, *res = NULL, *r; - char addr[NET_ADDRSTRLEN] = ""; + char addr[64] = ""; char serv[NI_MAXSERV] = "0"; int error, err; @@ -916,10 +913,9 @@ int tcp_conn_bind(struct tcp_conn *tc, const struct sa *local) return EINVAL; if (local) { - err = sa_ntop(local, addr, sizeof(addr)); + (void)re_snprintf(addr, sizeof(addr), "%H", + sa_print_addr, local); (void)re_snprintf(serv, sizeof(serv), "%u", sa_port(local)); - if (err) - return err; } memset(&hints, 0, sizeof(hints)); @@ -983,9 +979,9 @@ int tcp_conn_bind(struct tcp_conn *tc, const struct sa *local) int tcp_conn_connect(struct tcp_conn *tc, const struct sa *peer) { struct addrinfo hints, *res = NULL, *r; - char addr[NET_ADDRSTRLEN]; + char addr[64]; char serv[NI_MAXSERV]; - int error, err; + int error, err = 0; if (!tc || !sa_isset(peer, SA_ALL)) return EINVAL; @@ -1004,10 +1000,9 @@ int tcp_conn_connect(struct tcp_conn *tc, const struct sa *peer) hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - err = sa_ntop(peer, addr, sizeof(addr)); + (void)re_snprintf(addr, sizeof(addr), "%H", + sa_print_addr, peer); (void)re_snprintf(serv, sizeof(serv), "%u", sa_port(peer)); - if (err) - return err; error = getaddrinfo(addr, serv, &hints, &res); if (error) { diff --git a/src/udp/udp.c b/src/udp/udp.c index 13479ee..07555d2 100644 --- a/src/udp/udp.c +++ b/src/udp/udp.c @@ -262,7 +262,7 @@ int udp_listen(struct udp_sock **usp, const struct sa *local, { struct addrinfo hints, *res = NULL, *r; struct udp_sock *us = NULL; - char addr[NET_ADDRSTRLEN]; + char addr[64]; char serv[6] = "0"; int af, error, err = 0; @@ -280,10 +280,9 @@ int udp_listen(struct udp_sock **usp, const struct sa *local, if (local) { af = sa_af(local); - err = sa_ntop(local, addr, sizeof(addr)); + (void)re_snprintf(addr, sizeof(addr), "%H", + sa_print_addr, local); (void)re_snprintf(serv, sizeof(serv), "%u", sa_port(local)); - if (err) - goto out; } else { #ifdef HAVE_INET6