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