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