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