1 #include <windows.h> 2 #include <ws2tcpip.h> 3 #include "u.h" 4 #include "lib.h" 5 #include "dat.h" 6 #include "fns.h" 7 #include "error.h" 8 #include "ip.h" 9 10 #include "devip.h" 11 12 #ifdef MSVC 13 #pragma comment(lib, "wsock32.lib") 14 #endif 15 16 #undef listen 17 #undef accept 18 #undef bind 19 20 static int 21 family(unsigned char *addr) 22 { 23 if(isv4(addr)) 24 return AF_INET; 25 return AF_INET6; 26 } 27 28 static int 29 addrlen(struct sockaddr_storage *ss) 30 { 31 switch(ss->ss_family){ 32 case AF_INET: 33 return sizeof(struct sockaddr_in); 34 case AF_INET6: 35 return sizeof(struct sockaddr_in6); 36 } 37 return 0; 38 } 39 40 void 41 osipinit(void) 42 { 43 WSADATA wasdat; 44 char buf[1024]; 45 46 if(WSAStartup(MAKEWORD(1, 1), &wasdat) != 0) 47 panic("no winsock.dll"); 48 49 gethostname(buf, sizeof(buf)); 50 kstrdup(&sysname, buf); 51 } 52 53 int 54 so_socket(int type, unsigned char *addr) 55 { 56 int fd, one; 57 58 switch(type) { 59 default: 60 error("bad protocol type"); 61 case S_TCP: 62 type = SOCK_STREAM; 63 break; 64 case S_UDP: 65 type = SOCK_DGRAM; 66 break; 67 } 68 69 fd = socket(family(addr), type, 0); 70 if(fd < 0) 71 oserror(); 72 73 one = 1; 74 if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){ 75 oserrstr(); 76 print("setsockopt: %s\n", up->errstr); 77 } 78 79 return fd; 80 } 81 82 83 void 84 so_connect(int fd, unsigned char *raddr, unsigned short rport) 85 { 86 struct sockaddr_storage ss; 87 88 memset(&ss, 0, sizeof(ss)); 89 90 ss.ss_family = family(raddr); 91 92 switch(ss.ss_family){ 93 case AF_INET: 94 hnputs(&((struct sockaddr_in*)&ss)->sin_port, rport); 95 v6tov4((unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr, raddr); 96 break; 97 case AF_INET6: 98 hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, rport); 99 memcpy(&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, raddr, sizeof(struct in6_addr)); 100 break; 101 } 102 103 if(connect(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0) 104 oserror(); 105 } 106 107 void 108 so_getsockname(int fd, unsigned char *laddr, unsigned short *lport) 109 { 110 int len; 111 struct sockaddr_storage ss; 112 113 len = sizeof(ss); 114 if(getsockname(fd, (struct sockaddr*)&ss, &len) < 0) 115 oserror(); 116 117 switch(ss.ss_family){ 118 case AF_INET: 119 v4tov6(laddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr); 120 *lport = nhgets(&((struct sockaddr_in*)&ss)->sin_port); 121 break; 122 case AF_INET6: 123 memcpy(laddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr)); 124 *lport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port); 125 break; 126 default: 127 error("not AF_INET or AF_INET6"); 128 } 129 } 130 131 void 132 so_listen(int fd) 133 { 134 if(listen(fd, 5) < 0) 135 oserror(); 136 } 137 138 int 139 so_accept(int fd, unsigned char *raddr, unsigned short *rport) 140 { 141 int nfd; 142 int len; 143 struct sockaddr_storage ss; 144 145 len = sizeof(ss); 146 nfd = accept(fd, (struct sockaddr*)&ss, &len); 147 if(nfd < 0) 148 oserror(); 149 150 switch(ss.ss_family){ 151 case AF_INET: 152 v4tov6(raddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr); 153 *rport = nhgets(&((struct sockaddr_in*)&ss)->sin_port); 154 break; 155 case AF_INET6: 156 memcpy(raddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr)); 157 *rport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port); 158 break; 159 default: 160 error("not AF_INET or AF_INET6"); 161 } 162 return nfd; 163 } 164 165 void 166 so_bind(int fd, int su, unsigned short port, unsigned char *addr) 167 { 168 int i, one; 169 struct sockaddr_storage ss; 170 171 one = 1; 172 if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){ 173 oserrstr(); 174 print("setsockopt: %r"); 175 } 176 177 if(su) { 178 for(i = 600; i < 1024; i++) { 179 memset(&ss, 0, sizeof(ss)); 180 ss.ss_family = family(addr); 181 182 switch(ss.ss_family){ 183 case AF_INET: 184 ((struct sockaddr_in*)&ss)->sin_port = i; 185 break; 186 case AF_INET6: 187 ((struct sockaddr_in6*)&ss)->sin6_port = i; 188 break; 189 } 190 191 if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) >= 0) 192 return; 193 } 194 oserror(); 195 } 196 197 memset(&ss, 0, sizeof(ss)); 198 ss.ss_family = family(addr); 199 200 switch(ss.ss_family){ 201 case AF_INET: 202 hnputs(&((struct sockaddr_in*)&ss)->sin_port, port); 203 break; 204 case AF_INET6: 205 hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, port); 206 break; 207 } 208 209 if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0) 210 oserror(); 211 } 212 213 int 214 so_gethostbyname(char *host, char**hostv, int n) 215 { 216 int i; 217 char buf[32]; 218 unsigned char *p; 219 struct hostent *hp; 220 221 hp = gethostbyname(host); 222 if(hp == 0) 223 return 0; 224 225 for(i = 0; hp->h_addr_list[i] && i < n; i++) { 226 p = (unsigned char*)hp->h_addr_list[i]; 227 sprint(buf, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 228 hostv[i] = strdup(buf); 229 if(hostv[i] == 0) 230 break; 231 } 232 return i; 233 } 234 235 char* 236 hostlookup(char *host) 237 { 238 char buf[100]; 239 uchar *p; 240 struct hostent *he; 241 242 he = gethostbyname(host); 243 if(he != 0 && he->h_addr_list[0]) { 244 p = (uchar*)he->h_addr_list[0]; 245 sprint(buf, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3]); 246 } else 247 strcpy(buf, host); 248 249 return strdup(buf); 250 } 251 252 int 253 so_getservbyname(char *service, char *net, char *port) 254 { 255 struct servent *s; 256 257 s = getservbyname(service, net); 258 if(s == 0) 259 return -1; 260 261 sprint(port, "%d", nhgets(&s->s_port)); 262 return 0; 263 } 264 265 int 266 so_send(int fd, void *d, int n, int f) 267 { 268 return send(fd, d, n, f); 269 } 270 271 int 272 so_recv(int fd, void *d, int n, int f) 273 { 274 return recv(fd, d, n, f); 275 } 276