xref: /minix3/crypto/external/bsd/openssl/dist/demos/tunala/ip.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1ebfedea0SLionel Sambuc #include "tunala.h"
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc #ifndef NO_IP
4ebfedea0SLionel Sambuc 
5ebfedea0SLionel Sambuc # define IP_LISTENER_BACKLOG 511/* So if it gets masked by 256 or some other
6*0a6a1f1dSLionel Sambuc                                  * such value it'll still be respectable */
7ebfedea0SLionel Sambuc 
8ebfedea0SLionel Sambuc /* Any IP-related initialisations. For now, this means blocking SIGPIPE */
ip_initialise(void)9ebfedea0SLionel Sambuc int ip_initialise(void)
10ebfedea0SLionel Sambuc {
11ebfedea0SLionel Sambuc     struct sigaction sa;
12ebfedea0SLionel Sambuc 
13ebfedea0SLionel Sambuc     sa.sa_handler = SIG_IGN;
14ebfedea0SLionel Sambuc     sa.sa_flags = 0;
15ebfedea0SLionel Sambuc     sigemptyset(&sa.sa_mask);
16ebfedea0SLionel Sambuc     if (sigaction(SIGPIPE, &sa, NULL) != 0)
17ebfedea0SLionel Sambuc         return 0;
18ebfedea0SLionel Sambuc     return 1;
19ebfedea0SLionel Sambuc }
20ebfedea0SLionel Sambuc 
ip_create_listener_split(const char * ip,unsigned short port)21ebfedea0SLionel Sambuc int ip_create_listener_split(const char *ip, unsigned short port)
22ebfedea0SLionel Sambuc {
23ebfedea0SLionel Sambuc     struct sockaddr_in in_addr;
24ebfedea0SLionel Sambuc     int fd = -1;
25ebfedea0SLionel Sambuc     int reuseVal = 1;
26ebfedea0SLionel Sambuc 
27ebfedea0SLionel Sambuc     /* Create the socket */
28ebfedea0SLionel Sambuc     if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
29ebfedea0SLionel Sambuc         goto err;
30ebfedea0SLionel Sambuc     /* Set the SO_REUSEADDR flag - servers act weird without it */
31ebfedea0SLionel Sambuc     if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)(&reuseVal),
32ebfedea0SLionel Sambuc                    sizeof(reuseVal)) != 0)
33ebfedea0SLionel Sambuc         goto err;
34ebfedea0SLionel Sambuc     /* Prepare the listen address stuff */
35ebfedea0SLionel Sambuc     in_addr.sin_family = AF_INET;
36ebfedea0SLionel Sambuc     memcpy(&in_addr.sin_addr.s_addr, ip, 4);
37ebfedea0SLionel Sambuc     in_addr.sin_port = htons(port);
38ebfedea0SLionel Sambuc     /* Bind to the required port/address/interface */
39*0a6a1f1dSLionel Sambuc     if (bind(fd, (struct sockaddr *)&in_addr, sizeof(struct sockaddr_in)) !=
40*0a6a1f1dSLionel Sambuc         0)
41ebfedea0SLionel Sambuc         goto err;
42ebfedea0SLionel Sambuc     /* Start "listening" */
43ebfedea0SLionel Sambuc     if (listen(fd, IP_LISTENER_BACKLOG) != 0)
44ebfedea0SLionel Sambuc         goto err;
45ebfedea0SLionel Sambuc     return fd;
46ebfedea0SLionel Sambuc  err:
47ebfedea0SLionel Sambuc     if (fd != -1)
48ebfedea0SLionel Sambuc         close(fd);
49ebfedea0SLionel Sambuc     return -1;
50ebfedea0SLionel Sambuc }
51ebfedea0SLionel Sambuc 
ip_create_connection_split(const char * ip,unsigned short port)52ebfedea0SLionel Sambuc int ip_create_connection_split(const char *ip, unsigned short port)
53ebfedea0SLionel Sambuc {
54ebfedea0SLionel Sambuc     struct sockaddr_in in_addr;
55ebfedea0SLionel Sambuc     int flags, fd = -1;
56ebfedea0SLionel Sambuc 
57ebfedea0SLionel Sambuc     /* Create the socket */
58ebfedea0SLionel Sambuc     if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
59ebfedea0SLionel Sambuc         goto err;
60ebfedea0SLionel Sambuc     /* Make it non-blocking */
61ebfedea0SLionel Sambuc     if (((flags = fcntl(fd, F_GETFL, 0)) < 0) ||
62ebfedea0SLionel Sambuc         (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0))
63ebfedea0SLionel Sambuc         goto err;
64ebfedea0SLionel Sambuc     /* Prepare the connection address stuff */
65ebfedea0SLionel Sambuc     in_addr.sin_family = AF_INET;
66ebfedea0SLionel Sambuc     memcpy(&in_addr.sin_addr.s_addr, ip, 4);
67ebfedea0SLionel Sambuc     in_addr.sin_port = htons(port);
68ebfedea0SLionel Sambuc     /* Start a connect (non-blocking, in all likelihood) */
69ebfedea0SLionel Sambuc     if ((connect(fd, (struct sockaddr *)&in_addr,
70*0a6a1f1dSLionel Sambuc                  sizeof(struct sockaddr_in)) != 0) && (errno != EINPROGRESS))
71ebfedea0SLionel Sambuc         goto err;
72ebfedea0SLionel Sambuc     return fd;
73ebfedea0SLionel Sambuc  err:
74ebfedea0SLionel Sambuc     if (fd != -1)
75ebfedea0SLionel Sambuc         close(fd);
76ebfedea0SLionel Sambuc     return -1;
77ebfedea0SLionel Sambuc }
78ebfedea0SLionel Sambuc 
79ebfedea0SLionel Sambuc static char all_local_ip[] = { 0x00, 0x00, 0x00, 0x00 };
80ebfedea0SLionel Sambuc 
ip_parse_address(const char * address,const char ** parsed_ip,unsigned short * parsed_port,int accept_all_ip)81ebfedea0SLionel Sambuc int ip_parse_address(const char *address, const char **parsed_ip,
82ebfedea0SLionel Sambuc                      unsigned short *parsed_port, int accept_all_ip)
83ebfedea0SLionel Sambuc {
84ebfedea0SLionel Sambuc     char buf[256];
85ebfedea0SLionel Sambuc     struct hostent *lookup;
86ebfedea0SLionel Sambuc     unsigned long port;
87ebfedea0SLionel Sambuc     const char *ptr = strstr(address, ":");
88ebfedea0SLionel Sambuc     const char *ip = all_local_ip;
89ebfedea0SLionel Sambuc 
90ebfedea0SLionel Sambuc     if (!ptr) {
91*0a6a1f1dSLionel Sambuc         /*
92*0a6a1f1dSLionel Sambuc          * We assume we're listening on all local interfaces and have only
93*0a6a1f1dSLionel Sambuc          * specified a port.
94*0a6a1f1dSLionel Sambuc          */
95ebfedea0SLionel Sambuc         if (!accept_all_ip)
96ebfedea0SLionel Sambuc             return 0;
97ebfedea0SLionel Sambuc         ptr = address;
98ebfedea0SLionel Sambuc         goto determine_port;
99ebfedea0SLionel Sambuc     }
100ebfedea0SLionel Sambuc     if ((ptr - address) > 255)
101ebfedea0SLionel Sambuc         return 0;
102ebfedea0SLionel Sambuc     memset(buf, 0, 256);
103ebfedea0SLionel Sambuc     memcpy(buf, address, ptr - address);
104ebfedea0SLionel Sambuc     ptr++;
105ebfedea0SLionel Sambuc     if ((lookup = gethostbyname(buf)) == NULL) {
106*0a6a1f1dSLionel Sambuc         /*
107*0a6a1f1dSLionel Sambuc          * Spit a message to differentiate between lookup failures and bad
108*0a6a1f1dSLionel Sambuc          * strings.
109*0a6a1f1dSLionel Sambuc          */
110ebfedea0SLionel Sambuc         fprintf(stderr, "hostname lookup for '%s' failed\n", buf);
111ebfedea0SLionel Sambuc         return 0;
112ebfedea0SLionel Sambuc     }
113ebfedea0SLionel Sambuc     ip = lookup->h_addr_list[0];
114ebfedea0SLionel Sambuc  determine_port:
115ebfedea0SLionel Sambuc     if (strlen(ptr) < 1)
116ebfedea0SLionel Sambuc         return 0;
117ebfedea0SLionel Sambuc     if (!int_strtoul(ptr, &port) || (port > 65535))
118ebfedea0SLionel Sambuc         return 0;
119ebfedea0SLionel Sambuc     *parsed_ip = ip;
120ebfedea0SLionel Sambuc     *parsed_port = (unsigned short)port;
121ebfedea0SLionel Sambuc     return 1;
122ebfedea0SLionel Sambuc }
123ebfedea0SLionel Sambuc 
ip_create_listener(const char * address)124ebfedea0SLionel Sambuc int ip_create_listener(const char *address)
125ebfedea0SLionel Sambuc {
126ebfedea0SLionel Sambuc     const char *ip;
127ebfedea0SLionel Sambuc     unsigned short port;
128ebfedea0SLionel Sambuc 
129ebfedea0SLionel Sambuc     if (!ip_parse_address(address, &ip, &port, 1))
130ebfedea0SLionel Sambuc         return -1;
131ebfedea0SLionel Sambuc     return ip_create_listener_split(ip, port);
132ebfedea0SLionel Sambuc }
133ebfedea0SLionel Sambuc 
ip_create_connection(const char * address)134ebfedea0SLionel Sambuc int ip_create_connection(const char *address)
135ebfedea0SLionel Sambuc {
136ebfedea0SLionel Sambuc     const char *ip;
137ebfedea0SLionel Sambuc     unsigned short port;
138ebfedea0SLionel Sambuc 
139ebfedea0SLionel Sambuc     if (!ip_parse_address(address, &ip, &port, 0))
140ebfedea0SLionel Sambuc         return -1;
141ebfedea0SLionel Sambuc     return ip_create_connection_split(ip, port);
142ebfedea0SLionel Sambuc }
143ebfedea0SLionel Sambuc 
ip_accept_connection(int listen_fd)144ebfedea0SLionel Sambuc int ip_accept_connection(int listen_fd)
145ebfedea0SLionel Sambuc {
146ebfedea0SLionel Sambuc     return accept(listen_fd, NULL, NULL);
147ebfedea0SLionel Sambuc }
148ebfedea0SLionel Sambuc 
149ebfedea0SLionel Sambuc #endif                          /* !defined(NO_IP) */
150