diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2023-11-23 03:22:15 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2023-11-23 03:22:15 +0000 |
commit | f46d63340d48aaa9bed8426a44298cbb14657850 (patch) | |
tree | 8f79a81e980608bbe192e02b273c932786cc9185 /sbin/ifconfig/ifconfig.c | |
parent | 5650389d0a250962e0a4fd43de7ec5cfe1bd0af8 (diff) |
add support for specifying ports on the src address in tunnel endpoints.
Diffstat (limited to 'sbin/ifconfig/ifconfig.c')
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 123 |
1 files changed, 82 insertions, 41 deletions
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 1b0ba073dd6..6d8a90209ff 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ifconfig.c,v 1.468 2023/10/29 14:23:04 millert Exp $ */ +/* $OpenBSD: ifconfig.c,v 1.469 2023/11/23 03:22:14 dlg Exp $ */ /* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */ /* @@ -3185,9 +3185,11 @@ static void print_tunnel(const struct if_laddrreq *req) { char psrcaddr[NI_MAXHOST]; + char psrcport[NI_MAXSERV]; char pdstaddr[NI_MAXHOST]; + char pdstport[NI_MAXSERV]; const char *ver = ""; - const int niflag = NI_NUMERICHOST; + const int niflag = NI_NUMERICHOST | NI_NUMERICSERV | NI_DGRAM; if (req == NULL) { printf("(unset)"); @@ -3197,12 +3199,15 @@ print_tunnel(const struct if_laddrreq *req) psrcaddr[0] = pdstaddr[0] = '\0'; if (getnameinfo((struct sockaddr *)&req->addr, req->addr.ss_len, - psrcaddr, sizeof(psrcaddr), 0, 0, niflag) != 0) + psrcaddr, sizeof(psrcaddr), psrcport, sizeof(psrcport), + niflag) != 0) strlcpy(psrcaddr, "<error>", sizeof(psrcaddr)); if (req->addr.ss_family == AF_INET6) ver = "6"; printf("inet%s %s", ver, psrcaddr); + if (strcmp(psrcport, "0") != 0) + printf(":%s", psrcport); if (req->dstaddr.ss_family != AF_UNSPEC) { in_port_t dstport = 0; @@ -3211,24 +3216,12 @@ print_tunnel(const struct if_laddrreq *req) if (getnameinfo((struct sockaddr *)&req->dstaddr, req->dstaddr.ss_len, pdstaddr, sizeof(pdstaddr), - 0, 0, niflag) != 0) + pdstport, sizeof(pdstport), niflag) != 0) strlcpy(pdstaddr, "<error>", sizeof(pdstaddr)); printf(" --> %s", pdstaddr); - - switch (req->dstaddr.ss_family) { - case AF_INET: - sin = (const struct sockaddr_in *)&req->dstaddr; - dstport = sin->sin_port; - break; - case AF_INET6: - sin6 = (const struct sockaddr_in6 *)&req->dstaddr; - dstport = sin6->sin6_port; - break; - } - - if (dstport) - printf(":%u", ntohs(dstport)); + if (strcmp(pdstport, "0") != 0) + printf(":%s", pdstport); } } @@ -3715,29 +3708,58 @@ in6_status(int force) void settunnel(const char *src, const char *dst) { - char buf[HOST_NAME_MAX+1 + sizeof (":65535")], *dstport; - const char *dstip; + char srcbuf[HOST_NAME_MAX], dstbuf[HOST_NAME_MAX]; + const char *srcport, *dstport; + const char *srcaddr, *dstaddr; struct addrinfo *srcres, *dstres; + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_DGRAM, + .ai_protocol = IPPROTO_UDP, + .ai_flags = AI_PASSIVE, + }; int ecode; + size_t len; struct if_laddrreq req; - if (strchr(dst, ':') == NULL || strchr(dst, ':') != strrchr(dst, ':')) { + srcport = strchr(src, ':'); + if (srcport == NULL || srcport != strrchr(src, ':')) { /* no port or IPv6 */ - dstip = dst; + srcaddr = src; + srcport = NULL; + } else { + len = srcport - src; + if (len >= sizeof(srcbuf)) + errx(1, "src %s bad value", src); + memcpy(srcbuf, src, len); + srcbuf[len] = '\0'; + + srcaddr = srcbuf; + srcport++; + } + + dstport = strchr(dst, ':'); + if (dstport == NULL || dstport != strrchr(dst, ':')) { + /* no port or IPv6 */ + dstaddr = dst; dstport = NULL; } else { - if (strlcpy(buf, dst, sizeof(buf)) >= sizeof(buf)) - errx(1, "%s bad value", dst); - dstport = strchr(buf, ':'); - *dstport++ = '\0'; - dstip = buf; + len = dstport - dst; + if (len >= sizeof(dstbuf)) + errx(1, "dst %s bad value", dst); + memcpy(dstbuf, dst, len); + dstbuf[len] = '\0'; + + dstaddr = dstbuf; + dstport++; } - if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0) + if ((ecode = getaddrinfo(srcaddr, srcport, &hints, &srcres)) != 0) errx(1, "error in parsing address string: %s", gai_strerror(ecode)); - if ((ecode = getaddrinfo(dstip, dstport, NULL, &dstres)) != 0) + hints.ai_flags = 0; + if ((ecode = getaddrinfo(dstaddr, dstport, &hints, &dstres)) != 0) errx(1, "error in parsing address string: %s", gai_strerror(ecode)); @@ -3757,37 +3779,56 @@ settunnel(const char *src, const char *dst) } void -settunneladdr(const char *addr, int ignored) +settunneladdr(const char *src, int ignored) { - struct addrinfo hints, *res; + char srcbuf[HOST_NAME_MAX]; + const char *srcport; + const char *srcaddr; + struct addrinfo *srcres; + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_DGRAM, + .ai_protocol = IPPROTO_UDP, + .ai_flags = AI_PASSIVE, + }; struct if_laddrreq req; ssize_t len; int rv; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = 0; - hints.ai_flags = AI_PASSIVE; + srcport = strchr(src, ':'); + if (srcport == NULL || srcport != strrchr(src, ':')) { + /* no port or IPv6 */ + srcaddr = src; + srcport = NULL; + } else { + len = srcport - src; + if (len >= sizeof(srcbuf)) + errx(1, "src %s bad value", src); + memcpy(srcbuf, src, len); + srcbuf[len] = '\0'; - rv = getaddrinfo(addr, NULL, &hints, &res); + srcaddr = srcbuf; + srcport++; + } + + rv = getaddrinfo(srcaddr, srcport, &hints, &srcres); if (rv != 0) - errx(1, "tunneladdr %s: %s", addr, gai_strerror(rv)); + errx(1, "tunneladdr %s: %s", src, gai_strerror(rv)); memset(&req, 0, sizeof(req)); len = strlcpy(req.iflr_name, ifname, sizeof(req.iflr_name)); if (len >= sizeof(req.iflr_name)) errx(1, "%s: Interface name too long", ifname); - memcpy(&req.addr, res->ai_addr, res->ai_addrlen); + memcpy(&req.addr, srcres->ai_addr, srcres->ai_addrlen); req.dstaddr.ss_len = 2; req.dstaddr.ss_family = AF_UNSPEC; if (ioctl(sock, SIOCSLIFPHYADDR, &req) == -1) - warn("tunneladdr %s", addr); + warn("tunneladdr %s", src); - freeaddrinfo(res); + freeaddrinfo(srcres); } void |