summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2014-05-27 19:47:22 +0200
committerGreg Hudson <ghudson@mit.edu>2014-06-27 19:36:40 -0400
commit0d04b60d159ab83b943e43802b1449a3b074bc83 (patch)
tree69c67a722770b6999963798cd7a372262ef9946c
parent7567f36f83bab47206c2ea85724c1e74c26ec0d6 (diff)
downloadkrb5-0d04b60d159ab83b943e43802b1449a3b074bc83.tar.gz
krb5-0d04b60d159ab83b943e43802b1449a3b074bc83.tar.xz
krb5-0d04b60d159ab83b943e43802b1449a3b074bc83.zip
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)
-rw-r--r--src/include/gssrpc/rename.h1
-rw-r--r--src/include/gssrpc/rpc.h1
-rw-r--r--src/lib/rpc/bindresvport.c34
3 files changed, 25 insertions, 11 deletions
diff --git a/src/include/gssrpc/rename.h b/src/include/gssrpc/rename.h
index ecec66ab1..444bc97a6 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 565f1c2f3..2d94a7fe9 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 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 <asn@samba.org>
*
* All rights reserved.
*
@@ -33,6 +34,8 @@
*/
#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/errno.h>
@@ -40,27 +43,31 @@
#include <netinet/in.h>
#include <gssrpc/rpc.h>
#include <errno.h>
+#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));
+}