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