3 * - address-family specific code
6 * This file is part of adns, which is
7 * Copyright (C) 1997-2000,2003,2006 Ian Jackson
8 * Copyright (C) 1999-2000,2003,2006 Tony Finch
9 * Copyright (C) 1991 Massachusetts Institute of Technology
10 * (See the file INSTALL for full details.)
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
44 #define SIN(sa) ((struct sockaddr_in *)(sa))
46 static void *inet_sockaddr_to_inaddr(struct sockaddr *sa)
47 { return &SIN(sa)->sin_addr; }
49 static void inet_prefix_mask(int len, union gen_addr *mask)
50 { mask->v4.s_addr = htonl(!len ? 0 : 0xffffffff << (32 - len)); }
52 static int inet_guess_len(const union gen_addr *addr)
54 unsigned a = (ntohl(addr->v4.s_addr) >> 24) & 0xff;
56 if (a < 128) return 8;
57 else if (a < 192) return 16;
58 else if (a < 224) return 24;
62 static int inet_matchp(const union gen_addr *addr,
63 const union gen_addr *base,
64 const union gen_addr *mask)
65 { return (addr->v4.s_addr & mask->v4.s_addr) == base->v4.s_addr; }
67 const afinfo adns__inet_afinfo = {
69 inet_sockaddr_to_inaddr, inet_prefix_mask, inet_guess_len, inet_matchp
76 #define SIN6(sa) ((struct sockaddr_in6 *)(sa))
78 static void *inet6_sockaddr_to_inaddr(struct sockaddr *sa)
79 { return &SIN6(sa)->sin6_addr; }
81 static void inet6_prefix_mask(int len, union gen_addr *mask)
83 int i = len/8, j = len%8;
84 unsigned char *m = mask->v6.s6_addr;
88 if (j) m[i++] = (0xff << (8-j)) & 0xff;
89 memset(m + i, 0, 16-i);
92 static int inet6_guess_len(const union gen_addr *addr)
95 static int inet6_matchp(const union gen_addr *addr,
96 const union gen_addr *base,
97 const union gen_addr *mask)
100 const char *a = addr->v6.s6_addr;
101 const char *b = base->v6.s6_addr;
102 const char *m = mask->v6.s6_addr;
104 for (i = 0; i < 16; i++)
105 if ((a[i] & m[i]) != b[i]) return 0;
109 const afinfo adns__inet6_afinfo = {
111 inet6_sockaddr_to_inaddr, inet6_prefix_mask, inet6_guess_len, inet6_matchp