1 /* source: xio-ip4.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this file contains the source for IP4 related functions */
7 #include "xiosysincludes.h"
12 #include "xio-socket.h"
17 int xioparsenetwork_ip4(const char *rangename
, struct xiorange
*range
) {
18 struct in_addr
*netaddr_in
= &range
->netaddr
.ip4
.sin_addr
;
19 struct in_addr
*netmask_in
= &range
->netmask
.ip4
.sin_addr
;
20 char *rangename1
; /* a copy of rangename with writing allowed */
21 char *delimpos
; /* absolute address of delimiter */
22 unsigned int bits
; /* netmask bits */
23 union sockaddr_union sau
;
24 socklen_t socklen
= sizeof(sau
);
27 if ((rangename1
= strdup(rangename
)) == NULL
) {
28 Error1("strdup(\"%s\"): out of memory", rangename
);
29 return STAT_RETRYLATER
;
32 if (delimpos
= strchr(rangename1
, '/')) {
34 bits
= strtoul(delimpos
+1, &endptr
, 10);
35 if (! ((*(delimpos
+1) != '\0') && (*endptr
== '\0'))) {
36 Error1("not a valid netmask in \"%s\"", rangename
);
37 bits
= 32; /* most secure selection */
38 } else if (bits
> 32) {
39 Error1("netmask \"%s\" is too large", rangename
);
43 netmask_in
->s_addr
= 0;
45 netmask_in
->s_addr
= htonl((0xffffffff << (32-bits
)));
47 } else if (delimpos
= strchr(rangename1
, ':')) {
48 if ((rc
= xiogetaddrinfo(delimpos
+1, NULL
, PF_UNSPEC
, 0, 0,
49 &sau
, &socklen
, 0, 0))
53 netmask_in
->s_addr
= sau
.ip4
.sin_addr
.s_addr
;
55 Error1("xioparsenetwork_ip4(\"%s\",,): missing netmask delimiter", rangename
);
61 if ((rc
= xiogetaddrinfo(rangename1
, NULL
, PF_UNSPEC
, 0, 0,
62 &sau
, &socklen
, 0, 0))
66 netaddr_in
->s_addr
= sau
.ip4
.sin_addr
.s_addr
;
72 /* check if peer address is within permitted range.
74 int xiocheckrange_ip4(struct sockaddr_in
*pa
, struct xiorange
*range
) {
75 struct in_addr
*netaddr_in
= &range
->netaddr
.ip4
.sin_addr
;
76 struct in_addr
*netmask_in
= &range
->netmask
.ip4
.sin_addr
;
77 char addrbuf
[256], maskbuf
[256];
80 /* is provided client address valid? */
81 if (pa
->sin_addr
.s_addr
== 0) {
82 Warn("invalid client address 0.0.0.0");
85 /* client address restriction */
86 Debug2("permitted client subnet: %s:%s",
87 inet4addr_info(ntohl(netaddr_in
->s_addr
), addrbuf
, sizeof(addrbuf
)),
88 inet4addr_info(ntohl(netmask_in
->s_addr
), maskbuf
, sizeof(maskbuf
)));
89 Debug1("client address is 0x%08x",
90 ntohl(pa
->sin_addr
.s_addr
));
91 Debug1("masked address is 0x%08x",
92 ntohl(pa
->sin_addr
.s_addr
& netmask_in
->s_addr
));
93 if ((pa
->sin_addr
.s_addr
& netmask_in
->s_addr
)
94 != netaddr_in
->s_addr
) {
95 Debug1("client address %s is not permitted",
96 sockaddr_inet4_info(pa
, peername
, sizeof(peername
)));
102 /* returns information that can be used for constructing an environment
103 variable describing the socket address.
104 if idx is 0, this function writes "ADDR" into namebuff and the IP address
105 into valuebuff, and returns 1 (which means that one more info is there).
106 if idx is 1, it writes "PORT" into namebuff and the port number into
107 valuebuff, and returns 0 (no more info)
108 namelen and valuelen contain the max. allowed length of output chars in the
110 on error this function returns -1.
113 xiosetsockaddrenv_ip4(int idx
, char *namebuff
, size_t namelen
,
114 char *valuebuff
, size_t valuelen
,
115 struct sockaddr_in
*sa
, int ipproto
) {
118 strcpy(namebuff
, "ADDR");
119 inet4addr_info(ntohl(sa
->sin_addr
.s_addr
), valuebuff
, valuelen
);
126 return 1; /* there is port information to also be retrieved */
128 return 0; /* no port info coming */
131 strcpy(namebuff
, "PORT");
132 snprintf(valuebuff
, valuelen
, "%u", ntohs(sa
->sin_port
));
138 #endif /* WITH_IP4 */