xref: /plan9-contrib/sys/src/cmd/unix/drawterm/kern/devip-win32.c (revision 14093dc2f1c686bec1bc44cefce44368c26be35a)
18ccd4a63SDavid du Colombier #include <windows.h>
28ccd4a63SDavid du Colombier #include "u.h"
38ccd4a63SDavid du Colombier #include "lib.h"
48ccd4a63SDavid du Colombier #include "dat.h"
58ccd4a63SDavid du Colombier #include "fns.h"
68ccd4a63SDavid du Colombier #include "error.h"
78ccd4a63SDavid du Colombier 
88ccd4a63SDavid du Colombier #include "devip.h"
98ccd4a63SDavid du Colombier 
108ccd4a63SDavid du Colombier #ifdef MSVC
118ccd4a63SDavid du Colombier #pragma comment(lib, "wsock32.lib")
128ccd4a63SDavid du Colombier #endif
138ccd4a63SDavid du Colombier 
148ccd4a63SDavid du Colombier #undef listen
158ccd4a63SDavid du Colombier #undef accept
168ccd4a63SDavid du Colombier #undef bind
178ccd4a63SDavid du Colombier 
188ccd4a63SDavid du Colombier void
198ccd4a63SDavid du Colombier osipinit(void)
208ccd4a63SDavid du Colombier {
218ccd4a63SDavid du Colombier 	WSADATA wasdat;
228ccd4a63SDavid du Colombier 	char buf[1024];
238ccd4a63SDavid du Colombier 
248ccd4a63SDavid du Colombier 	if(WSAStartup(MAKEWORD(1, 1), &wasdat) != 0)
258ccd4a63SDavid du Colombier 		panic("no winsock.dll");
268ccd4a63SDavid du Colombier 
278ccd4a63SDavid du Colombier 	gethostname(buf, sizeof(buf));
288ccd4a63SDavid du Colombier 	kstrdup(&sysname, buf);
298ccd4a63SDavid du Colombier }
308ccd4a63SDavid du Colombier 
318ccd4a63SDavid du Colombier int
328ccd4a63SDavid du Colombier so_socket(int type)
338ccd4a63SDavid du Colombier {
348ccd4a63SDavid du Colombier 	int fd, one;
358ccd4a63SDavid du Colombier 
368ccd4a63SDavid du Colombier 	switch(type) {
378ccd4a63SDavid du Colombier 	default:
388ccd4a63SDavid du Colombier 		error("bad protocol type");
398ccd4a63SDavid du Colombier 	case S_TCP:
408ccd4a63SDavid du Colombier 		type = SOCK_STREAM;
418ccd4a63SDavid du Colombier 		break;
428ccd4a63SDavid du Colombier 	case S_UDP:
438ccd4a63SDavid du Colombier 		type = SOCK_DGRAM;
448ccd4a63SDavid du Colombier 		break;
458ccd4a63SDavid du Colombier 	}
468ccd4a63SDavid du Colombier 
478ccd4a63SDavid du Colombier 	fd = socket(AF_INET, type, 0);
488ccd4a63SDavid du Colombier 	if(fd < 0)
498ccd4a63SDavid du Colombier 		oserror();
508ccd4a63SDavid du Colombier 
518ccd4a63SDavid du Colombier 	one = 1;
528ccd4a63SDavid du Colombier 	if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){
538ccd4a63SDavid du Colombier 		oserrstr();
548ccd4a63SDavid du Colombier 		print("setsockopt: %s\n", up->errstr);
558ccd4a63SDavid du Colombier 	}
568ccd4a63SDavid du Colombier 
578ccd4a63SDavid du Colombier 	return fd;
588ccd4a63SDavid du Colombier }
598ccd4a63SDavid du Colombier 
608ccd4a63SDavid du Colombier 
618ccd4a63SDavid du Colombier void
628ccd4a63SDavid du Colombier so_connect(int fd, unsigned long raddr, unsigned short rport)
638ccd4a63SDavid du Colombier {
648ccd4a63SDavid du Colombier 	struct sockaddr_in sin;
658ccd4a63SDavid du Colombier 
668ccd4a63SDavid du Colombier 	memset(&sin, 0, sizeof(sin));
678ccd4a63SDavid du Colombier 	sin.sin_family = AF_INET;
688ccd4a63SDavid du Colombier 	hnputs(&sin.sin_port, rport);
698ccd4a63SDavid du Colombier 	hnputl(&sin.sin_addr.s_addr, raddr);
708ccd4a63SDavid du Colombier 
718ccd4a63SDavid du Colombier 	if(connect(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
728ccd4a63SDavid du Colombier 		oserror();
738ccd4a63SDavid du Colombier }
748ccd4a63SDavid du Colombier 
758ccd4a63SDavid du Colombier void
768ccd4a63SDavid du Colombier so_getsockname(int fd, unsigned long *laddr, unsigned short *lport)
778ccd4a63SDavid du Colombier {
788ccd4a63SDavid du Colombier 	int len;
798ccd4a63SDavid du Colombier 	struct sockaddr_in sin;
808ccd4a63SDavid du Colombier 
818ccd4a63SDavid du Colombier 	len = sizeof(sin);
828ccd4a63SDavid du Colombier 	if(getsockname(fd, (struct sockaddr*)&sin, &len) < 0)
838ccd4a63SDavid du Colombier 		oserror();
848ccd4a63SDavid du Colombier 
858ccd4a63SDavid du Colombier 	if(sin.sin_family != AF_INET || len != sizeof(sin))
868ccd4a63SDavid du Colombier 		error("not AF_INET");
878ccd4a63SDavid du Colombier 
888ccd4a63SDavid du Colombier 	*laddr = nhgetl(&sin.sin_addr.s_addr);
898ccd4a63SDavid du Colombier 	*lport = nhgets(&sin.sin_port);
908ccd4a63SDavid du Colombier }
918ccd4a63SDavid du Colombier 
928ccd4a63SDavid du Colombier void
938ccd4a63SDavid du Colombier so_listen(int fd)
948ccd4a63SDavid du Colombier {
958ccd4a63SDavid du Colombier 	if(listen(fd, 5) < 0)
968ccd4a63SDavid du Colombier 		oserror();
978ccd4a63SDavid du Colombier }
988ccd4a63SDavid du Colombier 
998ccd4a63SDavid du Colombier int
1008ccd4a63SDavid du Colombier so_accept(int fd, unsigned long *raddr, unsigned short *rport)
1018ccd4a63SDavid du Colombier {
1028ccd4a63SDavid du Colombier 	int nfd, len;
1038ccd4a63SDavid du Colombier 	struct sockaddr_in sin;
1048ccd4a63SDavid du Colombier 
1058ccd4a63SDavid du Colombier 	len = sizeof(sin);
1068ccd4a63SDavid du Colombier 	nfd = accept(fd, (struct sockaddr*)&sin, &len);
1078ccd4a63SDavid du Colombier 	if(nfd < 0)
1088ccd4a63SDavid du Colombier 		oserror();
1098ccd4a63SDavid du Colombier 
1108ccd4a63SDavid du Colombier 	if(sin.sin_family != AF_INET || len != sizeof(sin))
1118ccd4a63SDavid du Colombier 		error("not AF_INET");
1128ccd4a63SDavid du Colombier 
1138ccd4a63SDavid du Colombier 	*raddr = nhgetl(&sin.sin_addr.s_addr);
1148ccd4a63SDavid du Colombier 	*rport = nhgets(&sin.sin_port);
1158ccd4a63SDavid du Colombier 	return nfd;
1168ccd4a63SDavid du Colombier }
1178ccd4a63SDavid du Colombier 
1188ccd4a63SDavid du Colombier void
1198ccd4a63SDavid du Colombier so_bind(int fd, int su, unsigned short port)
1208ccd4a63SDavid du Colombier {
1218ccd4a63SDavid du Colombier 	int i, one;
1228ccd4a63SDavid du Colombier 	struct sockaddr_in sin;
1238ccd4a63SDavid du Colombier 
1248ccd4a63SDavid du Colombier 	one = 1;
1258ccd4a63SDavid du Colombier 	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){
1268ccd4a63SDavid du Colombier 		oserrstr();
1278ccd4a63SDavid du Colombier 		print("setsockopt: %s", up->errstr);
1288ccd4a63SDavid du Colombier 	}
1298ccd4a63SDavid du Colombier 
1308ccd4a63SDavid du Colombier 	if(su) {
1318ccd4a63SDavid du Colombier 		for(i = 600; i < 1024; i++) {
1328ccd4a63SDavid du Colombier 			memset(&sin, 0, sizeof(sin));
1338ccd4a63SDavid du Colombier 			sin.sin_family = AF_INET;
1348ccd4a63SDavid du Colombier 			sin.sin_port = i;
1358ccd4a63SDavid du Colombier 
1368ccd4a63SDavid du Colombier 			if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) >= 0)
1378ccd4a63SDavid du Colombier 				return;
1388ccd4a63SDavid du Colombier 		}
1398ccd4a63SDavid du Colombier 		oserror();
1408ccd4a63SDavid du Colombier 	}
1418ccd4a63SDavid du Colombier 
1428ccd4a63SDavid du Colombier 	memset(&sin, 0, sizeof(sin));
1438ccd4a63SDavid du Colombier 	sin.sin_family = AF_INET;
1448ccd4a63SDavid du Colombier 	hnputs(&sin.sin_port, port);
1458ccd4a63SDavid du Colombier 
1468ccd4a63SDavid du Colombier 	if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
1478ccd4a63SDavid du Colombier 		oserror();
1488ccd4a63SDavid du Colombier }
1498ccd4a63SDavid du Colombier 
1508ccd4a63SDavid du Colombier int
1518ccd4a63SDavid du Colombier so_gethostbyname(char *host, char**hostv, int n)
1528ccd4a63SDavid du Colombier {
1538ccd4a63SDavid du Colombier 	int i;
1548ccd4a63SDavid du Colombier 	char buf[32];
1558ccd4a63SDavid du Colombier 	unsigned char *p;
1568ccd4a63SDavid du Colombier 	struct hostent *hp;
1578ccd4a63SDavid du Colombier 
1588ccd4a63SDavid du Colombier 	hp = gethostbyname(host);
1598ccd4a63SDavid du Colombier 	if(hp == 0)
1608ccd4a63SDavid du Colombier 		return 0;
1618ccd4a63SDavid du Colombier 
1628ccd4a63SDavid du Colombier 	for(i = 0; hp->h_addr_list[i] && i < n; i++) {
1638ccd4a63SDavid du Colombier 		p = (unsigned char*)hp->h_addr_list[i];
1648ccd4a63SDavid du Colombier 		sprint(buf, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
1658ccd4a63SDavid du Colombier 		hostv[i] = strdup(buf);
1668ccd4a63SDavid du Colombier 		if(hostv[i] == 0)
1678ccd4a63SDavid du Colombier 			break;
1688ccd4a63SDavid du Colombier 	}
1698ccd4a63SDavid du Colombier 	return i;
1708ccd4a63SDavid du Colombier }
1718ccd4a63SDavid du Colombier 
1728ccd4a63SDavid du Colombier char*
1738ccd4a63SDavid du Colombier hostlookup(char *host)
1748ccd4a63SDavid du Colombier {
1758ccd4a63SDavid du Colombier 	char buf[100];
1768ccd4a63SDavid du Colombier 	uchar *p;
1778ccd4a63SDavid du Colombier 	HOSTENT *he;
1788ccd4a63SDavid du Colombier 
1798ccd4a63SDavid du Colombier 	he = gethostbyname(host);
1808ccd4a63SDavid du Colombier 	if(he != 0 && he->h_addr_list[0]) {
181*14093dc2SDavid du Colombier 		p = (uchar*)he->h_addr_list[0];
1828ccd4a63SDavid du Colombier 		sprint(buf, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3]);
1838ccd4a63SDavid du Colombier 	} else
1848ccd4a63SDavid du Colombier 		strcpy(buf, host);
1858ccd4a63SDavid du Colombier 
1868ccd4a63SDavid du Colombier 	return strdup(buf);
1878ccd4a63SDavid du Colombier }
1888ccd4a63SDavid du Colombier 
1898ccd4a63SDavid du Colombier int
1908ccd4a63SDavid du Colombier so_getservbyname(char *service, char *net, char *port)
1918ccd4a63SDavid du Colombier {
1928ccd4a63SDavid du Colombier 	struct servent *s;
1938ccd4a63SDavid du Colombier 
1948ccd4a63SDavid du Colombier 	s = getservbyname(service, net);
1958ccd4a63SDavid du Colombier 	if(s == 0)
1968ccd4a63SDavid du Colombier 		return -1;
1978ccd4a63SDavid du Colombier 
1988ccd4a63SDavid du Colombier 	sprint(port, "%d", nhgets(&s->s_port));
1998ccd4a63SDavid du Colombier 	return 0;
2008ccd4a63SDavid du Colombier }
2018ccd4a63SDavid du Colombier 
2028ccd4a63SDavid du Colombier int
2038ccd4a63SDavid du Colombier so_send(int fd, void *d, int n, int f)
2048ccd4a63SDavid du Colombier {
2058ccd4a63SDavid du Colombier 	return send(fd, d, n, f);
2068ccd4a63SDavid du Colombier }
2078ccd4a63SDavid du Colombier 
2088ccd4a63SDavid du Colombier int
2098ccd4a63SDavid du Colombier so_recv(int fd, void *d, int n, int f)
2108ccd4a63SDavid du Colombier {
2118ccd4a63SDavid du Colombier 	return recv(fd, d, n, f);
2128ccd4a63SDavid du Colombier }
213