devip-posix.c - vx32 - Local 9vx git repository for patches.
(HTM) git clone git://r-36.net/vx32
(DIR) Log
(DIR) Files
(DIR) 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 }