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