Sync usage with man page.
[netbsd-mini2440.git] / crypto / external / bsd / openssl / dist / demos / tunala / ip.c
blob96ef4e65360682d64553c70b2ca01e9b0c10f23e
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)) != 0)
40 goto err;
41 /* Start "listening" */
42 if(listen(fd, IP_LISTENER_BACKLOG) != 0)
43 goto err;
44 return fd;
45 err:
46 if(fd != -1)
47 close(fd);
48 return -1;
51 int ip_create_connection_split(const char *ip, unsigned short port)
53 struct sockaddr_in in_addr;
54 int flags, fd = -1;
56 /* Create the socket */
57 if((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
58 goto err;
59 /* Make it non-blocking */
60 if(((flags = fcntl(fd, F_GETFL, 0)) < 0) ||
61 (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0))
62 goto err;
63 /* Prepare the connection address stuff */
64 in_addr.sin_family = AF_INET;
65 memcpy(&in_addr.sin_addr.s_addr, ip, 4);
66 in_addr.sin_port = htons(port);
67 /* Start a connect (non-blocking, in all likelihood) */
68 if((connect(fd, (struct sockaddr *)&in_addr,
69 sizeof(struct sockaddr_in)) != 0) &&
70 (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) {
91 /* We assume we're listening on all local interfaces and have
92 * only specified a port. */
93 if(!accept_all_ip)
94 return 0;
95 ptr = address;
96 goto determine_port;
98 if((ptr - address) > 255)
99 return 0;
100 memset(buf, 0, 256);
101 memcpy(buf, address, ptr - address);
102 ptr++;
103 if((lookup = gethostbyname(buf)) == NULL) {
104 /* Spit a message to differentiate between lookup failures and
105 * bad strings. */
106 fprintf(stderr, "hostname lookup for '%s' failed\n", buf);
107 return 0;
109 ip = lookup->h_addr_list[0];
110 determine_port:
111 if(strlen(ptr) < 1)
112 return 0;
113 if(!int_strtoul(ptr, &port) || (port > 65535))
114 return 0;
115 *parsed_ip = ip;
116 *parsed_port = (unsigned short)port;
117 return 1;
120 int ip_create_listener(const char *address)
122 const char *ip;
123 unsigned short port;
125 if(!ip_parse_address(address, &ip, &port, 1))
126 return -1;
127 return ip_create_listener_split(ip, port);
130 int ip_create_connection(const char *address)
132 const char *ip;
133 unsigned short port;
135 if(!ip_parse_address(address, &ip, &port, 0))
136 return -1;
137 return ip_create_connection_split(ip, port);
140 int ip_accept_connection(int listen_fd)
142 return accept(listen_fd, NULL, NULL);
145 #endif /* !defined(NO_IP) */