add listen-timeout to function as an accept timeout
[socat/sam.git] / xio-ip4.c
blob076ce1f3b45a9825c51466d6f5234edaf7508b43
1 /* source: xio-ip4.c */
2 /* Copyright Gerhard Rieger 2001-2008 */
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"
9 #if WITH_IP4
11 #include "xioopen.h"
12 #include "xio-socket.h"
13 #include "xio-ip.h"
14 #include "xio-ip4.h"
17 int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) {
18 struct hostent *maskaddr;
19 struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
20 struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
21 char *rangename1; /* a copy of rangename with writing allowed */
22 char *delimpos; /* absolute address of delimiter */
23 int bits;
25 if ((rangename1 = strdup(rangename)) == NULL) {
26 Error1("strdup(\"%s\"): out of memory", rangename);
27 return STAT_RETRYLATER;
30 if (delimpos = strchr(rangename1, '/')) {
31 bits = strtoul(delimpos+1, NULL, 10);
32 netmask_in->s_addr = htonl((0xffffffff << (32-bits)));
33 } else if (delimpos = strchr(rangename1, ':')) {
34 if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) {
35 /* note: cast is req on AIX: */
36 Error2("gethostbyname(\"%s\"): %s", delimpos+1,
37 h_errno == NETDB_INTERNAL ? strerror(errno) :
38 (char *)hstrerror(h_errno));
39 return STAT_NORETRY;
41 netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0];
42 } else {
43 Error1("xioparsenetwork_ip4(\"%s\",,): missing netmask delimiter", rangename);
44 free(rangename1);
45 return STAT_NORETRY;
48 struct hostent *nameaddr;
49 *delimpos = 0;
50 if ((nameaddr = Gethostbyname(rangename1)) == NULL) {
51 /* note: cast is req on AIX: */
52 Error2("gethostbyname(\"%s\"): %s", rangename1,
53 h_errno == NETDB_INTERNAL ? strerror(errno) :
54 (char *)hstrerror(h_errno));
55 free(rangename1);
56 return STAT_NORETRY;
58 netaddr_in->s_addr = *(unsigned long *)nameaddr->h_addr_list[0];
60 free(rangename1);
61 return STAT_OK;
64 /* check if peer address is within permitted range.
65 return >= 0 if so. */
66 int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange *range) {
67 struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
68 struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
69 char addrbuf[256], maskbuf[256];
70 char peername[256];
72 /* is provided client address valid? */
73 if (pa->sin_addr.s_addr == 0) {
74 Warn("invalid client address 0.0.0.0");
75 return -1;
77 /* client address restriction */
78 Debug2("permitted client subnet: %s:%s",
79 inet4addr_info(ntohl(netaddr_in->s_addr), addrbuf, sizeof(addrbuf)),
80 inet4addr_info(ntohl(netmask_in->s_addr), maskbuf, sizeof(maskbuf)));
81 Debug1("client address is 0x%08x",
82 ntohl(pa->sin_addr.s_addr));
83 Debug1("masked address is 0x%08x",
84 ntohl(pa->sin_addr.s_addr & netmask_in->s_addr));
85 if ((pa->sin_addr.s_addr & netmask_in->s_addr)
86 != netaddr_in->s_addr) {
87 Debug1("client address %s is not permitted",
88 sockaddr_inet4_info(pa, peername, sizeof(peername)));
89 return -1;
91 return 0;
94 /* returns information that can be used for constructing an environment
95 variable describing the socket address.
96 if idx is 0, this function writes "ADDR" into namebuff and the IP address
97 into valuebuff, and returns 1 (which means that one more info is there).
98 if idx is 1, it writes "PORT" into namebuff and the port number into
99 valuebuff, and returns 0 (no more info)
100 namelen and valuelen contain the max. allowed length of output chars in the
101 respective buffer.
102 on error this function returns -1.
105 xiosetsockaddrenv_ip4(int idx, char *namebuff, size_t namelen,
106 char *valuebuff, size_t valuelen,
107 struct sockaddr_in *sa, int ipproto) {
108 switch (idx) {
109 case 0:
110 strcpy(namebuff, "ADDR");
111 strcpy(valuebuff,
112 inet4addr_info(ntohl(sa->sin_addr.s_addr), valuebuff, valuelen));
113 switch (ipproto) {
114 case IPPROTO_TCP:
115 case IPPROTO_UDP:
116 #ifdef IPPROTO_SCTP
117 case IPPROTO_SCTP:
118 #endif
119 return 1; /* there is port information to also be retrieved */
120 default:
121 return 0; /* no port info coming */
123 case 1:
124 strcpy(namebuff, "PORT");
125 snprintf(valuebuff, valuelen, "%u", ntohs(sa->sin_port));
126 return 0;
128 return -1;
131 #endif /* WITH_IP4 */