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