/*
* int zgetbindaddr(char *bindspec, Usockaddr *sap)
*/
/*
Parse first argument for the specification of IP v.4 or v.6
address or network interface. If NULL or empty, fallback to
the value of 'BINDADDR' ZENV variable. On success, return
zero, otherwise non-zero. That is, if the caller gets zero
code, it should bind() to the address returned in *sap, else
bind to INADDR_ANY.
Possible specification formats are:
[0.0.0.0]
[IPv6.0::0]
iface:eth0:1
Original copyright by Matti Aarnio <mea@nic.funet.fi> 1997,2000,
modifications by Eugene Crosser <crosser@average.org> 2002
*/
#include "hostenv.h"
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <sys/ioctl.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <netinet/in.h>
#ifdef HAVE_NETINET_IN6_H
# include <netinet/in6.h>
#endif
#ifdef HAVE_NETINET6_IN6_H
# include <netinet6/in6.h>
#endif
#ifdef HAVE_LINUX_IN6_H
# include <linux/in6.h>
#endif
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include "libc.h"
#include "zmalloc.h"
#include "libz.h"
#include "hostenv.h"
#include <arpa/inet.h>
#include <net/if.h>
int
zgetbindaddr(bindspec, af, sap)
char *bindspec;
const int af;
Usockaddr *sap;
{
int result = 0;
if ((bindspec == NULL) || (*bindspec == '\0'))
bindspec = (char *)getzenv("BINDADDR"); /* we modify this..*/
if ((bindspec == NULL) || (*bindspec == '\0'))
return 1; /* not specified - bind to INADDR_ANY */
#if defined(AF_INET6) && defined(INET6)
if (cistrncmp(bindspec, "[ipv6 ", 6) == 0 ||
cistrncmp(bindspec, "[ipv6:", 6) == 0 ||
cistrncmp(bindspec, "[ipv6.", 6) == 0) {
char *s = strchr(bindspec, ']');
if (s) *s = 0;
if (inet_pton
(AF_INET6, bindspec + 6, &sap->v6.sin6_addr) < 1) {
/* False IPv6 number literal */
/* ... then we don't set the IP address... */
result = 1;
}
sap->v6.sin6_family = AF_INET6;
} else
#endif
if (*bindspec == '[') {
char *s = strchr(bindspec, ']');
if (s) *s = 0;
if (inet_pton(AF_INET, bindspec + 1, &sap->v4.sin_addr) < 1) {
/* False IP(v4) number literal */
/* ... then we don't set the IP address... */
result = 1;
}
sap->v4.sin_family = AF_INET;
} else {
if (CISTREQN(bindspec, "iface:", 6)) {
#if defined(AF_INET6) && defined(INET6)
if (af == AF_INET6) {
sap->v6.sin6_family = AF_INET6;
if (zgetifaddress( AF_INET6, bindspec + 6, sap )) {
/* Didn't get IPv6 interface address of given name.. */
if (zgetifaddress( AF_INET6, bindspec + 6, sap )) {
/* No recognized interface! */
result = 1;
}
}
return result;
}
#endif
if (af == 0 || af == AF_INET) {
if (zgetifaddress( AF_INET, bindspec + 6, sap )) {
/* No recognized interface! */
result = 1;
}
return result;
}
} else {
/* XXX: TODO: Try to see if this is an interface name,
and pick IPv4 and/or IPv6 addresses for that
interface. */
result = 1;
}
}
return result;
}
syntax highlighted by Code2HTML, v. 0.9.1