summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2011-05-02 15:23:08 +1000
committerAndrew Bartlett <abartlet@samba.org>2011-05-03 07:37:07 +0200
commitfbea52f74a80268446f45936a0cf40400aba8565 (patch)
tree5f77314c19f34a05683d9ee8f76ab250e4e8da6f
parent85fa87ea82a1dcbd4d0145e417d615ffca116751 (diff)
downloadsamba-fbea52f74a80268446f45936a0cf40400aba8565.tar.gz
samba-fbea52f74a80268446f45936a0cf40400aba8565.tar.bz2
samba-fbea52f74a80268446f45936a0cf40400aba8565.zip
lib/util Move more network utility functions from source3 into lib/util
This will help with the merge of the interfaces layer. Andrew Bartlett
-rw-r--r--lib/util/system.c72
-rw-r--r--lib/util/util.h14
-rw-r--r--lib/util/util_net.c155
-rw-r--r--lib/util/util_net.h35
-rw-r--r--source3/include/proto.h10
-rw-r--r--source3/lib/system.c71
-rw-r--r--source3/lib/util_sock.c156
7 files changed, 275 insertions, 238 deletions
diff --git a/lib/util/system.c b/lib/util/system.c
index 9bf5de1a83..17c0553102 100644
--- a/lib/util/system.c
+++ b/lib/util/system.c
@@ -117,3 +117,75 @@ _PUBLIC_ pid_t sys_getpid(void)
return mypid;
}
+
+
+_PUBLIC_ int sys_getpeereid( int s, uid_t *uid)
+{
+#if defined(HAVE_PEERCRED)
+ struct ucred cred;
+ socklen_t cred_len = sizeof(struct ucred);
+ int ret;
+
+ ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
+ if (ret != 0) {
+ return -1;
+ }
+
+ if (cred_len != sizeof(struct ucred)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ *uid = cred.uid;
+ return 0;
+#else
+#if defined(HAVE_GETPEEREID)
+ gid_t gid;
+ return getpeereid(s, uid, &gid);
+#endif
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+_PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa,
+ int salen,
+ char *host,
+ size_t hostlen,
+ char *service,
+ size_t servlen,
+ int flags)
+{
+ /*
+ * For Solaris we must make sure salen is the
+ * correct length for the incoming sa_family.
+ */
+
+ if (salen == sizeof(struct sockaddr_storage)) {
+ salen = sizeof(struct sockaddr_in);
+#if defined(HAVE_IPV6)
+ if (psa->sa_family == AF_INET6) {
+ salen = sizeof(struct sockaddr_in6);
+ }
+#endif
+ }
+ return getnameinfo(psa, salen, host, hostlen, service, servlen, flags);
+}
+
+_PUBLIC_ int sys_connect(int fd, const struct sockaddr * addr)
+{
+ socklen_t salen = (socklen_t)-1;
+
+ if (addr->sa_family == AF_INET) {
+ salen = sizeof(struct sockaddr_in);
+ } else if (addr->sa_family == AF_UNIX) {
+ salen = sizeof(struct sockaddr_un);
+ }
+#if defined(HAVE_IPV6)
+ else if (addr->sa_family == AF_INET6) {
+ salen = sizeof(struct sockaddr_in6);
+ }
+#endif
+
+ return connect(fd, addr, salen);
+}
diff --git a/lib/util/util.h b/lib/util/util.h
index 8dffece0da..5ed8427498 100644
--- a/lib/util/util.h
+++ b/lib/util/util.h
@@ -131,8 +131,20 @@ _PUBLIC_ pid_t sys_fork(void);
**/
_PUBLIC_ pid_t sys_getpid(void);
-/* The following definitions come from lib/util/genrand.c */
+_PUBLIC_ int sys_getpeereid( int s, uid_t *uid);
+
+struct sockaddr;
+_PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa,
+ int salen,
+ char *host,
+ size_t hostlen,
+ char *service,
+ size_t servlen,
+ int flags);
+_PUBLIC_ int sys_connect(int fd, const struct sockaddr * addr);
+
+/* The following definitions come from lib/util/genrand.c */
/**
Copy any user given reseed data.
**/
diff --git a/lib/util/util_net.c b/lib/util/util_net.c
index 9c8f5c6d47..e80447128f 100644
--- a/lib/util/util_net.c
+++ b/lib/util/util_net.c
@@ -540,3 +540,158 @@ void set_sockaddr_port(struct sockaddr *psa, uint16_t port)
}
+/****************************************************************************
+ Get a port number in host byte order from a sockaddr_storage.
+****************************************************************************/
+
+uint16_t get_sockaddr_port(const struct sockaddr_storage *pss)
+{
+ uint16_t port = 0;
+
+ if (pss->ss_family != AF_INET) {
+#if defined(HAVE_IPV6)
+ /* IPv6 */
+ const struct sockaddr_in6 *sa6 =
+ (const struct sockaddr_in6 *)pss;
+ port = ntohs(sa6->sin6_port);
+#endif
+ } else {
+ const struct sockaddr_in *sa =
+ (const struct sockaddr_in *)pss;
+ port = ntohs(sa->sin_port);
+ }
+ return port;
+}
+
+/****************************************************************************
+ Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_sockaddr_len(char *dest,
+ size_t destlen,
+ const struct sockaddr *psa,
+ socklen_t psalen)
+{
+ if (destlen > 0) {
+ dest[0] = '\0';
+ }
+ (void)sys_getnameinfo(psa,
+ psalen,
+ dest, destlen,
+ NULL, 0,
+ NI_NUMERICHOST);
+ return dest;
+}
+
+/****************************************************************************
+ Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_sockaddr(char *dest,
+ size_t destlen,
+ const struct sockaddr_storage *psa)
+{
+ return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa,
+ sizeof(struct sockaddr_storage));
+}
+
+/****************************************************************************
+ Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_canonical_sockaddr(TALLOC_CTX *ctx,
+ const struct sockaddr_storage *pss)
+{
+ char addr[INET6_ADDRSTRLEN];
+ char *dest = NULL;
+ int ret;
+
+ /* Linux getnameinfo() man pages says port is unitialized if
+ service name is NULL. */
+
+ ret = sys_getnameinfo((const struct sockaddr *)pss,
+ sizeof(struct sockaddr_storage),
+ addr, sizeof(addr),
+ NULL, 0,
+ NI_NUMERICHOST);
+ if (ret != 0) {
+ return NULL;
+ }
+
+ if (pss->ss_family != AF_INET) {
+#if defined(HAVE_IPV6)
+ dest = talloc_asprintf(ctx, "[%s]", addr);
+#else
+ return NULL;
+#endif
+ } else {
+ dest = talloc_asprintf(ctx, "%s", addr);
+ }
+
+ return dest;
+}
+
+/****************************************************************************
+ Return the port number we've bound to on a socket.
+****************************************************************************/
+
+int get_socket_port(int fd)
+{
+ struct sockaddr_storage sa;
+ socklen_t length = sizeof(sa);
+
+ if (fd == -1) {
+ return -1;
+ }
+
+ if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
+ int level = (errno == ENOTCONN) ? 2 : 0;
+ DEBUG(level, ("getsockname failed. Error was %s\n",
+ strerror(errno)));
+ return -1;
+ }
+
+#if defined(HAVE_IPV6)
+ if (sa.ss_family == AF_INET6) {
+ return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port);
+ }
+#endif
+ if (sa.ss_family == AF_INET) {
+ return ntohs(((struct sockaddr_in *)&sa)->sin_port);
+ }
+ return -1;
+}
+
+/****************************************************************************
+ Return the string of an IP address (IPv4 or IPv6).
+****************************************************************************/
+
+static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len)
+{
+ struct sockaddr_storage sa;
+ socklen_t length = sizeof(sa);
+
+ /* Ok, returning a hard coded IPv4 address
+ * is bogus, but it's just as bogus as a
+ * zero IPv6 address. No good choice here.
+ */
+
+ strlcpy(addr_buf, "0.0.0.0", addr_len);
+
+ if (fd == -1) {
+ return addr_buf;
+ }
+
+ if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
+ DEBUG(0,("getsockname failed. Error was %s\n",
+ strerror(errno) ));
+ return addr_buf;
+ }
+
+ return print_sockaddr_len(addr_buf, addr_len, (struct sockaddr *)&sa, length);
+}
+
+const char *client_socket_addr(int fd, char *addr, size_t addr_len)
+{
+ return get_socket_addr(fd, addr, addr_len);
+}
diff --git a/lib/util/util_net.h b/lib/util/util_net.h
index 530311e5c8..71d1d1a6bd 100644
--- a/lib/util/util_net.h
+++ b/lib/util/util_net.h
@@ -50,6 +50,15 @@ void set_sockaddr_port(struct sockaddr *psa, uint16_t port);
**/
_PUBLIC_ bool is_zero_ip_v4(struct in_addr ip);
+void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
+ struct in_addr ip);
+#if defined(HAVE_IPV6)
+/**
+ * Convert an IPv6 struct in_addr to a struct sockaddr_storage.
+ */
+void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
+ struct in6_addr ip);
+#endif
/**
Are two IPs on the same subnet?
**/
@@ -60,6 +69,11 @@ _PUBLIC_ bool same_net_v4(struct in_addr ip1,struct in_addr ip2,struct in_addr m
**/
_PUBLIC_ bool is_ipaddress(const char *str);
+bool is_broadcast_addr(const struct sockaddr *pss);
+bool is_loopback_ip_v4(struct in_addr ip);
+bool is_loopback_addr(const struct sockaddr *pss);
+bool is_zero_addr(const struct sockaddr_storage *pss);
+void zero_ip_v4(struct in_addr *ip);
/**
Interpret an internet address or name into an IP address in 4 byte form.
**/
@@ -72,5 +86,26 @@ _PUBLIC_ struct in_addr interpret_addr2(const char *str);
_PUBLIC_ bool is_ipaddress_v4(const char *str);
+bool is_address_any(const struct sockaddr *psa);
+bool same_net(const struct sockaddr *ip1,
+ const struct sockaddr *ip2,
+ const struct sockaddr *mask);
+bool sockaddr_equal(const struct sockaddr *ip1,
+ const struct sockaddr *ip2);
+
+bool is_address_any(const struct sockaddr *psa);
+uint16_t get_sockaddr_port(const struct sockaddr_storage *pss);
+char *print_sockaddr_len(char *dest,
+ size_t destlen,
+ const struct sockaddr *psa,
+ socklen_t psalen);
+char *print_sockaddr(char *dest,
+ size_t destlen,
+ const struct sockaddr_storage *psa);
+char *print_canonical_sockaddr(TALLOC_CTX *ctx,
+ const struct sockaddr_storage *pss);
+const char *client_name(int fd);
+int get_socket_port(int fd);
+const char *client_socket_addr(int fd, char *addr, size_t addr_len);
#endif /* _SAMBA_UTIL_NET_H_ */
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ebfa5e633a..3c2e30d6be 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -532,16 +532,6 @@ int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb);
int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb);
int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb);
int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout);
-int sys_getpeereid( int s, uid_t *uid);
-int sys_getnameinfo(const struct sockaddr *psa,
- socklen_t salen,
- char *host,
- size_t hostlen,
- char *service,
- size_t servlen,
- int flags);
-int sys_connect(int fd, const struct sockaddr * addr);
-
/* The following definitions come from lib/system_smbd.c */
bool getgroups_unix_user(TALLOC_CTX *mem_ctx, const char *user,
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 52b6477266..b6cc7a8b07 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -2633,74 +2633,3 @@ int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct
return -1;
}
#endif /* WITH_AIO */
-
-int sys_getpeereid( int s, uid_t *uid)
-{
-#if defined(HAVE_PEERCRED)
- struct ucred cred;
- socklen_t cred_len = sizeof(struct ucred);
- int ret;
-
- ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
- if (ret != 0) {
- return -1;
- }
-
- if (cred_len != sizeof(struct ucred)) {
- errno = EINVAL;
- return -1;
- }
-
- *uid = cred.uid;
- return 0;
-#else
-#if defined(HAVE_GETPEEREID)
- gid_t gid;
- return getpeereid(s, uid, &gid);
-#endif
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int sys_getnameinfo(const struct sockaddr *psa,
- socklen_t salen,
- char *host,
- size_t hostlen,
- char *service,
- size_t servlen,
- int flags)
-{
- /*
- * For Solaris we must make sure salen is the
- * correct length for the incoming sa_family.
- */
-
- if (salen == sizeof(struct sockaddr_storage)) {
- salen = sizeof(struct sockaddr_in);
-#if defined(HAVE_IPV6)
- if (psa->sa_family == AF_INET6) {
- salen = sizeof(struct sockaddr_in6);
- }
-#endif
- }
- return getnameinfo(psa, salen, host, hostlen, service, servlen, flags);
-}
-
-int sys_connect(int fd, const struct sockaddr * addr)
-{
- socklen_t salen = (socklen_t)-1;
-
- if (addr->sa_family == AF_INET) {
- salen = sizeof(struct sockaddr_in);
- } else if (addr->sa_family == AF_UNIX) {
- salen = sizeof(struct sockaddr_un);
- }
-#if defined(HAVE_IPV6)
- else if (addr->sa_family == AF_INET6) {
- salen = sizeof(struct sockaddr_in6);
- }
-#endif
-
- return connect(fd, addr, salen);
-}
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index daf91fef03..fa718590d7 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -28,157 +28,6 @@
#include "../lib/util/tevent_unix.h"
#include "../lib/util/tevent_ntstatus.h"
-/****************************************************************************
- Get a port number in host byte order from a sockaddr_storage.
-****************************************************************************/
-
-uint16_t get_sockaddr_port(const struct sockaddr_storage *pss)
-{
- uint16_t port = 0;
-
- if (pss->ss_family != AF_INET) {
-#if defined(HAVE_IPV6)
- /* IPv6 */
- const struct sockaddr_in6 *sa6 =
- (const struct sockaddr_in6 *)pss;
- port = ntohs(sa6->sin6_port);
-#endif
- } else {
- const struct sockaddr_in *sa =
- (const struct sockaddr_in *)pss;
- port = ntohs(sa->sin_port);
- }
- return port;
-}
-
-/****************************************************************************
- Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
-****************************************************************************/
-
-static char *print_sockaddr_len(char *dest,
- size_t destlen,
- const struct sockaddr *psa,
- socklen_t psalen)
-{
- if (destlen > 0) {
- dest[0] = '\0';
- }
- (void)sys_getnameinfo(psa,
- psalen,
- dest, destlen,
- NULL, 0,
- NI_NUMERICHOST);
- return dest;
-}
-
-/****************************************************************************
- Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
-****************************************************************************/
-
-char *print_sockaddr(char *dest,
- size_t destlen,
- const struct sockaddr_storage *psa)
-{
- return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa,
- sizeof(struct sockaddr_storage));
-}
-
-/****************************************************************************
- Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
-****************************************************************************/
-
-char *print_canonical_sockaddr(TALLOC_CTX *ctx,
- const struct sockaddr_storage *pss)
-{
- char addr[INET6_ADDRSTRLEN];
- char *dest = NULL;
- int ret;
-
- /* Linux getnameinfo() man pages says port is unitialized if
- service name is NULL. */
-
- ret = sys_getnameinfo((const struct sockaddr *)pss,
- sizeof(struct sockaddr_storage),
- addr, sizeof(addr),
- NULL, 0,
- NI_NUMERICHOST);
- if (ret != 0) {
- return NULL;
- }
-
- if (pss->ss_family != AF_INET) {
-#if defined(HAVE_IPV6)
- dest = talloc_asprintf(ctx, "[%s]", addr);
-#else
- return NULL;
-#endif
- } else {
- dest = talloc_asprintf(ctx, "%s", addr);
- }
-
- return dest;
-}
-
-/****************************************************************************
- Return the string of an IP address (IPv4 or IPv6).
-****************************************************************************/
-
-static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len)
-{
- struct sockaddr_storage sa;
- socklen_t length = sizeof(sa);
-
- /* Ok, returning a hard coded IPv4 address
- * is bogus, but it's just as bogus as a
- * zero IPv6 address. No good choice here.
- */
-
- strlcpy(addr_buf, "0.0.0.0", addr_len);
-
- if (fd == -1) {
- return addr_buf;
- }
-
- if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
- DEBUG(0,("getsockname failed. Error was %s\n",
- strerror(errno) ));
- return addr_buf;
- }
-
- return print_sockaddr_len(addr_buf, addr_len, (struct sockaddr *)&sa, length);
-}
-
-/****************************************************************************
- Return the port number we've bound to on a socket.
-****************************************************************************/
-
-int get_socket_port(int fd)
-{
- struct sockaddr_storage sa;
- socklen_t length = sizeof(sa);
-
- if (fd == -1) {
- return -1;
- }
-
- if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
- int level = (errno == ENOTCONN) ? 2 : 0;
- DEBUG(level, ("getsockname failed. Error was %s\n",
- strerror(errno)));
- return -1;
- }
-
-#if defined(HAVE_IPV6)
- if (sa.ss_family == AF_INET6) {
- return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port);
- }
-#endif
- if (sa.ss_family == AF_INET) {
- return ntohs(((struct sockaddr_in *)&sa)->sin_port);
- }
- return -1;
-}
-
const char *client_name(int fd)
{
return get_peer_name(fd,false);
@@ -189,11 +38,6 @@ const char *client_addr(int fd, char *addr, size_t addrlen)
return get_peer_addr(fd,addr,addrlen);
}
-const char *client_socket_addr(int fd, char *addr, size_t addr_len)
-{
- return get_socket_addr(fd, addr, addr_len);
-}
-
#if 0
/* Not currently used. JRA. */
int client_socket_port(int fd)