}
return -1;
}
+
+/** Convert IP addresses to canonical form for comparison. 6to4 addresses
+ * are converted to IPv4 addresses. All other addresses are left alone.
+ * @param[out] out Receives canonical format for address.
+ * @param[in] in IP address to canonicalize.
+ */
+void ip_canonicalize_6to4(struct irc_in_addr *out, const struct irc_in_addr *in)
+{
+ if (in->in6_16[0] == htons(0x2002)) {
+ out->in6_16[0] = out->in6_16[1] = out->in6_16[2] = 0;
+ out->in6_16[3] = out->in6_16[4] = 0;
+ out->in6_16[5] = 0xffff;
+ out->in6_16[6] = in->in6_16[1];
+ out->in6_16[7] = in->in6_16[2];
+ } else
+ memcpy(out, in, sizeof(*out));
+}
+
#define ircd_aton(ADDR, STR) ipmask_parse((STR), (ADDR), NULL)
extern int ipmask_parse(const char *in, struct irc_in_addr *mask, unsigned char *bits_ptr);
extern int ipmask_check(const struct irc_in_addr *, const struct irc_in_addr *, unsigned char);
+void ip_canonicalize_6to4(struct irc_in_addr *out, const struct irc_in_addr *in);
#define IPtostr(ipaddr) ircd_ntoa(&(ipaddr))
#define irc_in_addr_v4_to_int(ADDR) ((ntohs((ADDR)->in6_16[6]) << 16) | ntohs((ADDR)->in6_16[7]))
time_t timestamp;
time_t accountts;
sstring *away;
+ struct irc_in_addr ipaddress;
patricia_node_t *ipnode;
unsigned int marker;
struct nick *next;
void *exts[MAXNICKEXTS];
} nick;
-#define p_ipaddr ipnode->prefix->sin
+#define p_ipaddr ipaddress
#define NICKHASHSIZE 60000
#define HOSTHASHSIZE 40000
char *fakehost;
char *accountts;
char *accountflags;
- struct irc_in_addr ipaddress;
+ struct irc_in_addr ipaddress, ipaddress_canonical;
char *accountid;
unsigned long userid;
np->realname->nicks=np;
np->timestamp=timestamp;
- base64toip(cargv[cargc-3], &ipaddress);
- np->ipnode = refnode(iptree, &ipaddress, PATRICIA_MAXBITS);
+ memcpy(&(np->ipaddress), &ipaddress, sizeof(ipaddress));
+
+ ip_canonicalize_6to4(&ipaddress_canonical, &ipaddress);
+ np->ipnode = refnode(iptree, &ipaddress_canonical, irc_in_addr_is_ipv4(&ipaddress) ? 128 : 64);
node_increment_usercount(np->ipnode);
np->away=NULL;
uint32_t host;
trusthost *th;
void *arg[2];
+ struct irc_in_addr ipaddress;
- host = irc_in_addr_v4_to_int(&sender->p_ipaddr);
- th = th_getbyhost(host);
+ ip_canonicalize_6to4(&ipaddress, &sender->p_ipaddr);
+
+ if (irc_in_addr_is_ipv4(&ipaddress)) {
+ host = irc_in_addr_v4_to_int(&ipaddress);
+ th = th_getbyhost(host);
+ } else
+ th = NULL;
settrusthost(sender, th);
if(!th) {