xref: /plan9-contrib/sys/src/cmd/unix/drawterm/kern/devip-posix.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <netinet/in.h>
4 #include <netinet/tcp.h>
5 #include <netdb.h>
6 
7 #include "u.h"
8 #include "lib.h"
9 #include "dat.h"
10 #include "fns.h"
11 #include "error.h"
12 
13 #include "devip.h"
14 
15 #undef listen
16 #undef accept
17 #undef bind
18 
19 void
20 osipinit(void)
21 {
22 	char buf[1024];
23 	gethostname(buf, sizeof(buf));
24 	kstrdup(&sysname, buf);
25 
26 }
27 
28 int
29 so_socket(int type)
30 {
31 	int fd, one;
32 
33 	switch(type) {
34 	default:
35 		error("bad protocol type");
36 	case S_TCP:
37 		type = SOCK_STREAM;
38 		break;
39 	case S_UDP:
40 		type = SOCK_DGRAM;
41 		break;
42 	}
43 
44 	fd = socket(AF_INET, type, 0);
45 	if(fd < 0)
46 		oserror();
47 
48 	one = 1;
49 	if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){
50 		oserrstr();
51 		print("setsockopt: %r");
52 	}
53 
54 	return fd;
55 }
56 
57 
58 void
59 so_connect(int fd, unsigned long raddr, unsigned short rport)
60 {
61 	struct sockaddr_in sin;
62 
63 	memset(&sin, 0, sizeof(sin));
64 	sin.sin_family = AF_INET;
65 	hnputs(&sin.sin_port, rport);
66 	hnputl(&sin.sin_addr.s_addr, raddr);
67 
68 	if(connect(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
69 		oserror();
70 }
71 
72 void
73 so_getsockname(int fd, unsigned long *laddr, unsigned short *lport)
74 {
75 	socklen_t len;
76 	struct sockaddr_in sin;
77 
78 	len = sizeof(sin);
79 	if(getsockname(fd, (struct sockaddr*)&sin, &len) < 0)
80 		oserror();
81 
82 	if(sin.sin_family != AF_INET || len != sizeof(sin))
83 		error("not AF_INET");
84 
85 	*laddr = nhgetl(&sin.sin_addr.s_addr);
86 	*lport = nhgets(&sin.sin_port);
87 }
88 
89 void
90 so_listen(int fd)
91 {
92 	if(listen(fd, 5) < 0)
93 		oserror();
94 }
95 
96 int
97 so_accept(int fd, unsigned long *raddr, unsigned short *rport)
98 {
99 	int nfd;
100 	socklen_t len;
101 	struct sockaddr_in sin;
102 
103 	len = sizeof(sin);
104 	nfd = accept(fd, (struct sockaddr*)&sin, &len);
105 	if(nfd < 0)
106 		oserror();
107 
108 	if(sin.sin_family != AF_INET || len != sizeof(sin))
109 		error("not AF_INET");
110 
111 	*raddr = nhgetl(&sin.sin_addr.s_addr);
112 	*rport = nhgets(&sin.sin_port);
113 	return nfd;
114 }
115 
116 void
117 so_bind(int fd, int su, unsigned short port)
118 {
119 	int i, one;
120 	struct sockaddr_in sin;
121 
122 	one = 1;
123 	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){
124 		oserrstr();
125 		print("setsockopt: %r");
126 	}
127 
128 	if(su) {
129 		for(i = 600; i < 1024; i++) {
130 			memset(&sin, 0, sizeof(sin));
131 			sin.sin_family = AF_INET;
132 			sin.sin_port = i;
133 
134 			if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) >= 0)
135 				return;
136 		}
137 		oserror();
138 	}
139 
140 	memset(&sin, 0, sizeof(sin));
141 	sin.sin_family = AF_INET;
142 	hnputs(&sin.sin_port, port);
143 
144 	if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
145 		oserror();
146 }
147 
148 int
149 so_gethostbyname(char *host, char**hostv, int n)
150 {
151 	int i;
152 	char buf[32];
153 	unsigned char *p;
154 	struct hostent *hp;
155 
156 	hp = gethostbyname(host);
157 	if(hp == 0)
158 		return 0;
159 
160 	for(i = 0; hp->h_addr_list[i] && i < n; i++) {
161 		p = (unsigned char*)hp->h_addr_list[i];
162 		sprint(buf, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
163 		hostv[i] = strdup(buf);
164 		if(hostv[i] == 0)
165 			break;
166 	}
167 	return i;
168 }
169 
170 char*
171 hostlookup(char *host)
172 {
173 	char buf[100];
174 	uchar *p;
175 	struct hostent *he;
176 
177 	he = gethostbyname(host);
178 	if(he != 0 && he->h_addr_list[0]) {
179 		p = (uchar*)he->h_addr_list[0];
180 		sprint(buf, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3]);
181 	} else
182 		strcpy(buf, host);
183 
184 	return strdup(buf);
185 }
186 
187 int
188 so_getservbyname(char *service, char *net, char *port)
189 {
190 	struct servent *s;
191 
192 	s = getservbyname(service, net);
193 	if(s == 0)
194 		return -1;
195 
196 	sprint(port, "%d", nhgets(&s->s_port));
197 	return 0;
198 }
199 
200 int
201 so_send(int fd, void *d, int n, int f)
202 {
203 	return send(fd, d, n, f);
204 }
205 
206 int
207 so_recv(int fd, void *d, int n, int f)
208 {
209 	return recv(fd, d, n, f);
210 }
211