]>
Commit | Line | Data |
---|---|---|
fdcd7086 JR |
1 | From: Aron Xu <aron@debian.org> |
2 | Date: Mon, 13 Feb 2012 15:59:31 +0800 | |
3 | Subject: [PATCH] port to linux with libsd | |
4 | ||
5 | --- | |
6 | Makefile | 17 +++++++++- | |
7 | nc.1 | 2 +- | |
8 | netcat.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- | |
9 | socks.c | 46 +++++++++++++------------- | |
10 | 4 files changed, 130 insertions(+), 40 deletions(-) | |
11 | ||
12 | --- a/Makefile | |
13 | +++ b/Makefile | |
14 | @@ -1,6 +1,19 @@ | |
15 | -# $OpenBSD: Makefile,v 1.6 2001/09/02 18:45:41 jakob Exp $ | |
16 | +# $OpenBSD: Makefile,v 1.6 2001/09/02 18:45:41 jakob Exp $ | |
17 | ||
18 | PROG= nc | |
19 | SRCS= netcat.c atomicio.c socks.c | |
20 | ||
21 | -.include <bsd.prog.mk> | |
22 | +LIBS= `pkg-config --libs libbsd` -lresolv | |
23 | +OBJS= $(SRCS:.c=.o) | |
24 | +CFLAGS= -g -O2 | |
25 | +LDFLAGS= -Wl,--no-add-needed | |
26 | + | |
27 | +all: nc | |
28 | +nc: $(OBJS) | |
29 | + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o nc | |
30 | + | |
31 | +$(OBJS): %.o: %.c | |
32 | + $(CC) $(CFLAGS) -c $< -o $@ | |
33 | + | |
34 | +clean: | |
35 | + rm -f $(OBJS) nc | |
36 | --- a/nc.1 | |
37 | +++ b/nc.1 | |
38 | @@ -146,9 +146,6 @@ | |
39 | Specifies the source port | |
40 | .Nm | |
41 | should use, subject to privilege restrictions and availability. | |
42 | -It is an error to use this option in conjunction with the | |
43 | -.Fl l | |
44 | -option. | |
45 | .It Fl r | |
46 | Specifies that source and/or destination ports should be chosen randomly | |
47 | instead of sequentially within a range or in the order that the system | |
48 | @@ -170,6 +167,7 @@ | |
49 | may be one of | |
50 | .Ar critical , | |
51 | .Ar inetcontrol , | |
52 | +.Ar lowcost , | |
53 | .Ar lowdelay , | |
54 | .Ar netcontrol , | |
55 | .Ar throughput , | |
56 | --- a/netcat.c | |
57 | +++ b/netcat.c | |
58 | @@ -42,6 +42,46 @@ | |
59 | #include <netinet/ip.h> | |
60 | #include <arpa/telnet.h> | |
61 | ||
62 | +#ifndef IPTOS_LOWDELAY | |
63 | +# define IPTOS_LOWDELAY 0x10 | |
64 | +# define IPTOS_THROUGHPUT 0x08 | |
65 | +# define IPTOS_RELIABILITY 0x04 | |
66 | +# define IPTOS_LOWCOST 0x02 | |
67 | +# define IPTOS_MINCOST IPTOS_LOWCOST | |
68 | +#endif /* IPTOS_LOWDELAY */ | |
69 | + | |
70 | +# ifndef IPTOS_DSCP_AF11 | |
71 | +# define IPTOS_DSCP_AF11 0x28 | |
72 | +# define IPTOS_DSCP_AF12 0x30 | |
73 | +# define IPTOS_DSCP_AF13 0x38 | |
74 | +# define IPTOS_DSCP_AF21 0x48 | |
75 | +# define IPTOS_DSCP_AF22 0x50 | |
76 | +# define IPTOS_DSCP_AF23 0x58 | |
77 | +# define IPTOS_DSCP_AF31 0x68 | |
78 | +# define IPTOS_DSCP_AF32 0x70 | |
79 | +# define IPTOS_DSCP_AF33 0x78 | |
80 | +# define IPTOS_DSCP_AF41 0x88 | |
81 | +# define IPTOS_DSCP_AF42 0x90 | |
82 | +# define IPTOS_DSCP_AF43 0x98 | |
83 | +# define IPTOS_DSCP_EF 0xb8 | |
84 | +#endif /* IPTOS_DSCP_AF11 */ | |
85 | + | |
86 | +#ifndef IPTOS_DSCP_CS0 | |
87 | +# define IPTOS_DSCP_CS0 0x00 | |
88 | +# define IPTOS_DSCP_CS1 0x20 | |
89 | +# define IPTOS_DSCP_CS2 0x40 | |
90 | +# define IPTOS_DSCP_CS3 0x60 | |
91 | +# define IPTOS_DSCP_CS4 0x80 | |
92 | +# define IPTOS_DSCP_CS5 0xa0 | |
93 | +# define IPTOS_DSCP_CS6 0xc0 | |
94 | +# define IPTOS_DSCP_CS7 0xe0 | |
95 | +#endif /* IPTOS_DSCP_CS0 */ | |
96 | + | |
97 | +#ifndef IPTOS_DSCP_EF | |
98 | +# define IPTOS_DSCP_EF 0xb8 | |
99 | +#endif /* IPTOS_DSCP_EF */ | |
100 | + | |
101 | + | |
102 | #include <err.h> | |
103 | #include <errno.h> | |
104 | #include <netdb.h> | |
105 | @@ -53,6 +93,8 @@ | |
106 | #include <unistd.h> | |
107 | #include <fcntl.h> | |
108 | #include <limits.h> | |
7c95fee9 | 109 | +#include <bsd/stdlib.h> |
fdcd7086 JR |
110 | +#include <string.h> |
111 | #include "atomicio.h" | |
112 | ||
113 | #ifndef SUN_LEN | |
114 | @@ -118,7 +160,7 @@ | |
115 | struct servent *sv; | |
116 | socklen_t len; | |
117 | struct sockaddr_storage cliaddr; | |
118 | - char *proxy; | |
119 | + char *proxy = NULL; | |
120 | const char *errstr, *proxyhost = "", *proxyport = NULL; | |
121 | struct addrinfo proxyhints; | |
122 | char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; | |
123 | @@ -164,7 +206,11 @@ | |
124 | errx(1, "interval %s: %s", errstr, optarg); | |
125 | break; | |
126 | case 'j': | |
127 | +# if defined(SO_JUMBO) | |
128 | jflag = 1; | |
129 | +# else | |
130 | + errx(1, "no jumbo frame support available"); | |
131 | +# endif | |
132 | break; | |
133 | case 'k': | |
134 | kflag = 1; | |
135 | @@ -194,10 +240,14 @@ | |
136 | uflag = 1; | |
137 | break; | |
138 | case 'V': | |
139 | +# if defined(RT_TABLEID_MAX) | |
140 | rtableid = (unsigned int)strtonum(optarg, 0, | |
141 | RT_TABLEID_MAX, &errstr); | |
142 | if (errstr) | |
143 | errx(1, "rtable %s: %s", errstr, optarg); | |
144 | +# else | |
145 | + errx(1, "no alternate routing table support available"); | |
146 | +# endif | |
147 | break; | |
148 | case 'v': | |
149 | vflag = 1; | |
150 | @@ -232,7 +282,11 @@ | |
151 | errstr, optarg); | |
152 | break; | |
153 | case 'S': | |
154 | +# if defined(TCP_MD5SIG) | |
155 | Sflag = 1; | |
156 | +# else | |
157 | + errx(1, "no TCP MD5 signature support available"); | |
158 | +# endif | |
159 | break; | |
160 | case 'T': | |
161 | errstr = NULL; | |
162 | @@ -259,6 +313,15 @@ | |
163 | if (argv[0] && !argv[1] && family == AF_UNIX) { | |
164 | host = argv[0]; | |
165 | uport = NULL; | |
166 | + } else if (!argv[0] && lflag) { | |
167 | + if (sflag) | |
168 | + errx(1, "cannot use -s and -l"); | |
169 | + if (zflag) | |
170 | + errx(1, "cannot use -z and -l"); | |
171 | + if (pflag) | |
172 | + uport=pflag; | |
173 | + } else if (!lflag && kflag) { | |
174 | + errx(1, "cannot use -k without -l"); | |
175 | } else if (argv[0] && !argv[1]) { | |
176 | if (!lflag) | |
177 | usage(1); | |
178 | @@ -270,14 +333,7 @@ | |
179 | } else | |
180 | usage(1); | |
181 | ||
182 | - if (lflag && sflag) | |
183 | - errx(1, "cannot use -s and -l"); | |
184 | - if (lflag && pflag) | |
185 | - errx(1, "cannot use -p and -l"); | |
186 | - if (lflag && zflag) | |
187 | - errx(1, "cannot use -z and -l"); | |
188 | - if (!lflag && kflag) | |
189 | - errx(1, "must use -l with -k"); | |
190 | + | |
191 | ||
192 | /* Get name of temporary socket for unix datagram client */ | |
193 | if ((family == AF_UNIX) && uflag && !lflag) { | |
194 | @@ -286,8 +342,8 @@ | |
195 | } else { | |
196 | strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", | |
197 | UNIX_DG_TMP_SOCKET_SIZE); | |
198 | - if (mktemp(unix_dg_tmp_socket_buf) == NULL) | |
199 | - err(1, "mktemp"); | |
200 | + if (mkstemp(unix_dg_tmp_socket_buf) == -1) | |
201 | + err(1, "mkstemp"); | |
202 | unix_dg_tmp_socket = unix_dg_tmp_socket_buf; | |
203 | } | |
204 | } | |
205 | @@ -563,18 +619,22 @@ | |
206 | res0->ai_protocol)) < 0) | |
207 | continue; | |
208 | ||
209 | +# if defined(RT_TABLEID_MAX) | |
210 | if (rtableid) { | |
211 | if (setsockopt(s, SOL_SOCKET, SO_RTABLE, &rtableid, | |
212 | sizeof(rtableid)) == -1) | |
213 | err(1, "setsockopt SO_RTABLE"); | |
214 | } | |
215 | +# endif | |
216 | ||
217 | /* Bind to a local port or source address if specified. */ | |
218 | if (sflag || pflag) { | |
219 | struct addrinfo ahints, *ares; | |
220 | ||
221 | +# if defined (SO_BINDANY) | |
222 | /* try SO_BINDANY, but don't insist */ | |
223 | setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); | |
224 | +# endif | |
225 | memset(&ahints, 0, sizeof(struct addrinfo)); | |
226 | ahints.ai_family = res0->ai_family; | |
227 | ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; | |
228 | @@ -674,15 +734,23 @@ | |
229 | res0->ai_protocol)) < 0) | |
230 | continue; | |
231 | ||
232 | +# if defined(RT_TABLEID_MAX) | |
233 | if (rtableid) { | |
234 | if (setsockopt(s, IPPROTO_IP, SO_RTABLE, &rtableid, | |
235 | sizeof(rtableid)) == -1) | |
236 | err(1, "setsockopt SO_RTABLE"); | |
237 | } | |
238 | +# endif | |
239 | + | |
240 | + ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); | |
241 | + if (ret == -1) | |
242 | + err(1, NULL); | |
243 | ||
244 | +# if defined(SO_REUSEPORT) | |
245 | ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); | |
246 | if (ret == -1) | |
247 | err(1, NULL); | |
248 | +# endif | |
249 | ||
250 | set_common_sockopts(s); | |
251 | ||
252 | @@ -886,21 +954,25 @@ | |
253 | { | |
254 | int x = 1; | |
255 | ||
256 | +# if defined(TCP_MD5SIG) | |
257 | if (Sflag) { | |
258 | if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, | |
259 | &x, sizeof(x)) == -1) | |
260 | err(1, NULL); | |
261 | } | |
262 | +# endif | |
263 | if (Dflag) { | |
264 | if (setsockopt(s, SOL_SOCKET, SO_DEBUG, | |
265 | &x, sizeof(x)) == -1) | |
266 | err(1, NULL); | |
267 | } | |
268 | +# if defined(SO_JUMBO) | |
269 | if (jflag) { | |
270 | if (setsockopt(s, SOL_SOCKET, SO_JUMBO, | |
271 | &x, sizeof(x)) == -1) | |
272 | err(1, NULL); | |
273 | } | |
274 | +# endif | |
275 | if (Tflag != -1) { | |
276 | if (setsockopt(s, IPPROTO_IP, IP_TOS, | |
277 | &Tflag, sizeof(Tflag)) == -1) | |
278 | @@ -949,6 +1021,7 @@ | |
279 | { "cs7", IPTOS_DSCP_CS7 }, | |
280 | { "ef", IPTOS_DSCP_EF }, | |
281 | { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, | |
282 | + { "lowcost", IPTOS_LOWCOST }, | |
283 | { "lowdelay", IPTOS_LOWDELAY }, | |
284 | { "netcontrol", IPTOS_PREC_NETCONTROL }, | |
285 | { "reliability", IPTOS_RELIABILITY }, | |
286 | @@ -969,6 +1042,9 @@ | |
287 | void | |
288 | help(void) | |
289 | { | |
290 | +# if defined(DEBIAN_VERSION) | |
291 | + fprintf(stderr, "OpenBSD netcat (Debian patchlevel " DEBIAN_VERSION ")\n"); | |
292 | +# endif | |
293 | usage(0); | |
294 | fprintf(stderr, "\tCommand Summary:\n\ | |
295 | \t-4 Use IPv4\n\ | |
296 | @@ -978,6 +1054,7 @@ | |
297 | \t-h This help text\n\ | |
298 | \t-I length TCP receive buffer length\n\ | |
299 | \t-i secs\t Delay interval for lines sent, ports scanned\n\ | |
300 | + \t-j Use jumbo frame\n\ | |
301 | \t-k Keep inbound sockets open for multiple connects\n\ | |
302 | \t-l Listen mode, for inbound connects\n\ | |
303 | \t-n Suppress name/port resolutions\n\ | |
304 | @@ -998,15 +1075,15 @@ | |
305 | \t-x addr[:port]\tSpecify proxy address and port\n\ | |
306 | \t-z Zero-I/O mode [used for scanning]\n\ | |
307 | Port numbers can be individual or ranges: lo-hi [inclusive]\n"); | |
308 | - exit(1); | |
309 | + exit(0); | |
310 | } | |
311 | ||
312 | void | |
313 | usage(int ret) | |
314 | { | |
315 | fprintf(stderr, | |
316 | - "usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n" | |
317 | - "\t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n" | |
318 | + "usage: nc [-46DdhjklnrStUuvz] [-I length] [-i interval] [-O length]\n" | |
319 | + "\t [-P proxy_username] [-p source_port] [-s source] [-T toskeyword]\n" | |
320 | "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" | |
321 | "\t [-x proxy_address[:port]] [destination] [port]\n"); | |
322 | if (ret) | |
323 | --- a/socks.c | |
324 | +++ b/socks.c | |
325 | @@ -38,7 +38,7 @@ | |
326 | #include <string.h> | |
327 | #include <unistd.h> | |
328 | #include <resolv.h> | |
329 | -#include <readpassphrase.h> | |
330 | +#include <bsd/readpassphrase.h> | |
331 | #include "atomicio.h" | |
332 | ||
333 | #define SOCKS_PORT "1080" | |
334 | @@ -167,11 +167,11 @@ | |
335 | buf[2] = SOCKS_NOAUTH; | |
336 | cnt = atomicio(vwrite, proxyfd, buf, 3); | |
337 | if (cnt != 3) | |
338 | - err(1, "write failed (%zu/3)", cnt); | |
339 | + err(1, "write failed (%zu/3)", (size_t)cnt); | |
340 | ||
341 | cnt = atomicio(read, proxyfd, buf, 2); | |
342 | if (cnt != 2) | |
343 | - err(1, "read failed (%zu/3)", cnt); | |
344 | + err(1, "read failed (%zu/3)", (size_t)cnt); | |
345 | ||
346 | if (buf[1] == SOCKS_NOMETHOD) | |
347 | errx(1, "authentication method negotiation failed"); | |
348 | @@ -220,23 +220,23 @@ | |
349 | ||
350 | cnt = atomicio(vwrite, proxyfd, buf, wlen); | |
351 | if (cnt != wlen) | |
352 | - err(1, "write failed (%zu/%zu)", cnt, wlen); | |
353 | + err(1, "write failed (%zu/%zu)", (size_t)cnt, (size_t)wlen); | |
354 | ||
355 | cnt = atomicio(read, proxyfd, buf, 4); | |
356 | if (cnt != 4) | |
357 | - err(1, "read failed (%zu/4)", cnt); | |
358 | + err(1, "read failed (%zu/4)", (size_t)cnt); | |
359 | if (buf[1] != 0) | |
360 | errx(1, "connection failed, SOCKS error %d", buf[1]); | |
361 | switch (buf[3]) { | |
362 | case SOCKS_IPV4: | |
363 | cnt = atomicio(read, proxyfd, buf + 4, 6); | |
364 | if (cnt != 6) | |
365 | - err(1, "read failed (%d/6)", cnt); | |
366 | + err(1, "read failed (%lu/6)", (unsigned long)cnt); | |
367 | break; | |
368 | case SOCKS_IPV6: | |
369 | cnt = atomicio(read, proxyfd, buf + 4, 18); | |
370 | if (cnt != 18) | |
371 | - err(1, "read failed (%d/18)", cnt); | |
372 | + err(1, "read failed (%lu/18)", (unsigned long)cnt); | |
373 | break; | |
374 | default: | |
375 | errx(1, "connection failed, unsupported address type"); | |
376 | @@ -256,11 +256,11 @@ | |
377 | ||
378 | cnt = atomicio(vwrite, proxyfd, buf, wlen); | |
379 | if (cnt != wlen) | |
380 | - err(1, "write failed (%zu/%zu)", cnt, wlen); | |
381 | + err(1, "write failed (%zu/%zu)", (size_t)cnt, (size_t)wlen); | |
382 | ||
383 | cnt = atomicio(read, proxyfd, buf, 8); | |
384 | if (cnt != 8) | |
385 | - err(1, "read failed (%zu/8)", cnt); | |
386 | + err(1, "read failed (%zu/8)", (size_t)cnt); | |
387 | if (buf[1] != 90) | |
388 | errx(1, "connection failed, SOCKS error %d", buf[1]); | |
389 | } else if (socksv == -1) { | |
390 | @@ -272,39 +272,39 @@ | |
391 | ||
392 | /* Try to be sane about numeric IPv6 addresses */ | |
393 | if (strchr(host, ':') != NULL) { | |
394 | - r = snprintf(buf, sizeof(buf), | |
395 | + r = snprintf((char*)buf, sizeof(buf), | |
396 | "CONNECT [%s]:%d HTTP/1.0\r\n", | |
397 | host, ntohs(serverport)); | |
398 | } else { | |
399 | - r = snprintf(buf, sizeof(buf), | |
400 | + r = snprintf((char*)buf, sizeof(buf), | |
401 | "CONNECT %s:%d HTTP/1.0\r\n", | |
402 | host, ntohs(serverport)); | |
403 | } | |
404 | if (r == -1 || (size_t)r >= sizeof(buf)) | |
405 | errx(1, "hostname too long"); | |
406 | - r = strlen(buf); | |
407 | + r = strlen((char*)buf); | |
408 | ||
409 | cnt = atomicio(vwrite, proxyfd, buf, r); | |
410 | if (cnt != r) | |
411 | - err(1, "write failed (%zu/%d)", cnt, r); | |
412 | + err(1, "write failed (%zu/%d)", (size_t)cnt, (int)r); | |
413 | ||
414 | if (authretry > 1) { | |
415 | char resp[1024]; | |
416 | ||
417 | proxypass = getproxypass(proxyuser, proxyhost); | |
418 | - r = snprintf(buf, sizeof(buf), "%s:%s", | |
419 | + r = snprintf((char*)buf, sizeof(buf), "%s:%s", | |
420 | proxyuser, proxypass); | |
421 | if (r == -1 || (size_t)r >= sizeof(buf) || | |
422 | - b64_ntop(buf, strlen(buf), resp, | |
423 | + b64_ntop(buf, strlen((char*)buf), resp, | |
424 | sizeof(resp)) == -1) | |
425 | errx(1, "Proxy username/password too long"); | |
426 | - r = snprintf(buf, sizeof(buf), "Proxy-Authorization: " | |
427 | + r = snprintf((char*)buf, sizeof((char*)buf), "Proxy-Authorization: " | |
428 | "Basic %s\r\n", resp); | |
429 | if (r == -1 || (size_t)r >= sizeof(buf)) | |
430 | errx(1, "Proxy auth response too long"); | |
431 | - r = strlen(buf); | |
432 | + r = strlen((char*)buf); | |
433 | if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != r) | |
434 | - err(1, "write failed (%zu/%d)", cnt, r); | |
435 | + err(1, "write failed (%zu/%d)", (size_t)cnt, r); | |
436 | } | |
437 | ||
438 | /* Terminate headers */ | |
439 | @@ -312,22 +312,22 @@ | |
440 | err(1, "write failed (2/%d)", r); | |
441 | ||
442 | /* Read status reply */ | |
443 | - proxy_read_line(proxyfd, buf, sizeof(buf)); | |
444 | + proxy_read_line(proxyfd, (char*)buf, sizeof(buf)); | |
445 | if (proxyuser != NULL && | |
446 | - strncmp(buf, "HTTP/1.0 407 ", 12) == 0) { | |
447 | + strncmp((char*)buf, "HTTP/1.0 407 ", 12) == 0) { | |
448 | if (authretry > 1) { | |
449 | fprintf(stderr, "Proxy authentication " | |
450 | "failed\n"); | |
451 | } | |
452 | close(proxyfd); | |
453 | goto again; | |
454 | - } else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 && | |
455 | - strncmp(buf, "HTTP/1.1 200 ", 12) != 0) | |
456 | + } else if (strncmp((char*)buf, "HTTP/1.0 200 ", 12) != 0 && | |
457 | + strncmp((char*)buf, "HTTP/1.1 200 ", 12) != 0) | |
458 | errx(1, "Proxy error: \"%s\"", buf); | |
459 | ||
460 | /* Headers continue until we hit an empty line */ | |
461 | for (r = 0; r < HTTP_MAXHDRS; r++) { | |
462 | - proxy_read_line(proxyfd, buf, sizeof(buf)); | |
463 | + proxy_read_line(proxyfd, (char*)buf, sizeof(buf)); | |
464 | if (*buf == '\0') | |
465 | break; | |
466 | } |