extern aConfItem *find_conf (Link *, char*, int);
extern aConfItem *find_conf_exact (char *, char *, char *, int);
extern aConfItem *find_conf_host (Link *, char *, int);
-extern aConfItem *find_conf_ip (Link *, char *, char *, int);
+extern aConfItem *find_conf_ip (Link *, struct irc_addr *, char *, int);
extern aConfItem *find_conf_name (char *, int);
extern aConfItem *find_temp_conf_entry (aConfItem *, u_int);
extern aConfItem *find_conf_servern (char *);
extern char *rpl_str (int), *err_str (int);
extern char *strerror (int);
extern int dgets (int, char *, int);
-extern char *inetntoa (char *);
+extern char *inetntoa (const struct irc_addr *);
extern int dbufalloc, dbufblocks, debuglevel, errno, h_errno;
extern int highest_fd, debuglevel, portnum, debugtty, maxusersperchannel;
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, include/irc_addr.h
+ *
+ * Dual-stack (IPv4/IPv6) address abstraction.
+ * Replaces raw struct in_addr usage throughout the ircd.
+ */
+
+#ifndef __irc_addr_include__
+#define __irc_addr_include__
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+
+/* Large enough for any formatted address */
+#define IRC_ADDRSTRLEN INET6_ADDRSTRLEN
+
+/*
+ * irc_addr - holds either an IPv4 or IPv6 address.
+ * Used in Client, ConfItem, throttle records, and the resolver.
+ */
+struct irc_addr {
+ int family; /* AF_INET or AF_INET6 */
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ } addr;
+};
+
+/* Zero out an irc_addr */
+#define IRC_ADDR_ZERO(a) memset((a), 0, sizeof(struct irc_addr))
+
+/* Check if an irc_addr is all zeros (unset) */
+static inline int irc_addr_is_zero(const struct irc_addr *a)
+{
+ static const struct irc_addr zero;
+ return memcmp(a, &zero, sizeof(struct irc_addr)) == 0;
+}
+
+/* Compare two irc_addrs for equality */
+static inline int irc_addr_equal(const struct irc_addr *a, const struct irc_addr *b)
+{
+ if (a->family != b->family)
+ return 0;
+ if (a->family == AF_INET6)
+ return memcmp(&a->addr.v6, &b->addr.v6, sizeof(struct in6_addr)) == 0;
+ return a->addr.v4.s_addr == b->addr.v4.s_addr;
+}
+
+/* Copy an irc_addr */
+#define IRC_ADDR_COPY(dst, src) memcpy((dst), (src), sizeof(struct irc_addr))
+
+/* Format an irc_addr to a static buffer (not thread-safe, matches old inetntoa pattern) */
+static inline const char *irc_addr_str(const struct irc_addr *a)
+{
+ static char buf[IRC_ADDRSTRLEN];
+ if (a->family == AF_INET6)
+ inet_ntop(AF_INET6, &a->addr.v6, buf, sizeof(buf));
+ else
+ inet_ntop(AF_INET, &a->addr.v4, buf, sizeof(buf));
+ return buf;
+}
+
+/* Parse a string into an irc_addr. Returns 1 on success, 0 on failure. */
+static inline int irc_addr_from_str(struct irc_addr *a, const char *s)
+{
+ IRC_ADDR_ZERO(a);
+ if (strchr(s, ':')) {
+ a->family = AF_INET6;
+ return inet_pton(AF_INET6, s, &a->addr.v6) == 1;
+ }
+ a->family = AF_INET;
+ return inet_pton(AF_INET, s, &a->addr.v4) == 1;
+}
+
+/* Set an irc_addr from a sockaddr (v4 or v6) */
+static inline void irc_addr_from_sockaddr(struct irc_addr *a, const struct sockaddr *sa)
+{
+ IRC_ADDR_ZERO(a);
+ if (sa->sa_family == AF_INET6) {
+ a->family = AF_INET6;
+ memcpy(&a->addr.v6, &((struct sockaddr_in6 *)sa)->sin6_addr,
+ sizeof(struct in6_addr));
+ } else {
+ a->family = AF_INET;
+ memcpy(&a->addr.v4, &((struct sockaddr_in *)sa)->sin_addr,
+ sizeof(struct in_addr));
+ }
+}
+
+/* Check if address is loopback */
+static inline int irc_addr_is_loopback(const struct irc_addr *a)
+{
+ if (a->family == AF_INET6)
+ return IN6_IS_ADDR_LOOPBACK(&a->addr.v6);
+ return (ntohl(a->addr.v4.s_addr) >> 24) == 127;
+}
+
+/* Compute a hash byte from an irc_addr (for throttle table etc.) */
+static inline unsigned char irc_addr_hash(const struct irc_addr *a)
+{
+ const unsigned char *p;
+ unsigned char h = 0;
+ int len, i;
+
+ if (a->family == AF_INET6) {
+ p = (const unsigned char *)&a->addr.v6;
+ len = 16;
+ } else {
+ p = (const unsigned char *)&a->addr.v4;
+ len = 4;
+ }
+ for (i = 0; i < len; i++)
+ h ^= p[i];
+ return h;
+}
+
+/* Create an irc_addr from a raw struct in_addr (convenience for IPv4 code) */
+static inline struct irc_addr irc_addr_from_v4(const struct in_addr *v4)
+{
+ struct irc_addr a;
+ IRC_ADDR_ZERO(&a);
+ a.family = AF_INET;
+ memcpy(&a.addr.v4, v4, sizeof(struct in_addr));
+ return a;
+}
+
+#endif /* __irc_addr_include__ */
+
#include <netinet/in.h>
#include <netdb.h>
#include <stddef.h>
+#include "irc_addr.h"
#ifdef USE_SYSLOG
# include <syslog.h>
struct ConfItem {
unsigned int status; /* If CONF_ILLEGAL, delete when no clients */
int clients; /* Number of *LOCAL* clients using this */
- struct in_addr ipnum; /* ip number of host field */
+ struct irc_addr ipnum; /* ip number of host field */
char *host;
char *passwd;
char *name;
#ifdef ZIP_LINKS
aZdata *zip;
#endif
- struct in_addr ip; /* keep real ip# too */
+ struct irc_addr ip; /* keep real ip# too */
u_short port; /* and the remote port# too :-) */
struct hostent *hostp;
u_short notifies; /* Keep track of count of notifies */
#ifdef DEBUGMODE
aconfs.inuse++;
#endif
- memset ((char *) &aconf->ipnum, 0, sizeof (struct in_addr));
+ IRC_ADDR_ZERO (&aconf->ipnum);
aconf->next = NULL;
aconf->host = aconf->passwd = aconf->name = NULL;
aconf->status = CONF_ILLEGAL;
extern int highest_fd;
extern aClient *local[];
+/* Helper: format a raw in_addr for debug/log output (resolver is still IPv4-only) */
+static char *inetntoa_v4(const struct in_addr *in)
+{
+ struct irc_addr a = irc_addr_from_v4 (in);
+ return inetntoa (&a);
+}
+
static char hostbuf[HOSTLEN + 1];
static char dot[] = ".";
static int incache = 0;
memcpy ((char *) &dr, cp, dlen);
adr->s_addr = dr.s_addr;
Debug ((DEBUG_INFO, "got ip # %s for %s",
- inetntoa ((char *) adr), hostbuf));
+ inetntoa_v4 (adr), hostbuf));
if (!hp->h_name) {
hp->h_name = (char *) MyMalloc (len + 1);
(void) strcpy (hp->h_name, hostbuf);
struct hostent *hp2 = NULL;
Debug ((DEBUG_DNS, "relookup %s <-> %s",
- rptr->he.h_name, inetntoa ((char *) &rptr->he.h_addr)));
+ rptr->he.h_name, inetntoa_v4 (&rptr->he.h_addr)));
if (!rptr->he.h_name) {
char badip[128];
sprintf (badip, "%s (a = %d)",
- inetntoa ((char *) &rptr->he.h_addr), a);
+ inetntoa_v4 (&rptr->he.h_addr), a);
sendto_realops ("WARNING: Error in lookup of %s.", badip);
sendto_serv_butone (&me, ":%s GLOBOPS :Error in lookup of %s.",
cp = hashtable[hashv].num_list;
#ifdef DEBUG
Debug ((DEBUG_DNS, "find_cache_number:find %s[%08x]: hashv = %d",
- inetntoa (numb), ntohl (ip->s_addr), hashv));
+ inetntoa_v4 ((struct in_addr *) numb), ntohl (ip->s_addr), hashv));
#endif
for (; cp; cp = cp->hnum_next)
hashv = hash_number ((u_char *) hp->h_addr);
#ifdef DEBUG
Debug ((DEBUG_DEBUG, "rem_cache: h_addr %s hashv %d next %#x first %#x",
- inetntoa (hp->h_addr), hashv, ocp->hnum_next,
+ inetntoa_v4 ((struct in_addr *) hp->h_addr), hashv, ocp->hnum_next,
hashtable[hashv].num_list));
#endif
for (cp = &hashtable[hashv].num_list; *cp; cp = &((*cp)->hnum_next))
for (cp = cachetop; cp; cp = cp->list_next) {
sendto_one (sptr, "NOTICE %s :Ex %d ttl %d host %s(%s)",
parv[0], cp->expireat - time (NULL), cp->ttl,
- cp->he.h_name, inetntoa (cp->he.h_addr));
+ cp->he.h_name, inetntoa_v4 ((struct in_addr *) cp->he.h_addr));
for (i = 0; cp->he.h_aliases[i]; i++)
sendto_one (sptr, "NOTICE %s : %s = %s (CN)",
parv[0], cp->he.h_name, cp->he.h_aliases[i]);
for (i = 1; cp->he.h_addr_list[i]; i++)
sendto_one (sptr, "NOTICE %s : %s = %s (IP)",
parv[0], cp->he.h_name,
- inetntoa (cp->he.h_addr_list[i]));
+ inetntoa_v4 ((struct in_addr *) cp->he.h_addr_list[i]));
}
return 0;
}
if (port) {
server.sin_family = AF_INET;
/* per-port bindings, fixes /stats l */
- server.sin_addr.s_addr = inet_addr (ipname);
+ inet_pton (AF_INET, ipname, &server.sin_addr);
server.sin_port = htons (port);
/*
*/
if (cptr->fd > highest_fd)
highest_fd = cptr->fd;
- cptr->ip.s_addr = name ? inet_addr (ipname) : me.ip.s_addr;
+ if (name)
+ irc_addr_from_str (&cptr->ip, ipname);
+ else
+ IRC_ADDR_COPY (&cptr->ip, &me.ip);
cptr->port = (int) ntohs (server.sin_port);
(void) listen (cptr->fd, cfg_listen_size);
local[cptr->fd] = cptr;
report_error ("connect failure: %s %s", cptr);
return -1;
}
- (void) strcpy (sockn, (char *) inetntoa ((char *) &sk.sin_addr));
- if (inet_netof (sk.sin_addr) == IN_LOOPBACKNET) {
+ irc_addr_from_sockaddr (&cptr->ip, (struct sockaddr *) &sk);
+ (void) strcpy (sockn, (char *) inetntoa (&cptr->ip));
+ if (irc_addr_is_loopback (&cptr->ip)) {
cptr->hostp = NULL;
strncpyzt (sockn, me.sockhost, HOSTLEN);
}
- memcpy ((char *) &cptr->ip, (char *) &sk.sin_addr, sizeof (struct in_addr));
cptr->port = (int) ntohs (sk.sin_port);
return 0;
ClearAccess (cptr);
Debug ((DEBUG_DNS, "ch_cl: check access for %s[%s]",
- cptr->name, inetntoa ((char *) &cptr->ip)));
+ cptr->name, inetntoa (&cptr->ip)));
if (check_init (cptr, sockname))
return -2;
*/
if (hp) {
for (i = 0; hp->h_addr_list[i]; i++)
- if (!memcmp (hp->h_addr_list[i], (char *) &cptr->ip, sizeof (struct in_addr)))
+ if (!memcmp (hp->h_addr_list[i], (char *) &cptr->ip.addr.v4, sizeof (struct in_addr)))
break;
if (!hp->h_addr_list[i]) {
- sendto_ops ("IP# Mismatch: %s != %s[%08x]",
- inetntoa ((char *) &cptr->ip), hp->h_name,
- *((unsigned long *) hp->h_addr));
+ sendto_ops ("IP# Mismatch: %s != %s",
+ inetntoa (&cptr->ip), hp->h_name);
hp = NULL;
}
}
}
Debug ((DEBUG_DNS, "ch_cl: access ok: %s[%s]", cptr->name, sockname));
- if (inet_netof (cptr->ip) == IN_LOOPBACKNET || IsUnixSocket (cptr) ||
- inet_netof (cptr->ip) == inet_netof (mysk.sin_addr)) {
+ if (irc_addr_is_loopback (&cptr->ip) || IsUnixSocket (cptr)) {
ircstp->is_loc++;
cptr->flags |= FLAGS_LOCAL;
}
*/
if (hp) {
for (i = 0; hp->h_addr_list[i]; i++)
- if (!memcmp (hp->h_addr_list[i], (char *) &cptr->ip, sizeof (struct in_addr)))
+ if (!memcmp (hp->h_addr_list[i], (char *) &cptr->ip.addr.v4, sizeof (struct in_addr)))
break;
if (!hp->h_addr_list[i]) {
- sendto_ops ("IP# Mismatch: %s != %s[%08x]",
- inetntoa ((char *) &cptr->ip), hp->h_name,
- *((unsigned long *) hp->h_addr));
+ sendto_ops ("IP# Mismatch: %s != %s",
+ inetntoa (&cptr->ip), hp->h_name);
hp = NULL;
}
}
if (!hp) {
if (!c_conf)
c_conf =
- find_conf_ip (lp, (char *) &cptr->ip, cptr->username, CFLAG);
+ find_conf_ip (lp, &cptr->ip, cptr->username, CFLAG);
if (!n_conf)
n_conf =
- find_conf_ip (lp, (char *) &cptr->ip, cptr->username, NFLAG);
+ find_conf_ip (lp, &cptr->ip, cptr->username, NFLAG);
}
else
for (i = 0; hp->h_addr_list[i]; i++) {
+ struct irc_addr tmp_ip = irc_addr_from_v4 ((struct in_addr *) hp->h_addr_list[i]);
if (!c_conf)
c_conf =
- find_conf_ip (lp, hp->h_addr_list[i], cptr->username,
+ find_conf_ip (lp, &tmp_ip, cptr->username,
CFLAG);
if (!n_conf)
n_conf =
- find_conf_ip (lp, hp->h_addr_list[i], cptr->username,
+ find_conf_ip (lp, &tmp_ip, cptr->username,
NFLAG);
}
/*
(void) attach_conf (cptr, c_conf);
(void) attach_confs (cptr, name, CONF_HUB | CONF_UWORLD);
- if ((c_conf->ipnum.s_addr == -1) && !IsUnixSocket (cptr))
- memcpy ((char *) &c_conf->ipnum, (char *) &cptr->ip, sizeof (struct in_addr));
+ if (irc_addr_is_zero (&c_conf->ipnum) && !IsUnixSocket (cptr))
+ IRC_ADDR_COPY (&c_conf->ipnum, &cptr->ip);
if (!IsUnixSocket (cptr))
get_sockhost (cptr, c_conf->host);
/* Copy ascii address to 'sockhost' just in case. Then we
* have something valid to put into error messages...
*/
- get_sockhost (acptr, (char *) inetntoa ((char *) &addr.sin_addr));
- memcpy ((char *) &acptr->ip, (char *) &addr.sin_addr, sizeof (struct in_addr));
+ irc_addr_from_sockaddr (&acptr->ip, (struct sockaddr *) &addr);
+ get_sockhost (acptr, (char *) inetntoa (&acptr->ip));
/* Check for zaps -- Barubary */
if (find_zap (acptr, 0)) {
set_non_blocking (fd, acptr);
for (aconf2 = conf; aconf2; aconf2 = aconf2->next)
if (aconf2->status == CONF_CONNECT_SERVER &&
- (match (inetntoa ((char *) &addr.sin_addr), aconf2->host) == 0
- || match (inetntoa ((char *) &addr.sin_addr),
+ (match (inetntoa (&acptr->ip), aconf2->host) == 0
+ || match (inetntoa (&acptr->ip),
strchr (aconf2->host, '@') + 1) == 0))
break;
if (!aconf2) {
for (aconf2 = conf; aconf2; aconf2 = aconf2->next)
if (aconf2->status == CONF_NOCONNECT_SERVER &&
- (match (inetntoa ((char *) &addr.sin_addr), aconf2->host)
+ (match (inetntoa (&acptr->ip), aconf2->host)
== 0
- || match (inetntoa ((char *) &addr.sin_addr),
+ || match (inetntoa (&acptr->ip),
strchr (aconf2->host, '@') + 1) == 0))
break;
}
lin.flags = ASYNC_CLIENT;
lin.value.cptr = acptr;
- Debug ((DEBUG_DNS, "lookup %s", inetntoa ((char *) &addr.sin_addr)));
+ Debug ((DEBUG_DNS, "lookup %s", inetntoa (&acptr->ip)));
acptr->hostp = gethost_byaddr ((char *) &acptr->ip, &lin);
if (!acptr->hostp)
SetDNS (acptr);
int errtmp, len;
Debug ((DEBUG_NOTICE, "Connect to %s[%s] @%s",
- aconf->name, aconf->host, inetntoa ((char *) &aconf->ipnum)));
+ aconf->name, aconf->host, inetntoa (&aconf->ipnum)));
if ((c2ptr = find_server (aconf->name, NULL))) {
sendto_ops ("Server %s already present from %s",
* If we dont know the IP# for this host and itis a hostname and
* not a ip# string, then try and find the appropriate host record.
*/
- if ((!aconf->ipnum.s_addr)) {
+ if (irc_addr_is_zero (&aconf->ipnum)) {
Link lin;
lin.flags = ASYNC_CONNECT;
nextdnscheck = 1;
s = (char *) strchr (aconf->host, '@');
s++; /* should NEVER be NULL */
- if ((aconf->ipnum.s_addr = inet_addr (s)) == -1) {
- aconf->ipnum.s_addr = 0;
+ if (!irc_addr_from_str (&aconf->ipnum, s)) {
+ IRC_ADDR_ZERO (&aconf->ipnum);
hp = gethost_byname (s, &lin);
Debug ((DEBUG_NOTICE, "co_sv: hp %x ac %x na %s ho %s",
hp, aconf, aconf->name, s));
if (!hp)
return 0;
- memcpy ((char *) &aconf->ipnum, hp->h_addr, sizeof (struct in_addr));
+ aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
}
}
cptr = make_client (NULL, NULL);
}
get_sockhost (cptr, aconf->host);
server.sin_port = 0;
- server.sin_addr = me.ip;
+ server.sin_addr = me.ip.addr.v4;
server.sin_family = AF_INET;
/*
** Bind to a local IP# (with unknown port - let unix decide) so
** I had this on my Linux 1.1.88 --Run
*/
/* We do now. Virtual interface stuff --ns */
- if (me.ip.s_addr != INADDR_ANY)
+ if (!irc_addr_is_zero (&me.ip))
if (bind (cptr->fd, (struct sockaddr *) &server, sizeof (server)) ==
-1) {
report_error ("error binding to local port for %s:%s", cptr);
* conf line, whether as a result of the hostname lookup or the ip#
* being present instead. If we dont know it, then the connect fails.
*/
- if (isdigit (*aconf->host) && (aconf->ipnum.s_addr == -1))
- aconf->ipnum.s_addr = inet_addr (aconf->host);
- if (aconf->ipnum.s_addr == -1) {
+ if (isdigit (*aconf->host) && irc_addr_is_zero (&aconf->ipnum))
+ irc_addr_from_str (&aconf->ipnum, aconf->host);
+ if (irc_addr_is_zero (&aconf->ipnum)) {
hp = cptr->hostp;
if (!hp) {
Debug ((DEBUG_FATAL, "%s: unknown host", aconf->host));
return NULL;
}
- memcpy ((char *) &aconf->ipnum, hp->h_addr, sizeof (struct in_addr));
+ aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
}
- memcpy ((char *) &server.sin_addr, (char *) &aconf->ipnum, sizeof (struct in_addr));
- memcpy ((char *) &cptr->ip, (char *) &aconf->ipnum, sizeof (struct in_addr));
+ memcpy ((char *) &server.sin_addr, (char *) &aconf->ipnum.addr.v4, sizeof (struct in_addr));
+ IRC_ADDR_COPY (&cptr->ip, &aconf->ipnum);
server.sin_port = htons (((aconf->port > 0) ? aconf->port : portnum));
*lenp = sizeof (server);
return (struct sockaddr *) &server;
int on = 1;
memset ((char *) &from, 0, sizeof (from));
- from.sin_addr = me.ip;
+ from.sin_addr = me.ip.addr.v4;
from.sin_port = htons (7007);
from.sin_family = AF_INET;
case ASYNC_CONNECT:
aconf = ln.value.aconf;
if (hp && aconf) {
- memcpy ((char *) &aconf->ipnum, hp->h_addr, sizeof (struct in_addr));
+ aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
(void) connect_server (aconf, NULL, hp);
}
else
case ASYNC_CONF:
aconf = ln.value.aconf;
if (hp && aconf)
- memcpy ((char *) &aconf->ipnum, hp->h_addr, sizeof (struct in_addr));
+ aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
break;
case ASYNC_SERVER:
cptr = ln.value.cptr;
cptr = ln.value.cptr;
del_queries ((char *) cptr);
if (hp) {
- memcpy (&cptr->ip, hp->h_addr, sizeof (struct in_addr));
+ cptr->ip = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
if (ping_server (cptr, hp) != -1)
break;
}
* Find a conf line using the IP# stored in it to search upon.
* Added 1/8/92 by Avalon.
*/
-aConfItem * find_conf_ip (Link *lp, char *ip, char *user, int statmask)
+aConfItem * find_conf_ip (Link *lp, struct irc_addr *ip, char *user, int statmask)
{
aConfItem *tmp;
char *s;
continue;
}
*s = '@';
- if (!memcmp ((char *) &tmp->ipnum, ip, sizeof (struct in_addr)))
+ if (irc_addr_equal (&tmp->ipnum, ip))
return tmp;
}
return NULL;
if (me.name[0] == '\0' && aconf->host[0])
strncpyzt (me.name, aconf->host, sizeof (me.name));
if (aconf->passwd[0] && (aconf->passwd[0] != '*'))
- me.ip.s_addr = inet_addr (aconf->passwd);
+ irc_addr_from_str (&me.ip, aconf->passwd);
else
- me.ip.s_addr = INADDR_ANY;
+ IRC_ADDR_ZERO (&me.ip);
if (portnum < 0 && aconf->port >= 0)
portnum = aconf->port;
}
ln.value.aconf = aconf;
ln.flags = ASYNC_CONF;
- if (isdigit (*s))
- aconf->ipnum.s_addr = inet_addr (s);
+ if (isdigit (*s)) {
+ if (!irc_addr_from_str (&aconf->ipnum, s))
+ goto badlookup;
+ }
else if ((hp = gethost_byname (s, &ln)))
- memcpy ((char *) &(aconf->ipnum), hp->h_addr, sizeof (struct in_addr));
+ aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
- if (aconf->ipnum.s_addr == -1)
+ if (irc_addr_is_zero (&aconf->ipnum) && isdigit (*s))
goto badlookup;
return 0;
badlookup:
- if (aconf->ipnum.s_addr == -1)
- memset ((char *) &aconf->ipnum, 0, sizeof (struct in_addr));
+ IRC_ADDR_ZERO (&aconf->ipnum);
Debug ((DEBUG_ERROR, "Host/server name error: (%s) (%s)",
aconf->host, aconf->name));
return -1;
host = cptr->sockhost;
name = cptr->user->username;
- strncpy (ipaddy, inetntoa ((char *) &(cptr->ip)), HOSTLEN);
+ strncpy (ipaddy, inetntoa (&cptr->ip), HOSTLEN);
if (strlen (host) > (size_t) HOSTLEN ||
(name ? strlen (name) : 0) > (size_t) HOSTLEN)
char *retval = NULL;
char ipaddy[HOSTLEN + 1];
- strncpy (ipaddy, inetntoa ((char *) &cptr->ip), HOSTLEN);
+ strncpy (ipaddy, inetntoa (&cptr->ip), HOSTLEN);
for (tmp = conf; tmp; tmp = tmp->next)
if ((tmp->status == CONF_ZAP) && tmp->host
if (!dokillmsg && retval) {
sprintf (zlinebuf,
"ERROR :Closing Link: [%s] (You are not welcome on "
- "this server: %s.\r\n", inetntoa ((char *) &cptr->ip),
+ "this server: %s.\r\n", inetntoa (&cptr->ip),
retval);
retval = zlinebuf;
}
me.name, sptr->name);
return -1;
}
- strcpy (userhost, inetntoa ((char *) &acptr->ip));
+ strcpy (userhost, inetntoa (&acptr->ip));
person = &acptr->name[0];
acptr = NULL;
}
(void) sprintf (nbuf, "%s[%s@%s.%u]",
sptr->name,
sptr->username,
- inetntoa ((char *) &sptr->ip),
+ inetntoa (&sptr->ip),
(unsigned int) sptr->port);
else {
if (mycmp (sptr->name, sptr->sockhost))
return;
}
-extern u_long inet_addr ();
+/* inet_addr() provided by arpa/inet.h via struct.h */
void end_ping ();
void cancel_ping ();
if (!(cptr->acpt))
return -1;
- memcpy ((char *) &remote_addr.sin_addr, (char *) &cptr->ip, sizeof (struct in_addr));
+ memcpy ((char *) &remote_addr.sin_addr, (char *) &cptr->ip.addr.v4, sizeof (struct in_addr));
remote_addr.sin_port = htons (cptr->port);
remote_addr.sin_family = AF_INET;
"Sending %d ping%s to %s[%s] port %d",
cptr->hopcount,
(cptr->hopcount == 1) ? "" : "s", cptr->name,
- inetntoa ((char *) &remote_addr.sin_addr),
+ inetntoa (&cptr->ip),
ntohs (remote_addr.sin_port));
cptr->firsttime = time (NULL) + UPINGTIMEOUT;
struct sockaddr_in remote_addr;
struct timeval tv;
- memcpy ((char *) &remote_addr.sin_addr, (char *) &cptr->ip, sizeof (struct in_addr));
+ memcpy ((char *) &remote_addr.sin_addr, (char *) &cptr->ip.addr.v4, sizeof (struct in_addr));
remote_addr.sin_port = htons (cptr->port);
remote_addr.sin_family = AF_INET;
Debug ((DEBUG_SEND, "send_ping: sending [%s %s] to %s.%d on %d",
(char *) cptr->confs, (char *) cptr->confs + 12,
- inetntoa ((char *) &remote_addr.sin_addr),
+ inetntoa (&cptr->ip),
ntohs (remote_addr.sin_port), cptr->fd));
if (sendto (cptr->fd, (char *) cptr->confs, 1024, 0,
unsigned long int pingtime;
char *s;
- memcpy ((char *) &remote_addr.sin_addr, (char *) &cptr->ip, sizeof (struct in_addr));
+ memcpy ((char *) &remote_addr.sin_addr, (char *) &cptr->ip.addr.v4, sizeof (struct in_addr));
remote_addr.sin_port = htons (cptr->port);
remote_addr.sin_family = AF_INET;
int ping_server (aClient *cptr, struct hostent *hp)
{
- if ((!cptr->ip.s_addr)) {
+ if (irc_addr_is_zero (&cptr->ip)) {
struct hostent *hp;
char *s;
Link lin;
nextdnscheck = 1;
s = (char *) strchr (cptr->sockhost, '@');
s++; /* should never be NULL; cptr->sockhost is actually a conf->host */
- if ((cptr->ip.s_addr = inet_addr (s)) == -1) {
- cptr->ip.s_addr = 0;
+ if (!irc_addr_from_str (&cptr->ip, s)) {
+ IRC_ADDR_ZERO (&cptr->ip);
hp = gethost_byname (s, &lin);
Debug ((DEBUG_NOTICE, "ping_sv: hp %x ac %x ho %s", hp, cptr, s));
if (!hp)
return 0;
- memcpy ((char *) &cptr->ip, hp->h_addr, sizeof (struct in_addr));
+ cptr->ip = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
}
}
return start_ping (cptr);
strcpy (cptr->sockhost, aconf->host);
cptr->acpt = sptr;
SetAskedPing (sptr);
- memcpy ((void *) &cptr->ip, (void *) &aconf->ipnum, sizeof (struct in_addr));
+ IRC_ADDR_COPY (&cptr->ip, &aconf->ipnum);
strcpy (cptr->name, aconf->name);
cptr->firsttime = 0;
SetPing (cptr);
struct aThrottle
{ /* this is a throttle record */
- struct in_addr ip;
+ struct irc_addr ip;
time_t last;
struct aThrottle *next;
char *connected;
static void remove_clone_check (aClient * cptr)
{
- unsigned char *p = (unsigned char *) &cptr->ip.s_addr;
struct aThrottle *ptr =
- throttles[(p[0] + p[1] + p[2] + p[3]) & 0xff];
+ throttles[irc_addr_hash (&cptr->ip)];
- if (cptr->ip.s_addr == 0)
+ if (irc_addr_is_zero (&cptr->ip))
return;
- while (ptr && (cptr->ip.s_addr != ptr->ip.s_addr))
+ while (ptr && !irc_addr_equal (&cptr->ip, &ptr->ip))
ptr = ptr->next;
if (ptr && (ptr->count > 1))
int check_clones (aClient * cptr, const char *remote)
{
struct aThrottle **tscn, *tptr;
- unsigned char *p = (unsigned char *) &cptr->ip.s_addr;
- unsigned char hval = (unsigned char) (p[0] ^ p[1] ^ p[2] ^ p[3]) & 0xFF;
+ unsigned char hval = irc_addr_hash (&cptr->ip);
tscn = &throttles[hval];
- if (cptr->ip.s_addr == 0)
+ if (irc_addr_is_zero (&cptr->ip))
return 0;
- while (*tscn && (cptr->ip.s_addr != (*tscn)->ip.s_addr)) {
+ while (*tscn && !irc_addr_equal (&cptr->ip, &(*tscn)->ip)) {
if ((*tscn)->last + cfg_clone_period < now) {
tptr = *tscn;
*tscn = tptr->next;
int ret = exit_client (cptr, sptr, sptr,
"Your host/ip has been throttled");
static char hostip[128];
- strcpy (hostip, inetntoa ((char *) &sptr->ip));
+ strcpy (hostip, inetntoa (&sptr->ip));
if (!ZLineExists (hostip)) {
add_temp_conf (CONF_ZAP, hostip,
"Too_many_connection_attempts_from_your_IP_address",
for (tmpstr = sptr->sockhost; *tmpstr > ' ' && *tmpstr < 127;
tmpstr++);
if (*tmpstr || !*user->host || isdigit (*(tmpstr - 1)))
- strncpyzt (sptr->sockhost, (char *) inetntoa ((char *) &sptr->ip), sizeof (sptr->sockhost)); /* Fix the sockhost for debug jic */
+ strncpyzt (sptr->sockhost, (char *) inetntoa (&sptr->ip), sizeof (sptr->sockhost)); /* Fix the sockhost for debug jic */
strncpyzt (user->host, sptr->sockhost, sizeof (sptr->sockhost));
}
else /* Failsafe point, don't let the user define their
nextping = time (NULL);
sendto_umode (UMODE_OPER | UMODE_CLIENT,
"*** Notice -- Client connecting on port %d: %s (%s@%s) [%s] [%s/%s]",
- sptr->acpt->port, nick, user->username, user->host, inetntoa ((char *) &sptr->ip), sptr->sup_host, sptr->sup_server);
+ sptr->acpt->port, nick, user->username, user->host, inetntoa (&sptr->ip), sptr->sup_host, sptr->sup_server);
}
else if (IsServer (cptr)) {
aClient *acptr;
if (!(aconf = find_conf_exact (name, sptr->user->username, sptr->sockhost,
CONF_OPS)) &&
!(aconf = find_conf_exact (name, sptr->user->username,
- inetntoa ((char *) &cptr->ip),
+ inetntoa (&cptr->ip),
CONF_OPS))) {
sendto_one (sptr, err_str (ERR_NOOPERHOST), me.name, parv[0]);
sendto_realops ("Failed OPER attempt by %s (%s@%s)",
#endif /* HAVE_STRTOKEN */
/*
- ** inetntoa -- changed name to remove collision possibility and
- ** so behaviour is guaranteed to take a pointer arg.
- ** -avalon 23/11/92
+ ** inetntoa -- format an irc_addr to a static string buffer.
+ ** Supports both IPv4 and IPv6 addresses.
*/
-char * inetntoa (char *in)
+char * inetntoa (const struct irc_addr *addr)
{
- static char buf[16];
- u_char *s = (u_char *) in;
- int a, b, c, d;
-
- a = (int) *s++;
- b = (int) *s++;
- c = (int) *s++;
- d = (int) *s++;
- (void) sprintf (buf, "%d.%d.%d.%d", a, b, c, d);
-
+ static char buf[IRC_ADDRSTRLEN];
+ if (addr->family == AF_INET6)
+ inet_ntop (AF_INET6, &addr->addr.v6, buf, sizeof (buf));
+ else
+ inet_ntop (AF_INET, &addr->addr.v4, buf, sizeof (buf));
return buf;
}
ip = ipaddress;
if (MyClient (cptr))
- ip = inetntoa ((char *) &cptr->ip);
+ ip = inetntoa (&cptr->ip);
else {
strncpyzt (ip, "<n/a>", 6);
ip = ipaddress;