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/include/gssrpc/rename.h | 1 + src/include/gssrpc/rpc.h | 1 + src/lib/rpc/bindresvport.c | 34 +++++++++++++++++++++++----------- 3 files changed, 25 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/include/gssrpc/rename.h b/src/include/gssrpc/rename.h index ecec66a..444bc97 100644 --- a/src/include/gssrpc/rename.h +++ b/src/include/gssrpc/rename.h @@ -177,6 +177,7 @@ #define get_myaddress gssrpc_get_myaddress #define bindresvport gssrpc_bindresvport +#define bindresvport_sa gssrpc_bindresvport_sa #define callrpc gssrpc_callrpc #define getrpcport gssrpc_getrpcport diff --git a/src/include/gssrpc/rpc.h b/src/include/gssrpc/rpc.h index 565f1c2..2d94a7f 100644 --- a/src/include/gssrpc/rpc.h +++ b/src/include/gssrpc/rpc.h @@ -92,6 +92,7 @@ GSSRPC__BEGIN_DECLS extern int get_myaddress(struct sockaddr_in *); extern int bindresvport(int, struct sockaddr_in *); +extern int bindresvport_sa(int, struct sockaddr *); extern int callrpc(char *, rpcprog_t, rpcvers_t, rpcproc_t, xdrproc_t, char *, xdrproc_t , char *); extern int getrpcport(char *, rpcprog_t, rpcvers_t, rpcprot_t); diff --git a/src/lib/rpc/bindresvport.c b/src/lib/rpc/bindresvport.c index 6755f4d..fa28b60 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 v1.1