From 0d04b60d159ab83b943e43802b1449a3b074bc83 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 27 May 2014 19:47:22 +0200 Subject: Add a family-independent bindresvport_sa function This functions allows you to pass IPv4 and IPv6 addresses. If no address is given, t will determine the family by checking the socket with getsockname. [ghudson@mit.edu: clarified commit message, split out setport helper, squashed with next commit, minimized code changes from old bindresvport, used socket-utils.h helpers] ticket: 7935 (new) --- src/lib/rpc/bindresvport.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'src/lib') diff --git a/src/lib/rpc/bindresvport.c b/src/lib/rpc/bindresvport.c index 6755f4db2..fa28b6071 100644 --- a/src/lib/rpc/bindresvport.c +++ b/src/lib/rpc/bindresvport.c @@ -1,6 +1,7 @@ /* lib/rpc/bindresvport.c */ /* * Copyright (c) 2010, Oracle America, Inc. + * Copyright (c) 2014, Andreas Schneider * * All rights reserved. * @@ -33,6 +34,8 @@ */ #include +#include +#include #include #include #include @@ -40,27 +43,31 @@ #include #include #include +#include "socket-utils.h" /* * Bind a socket to a privileged IP port */ int -bindresvport(int sd, struct sockaddr_in *sockin) +bindresvport_sa(int sd, struct sockaddr *sa) { int res; static short port; - struct sockaddr_in myaddr; + struct sockaddr_storage myaddr; + socklen_t salen; int i; #define STARTPORT 600 #define ENDPORT (IPPORT_RESERVED - 1) #define NPORTS (ENDPORT - STARTPORT + 1) - - if (sockin == (struct sockaddr_in *)0) { - sockin = &myaddr; - memset(sockin, 0, sizeof (*sockin)); - sockin->sin_family = AF_INET; - } else if (sockin->sin_family != AF_INET) { + if (sa == NULL) { + salen = sizeof(myaddr); + sa = ss2sa(&myaddr); + res = getsockname(sd, sa, &salen); + if (res < 0) + return (-1); + } + if (!sa_is_inet(sa)) { errno = EPFNOSUPPORT; return (-1); } @@ -70,12 +77,17 @@ bindresvport(int sd, struct sockaddr_in *sockin) res = -1; errno = EADDRINUSE; for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) { - sockin->sin_port = htons(port++); + sa_setport(sa, htons(port++)); if (port > ENDPORT) { port = STARTPORT; } - res = bind(sd, (struct sockaddr *) sockin, - sizeof(struct sockaddr_in)); + res = bind(sd, sa, socklen(sa)); } return (res); } + +int +bindresvport(int sd, struct sockaddr_in *sockin) +{ + return (bindresvport_sa(sd, (struct sockaddr *)sockin)); +} -- cgit