vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

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 }