mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
lib/util Move more network utility functions from source3 into lib/util
This will help with the merge of the interfaces layer. Andrew Bartlett
This commit is contained in:
parent
85fa87ea82
commit
fbea52f74a
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
**/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user