• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/openssl-1.0.0q/demos/tunala/
1#include "tunala.h"
2
3#ifndef NO_IP
4
5#define IP_LISTENER_BACKLOG 511 /* So if it gets masked by 256 or some other
6				   such value it'll still be respectable */
7
8/* Any IP-related initialisations. For now, this means blocking SIGPIPE */
9int ip_initialise(void)
10{
11	struct sigaction sa;
12
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;
19}
20
21int ip_create_listener_split(const char *ip, unsigned short port)
22{
23	struct sockaddr_in in_addr;
24	int fd = -1;
25	int reuseVal = 1;
26
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;
45err:
46	if(fd != -1)
47		close(fd);
48	return -1;
49}
50
51int ip_create_connection_split(const char *ip, unsigned short port)
52{
53	struct sockaddr_in in_addr;
54	int flags, fd = -1;
55
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;
73err:
74	if(fd != -1)
75		close(fd);
76	return -1;
77}
78
79static char all_local_ip[] = {0x00,0x00,0x00,0x00};
80
81int ip_parse_address(const char *address, const char **parsed_ip,
82		unsigned short *parsed_port, int accept_all_ip)
83{
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;
89
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;
97	}
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;
108	}
109	ip = lookup->h_addr_list[0];
110determine_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;
118}
119
120int ip_create_listener(const char *address)
121{
122	const char *ip;
123	unsigned short port;
124
125	if(!ip_parse_address(address, &ip, &port, 1))
126		return -1;
127	return ip_create_listener_split(ip, port);
128}
129
130int ip_create_connection(const char *address)
131{
132	const char *ip;
133	unsigned short port;
134
135	if(!ip_parse_address(address, &ip, &port, 0))
136		return -1;
137	return ip_create_connection_split(ip, port);
138}
139
140int ip_accept_connection(int listen_fd)
141{
142	return accept(listen_fd, NULL, NULL);
143}
144
145#endif /* !defined(NO_IP) */
146
147