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 #define ADDRFAM_IPV4 AF_INET
34 #define NAME_IPV4 "IPv4"
35 #define ADDRLEN_IPV4 32
37 static int addreq_ipv4(const union addr
*a
, const union addr
*b
)
38 { return a
->ipv4
.s_addr
== b
->ipv4
.s_addr
; }
40 static int match_addrpat_ipv4(const struct addrpat
*ap
, const union addr
*a
)
44 if (!ap
->len
) return (1);
45 m
= htonl((MASK32
<< (32 - ap
->len
)) & MASK32
);
46 return (((ap
->addr
.ipv4
.s_addr
^ a
->ipv4
.s_addr
) & m
) == 0);
49 static void socket_to_sockaddr_ipv4(const struct socket
*s
,
50 void *sa
, size_t *ssz
)
52 struct sockaddr_in
*sin
= sa
;
54 sin
->sin_family
= AF_INET
;
55 sin
->sin_addr
= s
->addr
.ipv4
;
56 sin
->sin_port
= htons(s
->port
);
60 static void sockaddr_to_addr_ipv4(const void *sa
, union addr
*a
)
61 { const struct sockaddr_in
*sin
= sa
; a
->ipv4
= sin
->sin_addr
; }
63 static int init_listen_socket_ipv4(int fd
) { return (0); }
65 static const union addr any_ipv4
= { .ipv4
.s_addr
= INADDR_ANY
};
67 /*----- IPv6 addresses ----------------------------------------------------*/
69 #define ADDRFAM_IPV6 AF_INET6
70 #define NAME_IPV6 "IPv6"
71 #define ADDRLEN_IPV6 128
73 static int addreq_ipv6(const union addr
*a
, const union addr
*b
)
74 { return !memcmp(a
->ipv6
.s6_addr
, b
->ipv6
.s6_addr
, 16); }
76 static int match_addrpat_ipv6(const struct addrpat
*ap
, const union addr
*a
)
78 unsigned i
= 0, m
, n
= ap
->len
;
81 for (i
= 0; n
>= 8; i
++, n
-= 8)
82 if (ap
->addr
.ipv6
.s6_addr
[i
] != a
->ipv6
.s6_addr
[i
]) return (0);
84 m
= (MASK8
<< (8 - n
)) & MASK8
;
85 return (((ap
->addr
.ipv6
.s6_addr
[i
] ^ a
->ipv6
.s6_addr
[i
]) & m
) == 0);
88 static void socket_to_sockaddr_ipv6(const struct socket
*s
,
89 void *sa
, size_t *ssz
)
91 struct sockaddr_in6
*sin6
= sa
;
93 sin6
->sin6_family
= AF_INET6
;
94 sin6
->sin6_addr
= s
->addr
.ipv6
;
95 sin6
->sin6_port
= htons(s
->port
);
96 sin6
->sin6_flowinfo
= 0;
97 sin6
->sin6_scope_id
= 0;
101 static void sockaddr_to_addr_ipv6(const void *sa
, union addr
*a
)
102 { const struct sockaddr_in6
*sin6
= sa
; a
->ipv6
= sin6
->sin6_addr
; }
104 static int init_listen_socket_ipv6(int fd
)
108 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &yes
, sizeof(yes
)))
113 static const union addr any_ipv6
= { .ipv6
= IN6ADDR_ANY_INIT
};
115 /*----- General utilities -------------------------------------------------*/
117 /* Answer whether the sockets SA and SB are equal. */
118 int sockeq(const struct addrops
*ao
,
119 const struct socket
*sa
, const struct socket
*sb
)
120 { return (ao
->addreq(&sa
->addr
, &sb
->addr
) && sa
->port
== sb
->port
); }
122 /* Write a textual description of S to the string D. */
123 void dputsock(dstr
*d
, const struct addrops
*ao
, const struct socket
*s
)
127 inet_ntop(ao
->af
, &s
->addr
, buf
, sizeof(buf
));
128 if (!s
->port
|| ao
->af
!= AF_INET6
) dstr_puts(d
, buf
);
129 else { dstr_putc(d
, '['); dstr_puts(d
, buf
); dstr_putc(d
, ']'); }
130 if (s
->port
) dstr_putf(d
, ":%d", s
->port
);
133 /*----- The operations table ----------------------------------------------*/
135 const struct addrops addroptab
[] = {
136 #define DEFOPS(ty, TY) \
137 { ADDRFAM_##TY, NAME_##TY, ADDRLEN_##TY, \
138 &any_##ty, &addrops_sys_##ty, \
139 addreq_##ty, match_addrpat_##ty, \
140 socket_to_sockaddr_##ty, sockaddr_to_addr_##ty, \
141 init_listen_socket_##ty },
147 /*----- That's all, folks -------------------------------------------------*/