3 * Address-type specific functionality
5 * (c) 2012 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Yet Another Ident Daemon (YAID).
12 * YAID 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 of the License, or
15 * (at your option) any later version.
17 * YAID 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 YAID; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 /*----- Header files ------------------------------------------------------*/
31 /*----- IPv4 addresses ----------------------------------------------------*/
33 static int addreq_ipv4(const union addr
*a
, const union addr
*b
)
34 { return a
->ipv4
.s_addr
== b
->ipv4
.s_addr
; }
36 static int match_addrpat_ipv4(const struct addrpat
*ap
, const union addr
*a
)
40 if (!ap
->len
) return (1);
41 m
= htonl((MASK32
<< (32 - ap
->len
)) & MASK32
);
42 return (((ap
->addr
.ipv4
.s_addr
^ a
->ipv4
.s_addr
) & m
) == 0);
45 static void socket_to_sockaddr_ipv4(const struct socket
*s
,
46 void *sa
, size_t *ssz
)
48 struct sockaddr_in
*sin
= sa
;
50 sin
->sin_family
= AF_INET
;
51 sin
->sin_addr
= s
->addr
.ipv4
;
52 sin
->sin_port
= htons(s
->port
);
56 static void sockaddr_to_addr_ipv4(const void *sa
, union addr
*a
)
57 { const struct sockaddr_in
*sin
= sa
; a
->ipv4
= sin
->sin_addr
; }
59 static int init_listen_socket_ipv4(int fd
) { return (0); }
61 static const union addr any_ipv4
= { .ipv4
.s_addr
= INADDR_ANY
};
63 /*----- IPv6 addresses ----------------------------------------------------*/
65 static int addreq_ipv6(const union addr
*a
, const union addr
*b
)
66 { return !memcmp(a
->ipv6
.s6_addr
, b
->ipv6
.s6_addr
, 16); }
68 static int match_addrpat_ipv6(const struct addrpat
*ap
, const union addr
*a
)
70 unsigned i
= 0, m
, n
= ap
->len
;
73 for (i
= 0; n
>= 8; i
++, n
-= 8)
74 if (ap
->addr
.ipv6
.s6_addr
[i
] != a
->ipv6
.s6_addr
[i
]) return (0);
76 m
= (MASK8
<< (8 - n
)) & MASK8
;
77 return (((ap
->addr
.ipv6
.s6_addr
[i
] ^ a
->ipv6
.s6_addr
[i
]) & m
) == 0);
80 static void socket_to_sockaddr_ipv6(const struct socket
*s
,
81 void *sa
, size_t *ssz
)
83 struct sockaddr_in6
*sin6
= sa
;
85 sin6
->sin6_family
= AF_INET6
;
86 sin6
->sin6_addr
= s
->addr
.ipv6
;
87 sin6
->sin6_port
= htons(s
->port
);
88 sin6
->sin6_flowinfo
= 0;
89 sin6
->sin6_scope_id
= 0;
93 static void sockaddr_to_addr_ipv6(const void *sa
, union addr
*a
)
94 { const struct sockaddr_in6
*sin6
= sa
; a
->ipv6
= sin6
->sin6_addr
; }
96 static int init_listen_socket_ipv6(int fd
)
100 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &yes
, sizeof(yes
)))
105 static const union addr any_ipv6
= { .ipv6
= IN6ADDR_ANY_INIT
};
107 /*----- General utilities -------------------------------------------------*/
109 int sockeq(const struct addrops
*ao
,
110 const struct socket
*sa
, const struct socket
*sb
)
111 { return (ao
->addreq(&sa
->addr
, &sb
->addr
) && sa
->port
== sb
->port
); }
113 void dputsock(dstr
*d
, const struct addrops
*ao
, const struct socket
*s
)
117 inet_ntop(ao
->af
, &s
->addr
, buf
, sizeof(buf
));
118 if (!s
->port
|| ao
->af
!= AF_INET6
) dstr_puts(d
, buf
);
119 else { dstr_putc(d
, '['); dstr_puts(d
, buf
); dstr_putc(d
, ']'); }
120 if (s
->port
) dstr_putf(d
, ":%d", s
->port
);
123 /*----- The operations table ----------------------------------------------*/
125 const struct addrops addroptab
[] = {
126 #define DEFOPS(ty, TY, af, name, len) \
127 { AF_##af, name, len, &any_##ty, &addrops_sys_##ty, \
128 addreq_##ty, match_addrpat_##ty, \
129 socket_to_sockaddr_##ty, sockaddr_to_addr_##ty, \
130 init_listen_socket_##ty },
136 /*----- That's all, folks -------------------------------------------------*/