diff options
author | deraadt <> | 2000-01-24 19:13:33 +0000 |
---|---|---|
committer | deraadt <> | 2000-01-24 19:13:33 +0000 |
commit | 6fbf17e2769ebea71b57670da9959389ce6182a2 (patch) | |
tree | 9e48f382ce51f616f05791aae053bb25401a9925 /src | |
parent | a828cd4b1259ca9a6d8da71166c0a17cbdda9765 (diff) | |
download | openbsd-6fbf17e2769ebea71b57670da9959389ce6182a2.tar.gz openbsd-6fbf17e2769ebea71b57670da9959389ce6182a2.tar.bz2 openbsd-6fbf17e2769ebea71b57670da9959389ce6182a2.zip |
first cut at indent.. more to come
Diffstat (limited to 'src')
-rw-r--r-- | src/usr.bin/nc/netcat.c | 2301 |
1 files changed, 1175 insertions, 1126 deletions
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c index fca6502e15..523c2d7bf5 100644 --- a/src/usr.bin/nc/netcat.c +++ b/src/usr.bin/nc/netcat.c | |||
@@ -33,7 +33,6 @@ | |||
33 | /* #undef _POSIX_SOURCE /* might need this for something? */ | 33 | /* #undef _POSIX_SOURCE /* might need this for something? */ |
34 | #define HAVE_BIND /* ASSUMPTION -- seems to work everywhere! */ | 34 | #define HAVE_BIND /* ASSUMPTION -- seems to work everywhere! */ |
35 | #define HAVE_HELP /* undefine if you dont want the help text */ | 35 | #define HAVE_HELP /* undefine if you dont want the help text */ |
36 | /* #define ANAL /* if you want case-sensitive DNS matching */ | ||
37 | 36 | ||
38 | #ifdef HAVE_STDLIB_H | 37 | #ifdef HAVE_STDLIB_H |
39 | #include <stdlib.h> | 38 | #include <stdlib.h> |
@@ -60,7 +59,7 @@ | |||
60 | #else | 59 | #else |
61 | #define SRAND srand | 60 | #define SRAND srand |
62 | #define RAND rand | 61 | #define RAND rand |
63 | #endif /* HAVE_RANDOM */ | 62 | #endif /* HAVE_RANDOM */ |
64 | 63 | ||
65 | /* includes: */ | 64 | /* includes: */ |
66 | #include <sys/time.h> /* timeval, time_t */ | 65 | #include <sys/time.h> /* timeval, time_t */ |
@@ -81,7 +80,7 @@ | |||
81 | #define SA struct sockaddr /* socket overgeneralization braindeath */ | 80 | #define SA struct sockaddr /* socket overgeneralization braindeath */ |
82 | #define SAI struct sockaddr_in /* ... whoever came up with this model */ | 81 | #define SAI struct sockaddr_in /* ... whoever came up with this model */ |
83 | #define IA struct in_addr /* ... should be taken out and shot, */ | 82 | #define IA struct in_addr /* ... should be taken out and shot, */ |
84 | /* ... not that TLI is any better. sigh.. */ | 83 | /* ... not that TLI is any better. sigh.. */ |
85 | #define SLEAZE_PORT 31337 /* for UDP-scan RTT trick, change if ya want */ | 84 | #define SLEAZE_PORT 31337 /* for UDP-scan RTT trick, change if ya want */ |
86 | #define USHORT unsigned short /* use these for options an' stuff */ | 85 | #define USHORT unsigned short /* use these for options an' stuff */ |
87 | #define BIGSIZ 8192 /* big buffers */ | 86 | #define BIGSIZ 8192 /* big buffers */ |
@@ -91,43 +90,44 @@ | |||
91 | #endif | 90 | #endif |
92 | 91 | ||
93 | struct host_poop { | 92 | struct host_poop { |
94 | char name[MAXHOSTNAMELEN]; /* dns name */ | 93 | char name[MAXHOSTNAMELEN]; /* dns name */ |
95 | char addrs[8][24]; /* ascii-format IP addresses */ | 94 | char addrs[8][24]; /* ascii-format IP addresses */ |
96 | struct in_addr iaddrs[8]; /* real addresses: in_addr.s_addr: ulong */ | 95 | struct in_addr iaddrs[8]; /* real addresses: in_addr.s_addr: |
96 | * ulong */ | ||
97 | }; | 97 | }; |
98 | #define HINF struct host_poop | 98 | #define HINF struct host_poop |
99 | 99 | ||
100 | struct port_poop { | 100 | struct port_poop { |
101 | char name [64]; /* name in /etc/services */ | 101 | char name[64]; /* name in /etc/services */ |
102 | char anum [8]; /* ascii-format number */ | 102 | char anum[8]; /* ascii-format number */ |
103 | USHORT num; /* real host-order number */ | 103 | USHORT num; /* real host-order number */ |
104 | }; | 104 | }; |
105 | #define PINF struct port_poop | 105 | #define PINF struct port_poop |
106 | 106 | ||
107 | /* globals: */ | 107 | /* globals: */ |
108 | jmp_buf jbuf; /* timer crud */ | 108 | jmp_buf jbuf; /* timer crud */ |
109 | int jval = 0; /* timer crud */ | 109 | int jval = 0; /* timer crud */ |
110 | int netfd = -1; | 110 | int netfd = -1; |
111 | int ofd = 0; /* hexdump output fd */ | 111 | int ofd = 0; /* hexdump output fd */ |
112 | static char unknown[] = "(UNKNOWN)"; | 112 | static char unknown[] = "(UNKNOWN)"; |
113 | static char p_tcp[] = "tcp"; /* for getservby* */ | 113 | static char p_tcp[] = "tcp"; /* for getservby* */ |
114 | static char p_udp[] = "udp"; | 114 | static char p_udp[] = "udp"; |
115 | #ifdef HAVE_BIND | 115 | #ifdef HAVE_BIND |
116 | extern int h_errno; | 116 | extern int h_errno; |
117 | /* stolen almost wholesale from bsd herror.c */ | 117 | /* stolen almost wholesale from bsd herror.c */ |
118 | static char * h_errs[] = { | 118 | static char *h_errs[] = { |
119 | "Error 0", /* but we *don't* use this */ | 119 | "Error 0", /* but we *don't* use this */ |
120 | "Unknown host", /* 1 HOST_NOT_FOUND */ | 120 | "Unknown host", /* 1 HOST_NOT_FOUND */ |
121 | "Host name lookup failure", /* 2 TRY_AGAIN */ | 121 | "Host name lookup failure", /* 2 TRY_AGAIN */ |
122 | "Unknown server error", /* 3 NO_RECOVERY */ | 122 | "Unknown server error", /* 3 NO_RECOVERY */ |
123 | "No address associated with name", /* 4 NO_ADDRESS */ | 123 | "No address associated with name", /* 4 NO_ADDRESS */ |
124 | }; | 124 | }; |
125 | #else | 125 | #else |
126 | int h_errno; /* just so we *do* have it available */ | 126 | int h_errno; /* just so we *do* have it available */ |
127 | #endif /* HAVE_BIND */ | 127 | #endif /* HAVE_BIND */ |
128 | int gatesidx = 0; /* LSRR hop count */ | 128 | int gatesidx = 0; /* LSRR hop count */ |
129 | int gatesptr = 4; /* initial LSRR pointer, settable */ | 129 | int gatesptr = 4; /* initial LSRR pointer, settable */ |
130 | USHORT Single = 1; /* zero if scanning */ | 130 | USHORT Single = 1; /* zero if scanning */ |
131 | unsigned int insaved = 0; /* stdin-buffer size for multi-mode */ | 131 | unsigned int insaved = 0; /* stdin-buffer size for multi-mode */ |
132 | unsigned int wrote_out = 0; /* total stdout bytes */ | 132 | unsigned int wrote_out = 0; /* total stdout bytes */ |
133 | unsigned int wrote_net = 0; /* total net bytes */ | 133 | unsigned int wrote_net = 0; /* total net bytes */ |
@@ -135,30 +135,30 @@ static char wrote_txt[] = " sent %d, rcvd %d"; | |||
135 | static char hexnibs[20] = "0123456789abcdef "; | 135 | static char hexnibs[20] = "0123456789abcdef "; |
136 | 136 | ||
137 | /* will malloc up the following globals: */ | 137 | /* will malloc up the following globals: */ |
138 | struct timeval * timer1 = NULL; | 138 | struct timeval *timer1 = NULL; |
139 | struct timeval * timer2 = NULL; | 139 | struct timeval *timer2 = NULL; |
140 | SAI * lclend = NULL; /* sockaddr_in structs */ | 140 | SAI *lclend = NULL; /* sockaddr_in structs */ |
141 | SAI * remend = NULL; | 141 | SAI *remend = NULL; |
142 | HINF ** gates = NULL; /* LSRR hop hostpoop */ | 142 | HINF **gates = NULL; /* LSRR hop hostpoop */ |
143 | char * optbuf = NULL; /* LSRR or sockopts */ | 143 | char *optbuf = NULL; /* LSRR or sockopts */ |
144 | char * bigbuf_in; /* data buffers */ | 144 | char *bigbuf_in; /* data buffers */ |
145 | char * bigbuf_net; | 145 | char *bigbuf_net; |
146 | fd_set * ding1; /* for select loop */ | 146 | fd_set *ding1; /* for select loop */ |
147 | fd_set * ding2; | 147 | fd_set *ding2; |
148 | PINF * portpoop = NULL; /* for getportpoop / getservby* */ | 148 | PINF *portpoop = NULL; /* for getportpoop / getservby* */ |
149 | unsigned char * stage = NULL; /* hexdump line buffer */ | 149 | unsigned char *stage = NULL; /* hexdump line buffer */ |
150 | 150 | ||
151 | /* global cmd flags: */ | 151 | /* global cmd flags: */ |
152 | USHORT o_alla = 0; | 152 | USHORT o_alla = 0; |
153 | unsigned int o_interval = 0; | 153 | unsigned int o_interval = 0; |
154 | USHORT o_listen = 0; | 154 | USHORT o_listen = 0; |
155 | USHORT o_nflag = 0; | 155 | USHORT o_nflag = 0; |
156 | USHORT o_wfile = 0; | 156 | USHORT o_wfile = 0; |
157 | USHORT o_random = 0; | 157 | USHORT o_random = 0; |
158 | USHORT o_udpmode = 0; | 158 | USHORT o_udpmode = 0; |
159 | USHORT o_verbose = 0; | 159 | USHORT o_verbose = 0; |
160 | unsigned int o_wait = 0; | 160 | unsigned int o_wait = 0; |
161 | USHORT o_zero = 0; | 161 | USHORT o_zero = 0; |
162 | /* o_tn in optional section */ | 162 | /* o_tn in optional section */ |
163 | 163 | ||
164 | /* Debug macro: squirt whatever message and sleep a bit so we can see it go | 164 | /* Debug macro: squirt whatever message and sleep a bit so we can see it go |
@@ -167,7 +167,7 @@ USHORT o_zero = 0; | |||
167 | #ifdef DEBUG | 167 | #ifdef DEBUG |
168 | #define Debug(x) printf x; printf ("\n"); fflush (stdout); sleep (1); | 168 | #define Debug(x) printf x; printf ("\n"); fflush (stdout); sleep (1); |
169 | #else | 169 | #else |
170 | #define Debug(x) /* nil... */ | 170 | #define Debug(x) /* nil... */ |
171 | #endif | 171 | #endif |
172 | 172 | ||
173 | 173 | ||
@@ -178,160 +178,164 @@ USHORT o_zero = 0; | |||
178 | fake varargs -- need to do this way because we wind up calling through | 178 | fake varargs -- need to do this way because we wind up calling through |
179 | more levels of indirection than vanilla varargs can handle, and not all | 179 | more levels of indirection than vanilla varargs can handle, and not all |
180 | machines have vfprintf/vsyslog/whatever! 6 params oughta be enough. */ | 180 | machines have vfprintf/vsyslog/whatever! 6 params oughta be enough. */ |
181 | void holler (str, p1, p2, p3, p4, p5, p6) | 181 | void |
182 | char * str; | 182 | holler(str, p1, p2, p3, p4, p5, p6) |
183 | char * p1, * p2, * p3, * p4, * p5, * p6; | 183 | char *str; |
184 | char *p1, *p2, *p3, *p4, *p5, *p6; | ||
184 | { | 185 | { |
185 | if (o_verbose) { | 186 | if (o_verbose) { |
186 | fprintf (stderr, str, p1, p2, p3, p4, p5, p6); | 187 | fprintf(stderr, str, p1, p2, p3, p4, p5, p6); |
187 | #ifdef HAVE_BIND | 188 | #ifdef HAVE_BIND |
188 | if (h_errno) { /* if host-lookup variety of error ... */ | 189 | if (h_errno) { /* if host-lookup variety of error ... */ |
189 | if (h_errno > 4) /* oh no you don't, either */ | 190 | if (h_errno > 4) /* oh no you don't, either */ |
190 | fprintf (stderr, "preposterous h_errno: %d", h_errno); | 191 | fprintf(stderr, "preposterous h_errno: %d", h_errno); |
191 | else | 192 | else |
192 | fprintf (stderr, h_errs[h_errno]); /* handle it here */ | 193 | fprintf(stderr, h_errs[h_errno]); |
193 | h_errno = 0; /* and reset for next call */ | 194 | h_errno = 0; /* and reset for next call */ |
194 | } | 195 | } |
195 | #endif | 196 | #endif |
196 | if (errno) { /* this gives funny-looking messages, but */ | 197 | if (errno) { /* this gives funny-looking messages, but */ |
197 | perror (" "); /* it's more portable than sys_errlist[]... */ | 198 | perror(" "); /* it's more portable than |
198 | } else /* xxx: do something better? */ | 199 | * sys_errlist[]... */ |
199 | fprintf (stderr, "\n"); | 200 | } else /* xxx: do something better? */ |
200 | fflush (stderr); | 201 | fprintf(stderr, "\n"); |
201 | } | 202 | fflush(stderr); |
202 | } /* holler */ | 203 | } |
204 | } /* holler */ | ||
203 | 205 | ||
204 | /* bail : | 206 | /* bail : |
205 | error-exit handler, callable from anywhere */ | 207 | error-exit handler, callable from anywhere */ |
206 | void bail (str, p1, p2, p3, p4, p5, p6) | 208 | void |
207 | char * str; | 209 | bail(str, p1, p2, p3, p4, p5, p6) |
208 | char * p1, * p2, * p3, * p4, * p5, * p6; | 210 | char *str; |
211 | char *p1, *p2, *p3, *p4, *p5, *p6; | ||
209 | { | 212 | { |
210 | o_verbose = 1; | 213 | o_verbose = 1; |
211 | holler (str, p1, p2, p3, p4, p5, p6); | 214 | holler(str, p1, p2, p3, p4, p5, p6); |
212 | close (netfd); | 215 | close(netfd); |
213 | sleep (1); | 216 | sleep(1); |
214 | exit (1); | 217 | exit(1); |
215 | } /* bail */ | 218 | } /* bail */ |
216 | 219 | ||
217 | /* catch : | 220 | /* catch : |
218 | no-brainer interrupt handler */ | 221 | no-brainer interrupt handler */ |
219 | void catch () | 222 | void |
223 | catch() | ||
220 | { | 224 | { |
221 | errno = 0; | 225 | errno = 0; |
222 | if (o_verbose > 1) /* normally we don't care */ | 226 | if (o_verbose > 1) /* normally we don't care */ |
223 | bail (wrote_txt, wrote_net, wrote_out); | 227 | bail(wrote_txt, wrote_net, wrote_out); |
224 | bail (" punt!"); | 228 | bail(" punt!"); |
225 | } | 229 | } |
226 | 230 | ||
227 | /* timeout and other signal handling cruft */ | 231 | /* timeout and other signal handling cruft */ |
228 | void tmtravel () | 232 | void |
233 | tmtravel() | ||
229 | { | 234 | { |
230 | signal (SIGALRM, SIG_IGN); | 235 | signal(SIGALRM, SIG_IGN); |
231 | alarm (0); | 236 | alarm(0); |
232 | if (jval == 0) | 237 | if (jval == 0) |
233 | bail ("spurious timer interrupt!"); | 238 | bail("spurious timer interrupt!"); |
234 | longjmp (jbuf, jval); | 239 | longjmp(jbuf, jval); |
235 | } | 240 | } |
236 | 241 | ||
237 | /* arm : | 242 | /* arm : |
238 | set the timer. Zero secs arg means unarm */ | 243 | set the timer. Zero secs arg means unarm */ |
239 | void arm (num, secs) | 244 | void |
240 | unsigned int num; | 245 | arm(num, secs) |
241 | unsigned int secs; | 246 | unsigned int num; |
247 | unsigned int secs; | ||
242 | { | 248 | { |
243 | if (secs == 0) { /* reset */ | 249 | if (secs == 0) { /* reset */ |
244 | signal (SIGALRM, SIG_IGN); | 250 | signal(SIGALRM, SIG_IGN); |
245 | alarm (0); | 251 | alarm(0); |
246 | jval = 0; | 252 | jval = 0; |
247 | } else { /* set */ | 253 | } else { /* set */ |
248 | signal (SIGALRM, tmtravel); | 254 | signal(SIGALRM, tmtravel); |
249 | alarm (secs); | 255 | alarm(secs); |
250 | jval = num; | 256 | jval = num; |
251 | } /* if secs */ | 257 | } /* if secs */ |
252 | } /* arm */ | 258 | } /* arm */ |
253 | 259 | ||
254 | /* Hmalloc : | 260 | /* Hmalloc : |
255 | malloc up what I want, rounded up to *4, and pre-zeroed. Either succeeds | 261 | malloc up what I want, rounded up to *4, and pre-zeroed. Either succeeds |
256 | or bails out on its own, so that callers don't have to worry about it. */ | 262 | or bails out on its own, so that callers don't have to worry about it. */ |
257 | char * Hmalloc (size) | 263 | char * |
258 | unsigned int size; | 264 | Hmalloc(size) |
265 | unsigned int size; | ||
259 | { | 266 | { |
260 | unsigned int s = (size + 4) & 0xfffffffc; /* 4GB?! */ | 267 | unsigned int s = (size + 4) & 0xfffffffc; /* 4GB?! */ |
261 | char * p = malloc (s); | 268 | char *p = malloc(s); |
262 | if (p != NULL) | 269 | if (p != NULL) |
263 | memset (p, 0, s); | 270 | memset(p, 0, s); |
264 | else | 271 | else |
265 | bail ("Hmalloc %d failed", s); | 272 | bail("Hmalloc %d failed", s); |
266 | return (p); | 273 | return (p); |
267 | } /* Hmalloc */ | 274 | } /* Hmalloc */ |
268 | 275 | ||
269 | /* findline : | 276 | /* findline : |
270 | find the next newline in a buffer; return inclusive size of that "line", | 277 | find the next newline in a buffer; return inclusive size of that "line", |
271 | or the entire buffer size, so the caller knows how much to then write(). | 278 | or the entire buffer size, so the caller knows how much to then write(). |
272 | Not distinguishing \n vs \r\n for the nonce; it just works as is... */ | 279 | Not distinguishing \n vs \r\n for the nonce; it just works as is... */ |
273 | unsigned int findline (buf, siz) | 280 | unsigned int |
274 | char * buf; | 281 | findline(buf, siz) |
275 | unsigned int siz; | 282 | char *buf; |
283 | unsigned int siz; | ||
276 | { | 284 | { |
277 | register char * p; | 285 | register char *p; |
278 | register int x; | 286 | register int x; |
279 | if (! buf) /* various sanity checks... */ | 287 | if (!buf) /* various sanity checks... */ |
280 | return (0); | 288 | return (0); |
281 | if (siz > BIGSIZ) | 289 | if (siz > BIGSIZ) |
282 | return (0); | 290 | return (0); |
283 | x = siz; | 291 | x = siz; |
284 | for (p = buf; x > 0; x--) { | 292 | for (p = buf; x > 0; x--) { |
285 | if (*p == '\n') { | 293 | if (*p == '\n') { |
286 | x = (int) (p - buf); | 294 | x = (int) (p - buf); |
287 | x++; /* 'sokay if it points just past the end! */ | 295 | x++; /* 'sokay if it points just past the end! */ |
288 | Debug (("findline returning %d", x)) | 296 | Debug(("findline returning %d", x)) |
289 | return (x); | 297 | return (x); |
290 | } | 298 | } |
291 | p++; | 299 | p++; |
292 | } /* for */ | 300 | } /* for */ |
293 | Debug (("findline returning whole thing: %d", siz)) | 301 | Debug(("findline returning whole thing: %d", siz)) |
294 | return (siz); | 302 | return (siz); |
295 | } /* findline */ | 303 | } /* findline */ |
296 | 304 | ||
297 | /* comparehosts : | 305 | /* comparehosts : |
298 | cross-check the host_poop we have so far against new gethostby*() info, | 306 | cross-check the host_poop we have so far against new gethostby*() info, |
299 | and holler about mismatches. Perhaps gratuitous, but it can't hurt to | 307 | and holler about mismatches. Perhaps gratuitous, but it can't hurt to |
300 | point out when someone's DNS is fukt. Returns 1 if mismatch, in case | 308 | point out when someone's DNS is fukt. Returns 1 if mismatch, in case |
301 | someone else wants to do something about it. */ | 309 | someone else wants to do something about it. */ |
302 | int comparehosts (poop, hp) | 310 | int |
303 | HINF * poop; | 311 | comparehosts(poop, hp) |
304 | struct hostent * hp; | 312 | HINF *poop; |
313 | struct hostent *hp; | ||
305 | { | 314 | { |
306 | errno = 0; | 315 | errno = 0; |
307 | h_errno = 0; | 316 | h_errno = 0; |
308 | /* The DNS spec is officially case-insensitive, but for those times when you | 317 | if (strcasecmp(poop->name, hp->h_name) != 0) { /* normal */ |
309 | *really* wanna see any and all discrepancies, by all means define this. */ | 318 | holler("DNS fwd/rev mismatch: %s != %s", poop->name, hp->h_name); |
310 | #ifdef ANAL | 319 | return (1); |
311 | if (strcmp (poop->name, hp->h_name) != 0) { /* case-sensitive */ | 320 | } |
312 | #else | 321 | return (0); |
313 | if (strcasecmp (poop->name, hp->h_name) != 0) { /* normal */ | ||
314 | #endif | ||
315 | holler ("DNS fwd/rev mismatch: %s != %s", poop->name, hp->h_name); | ||
316 | return (1); | ||
317 | } | ||
318 | return (0); | ||
319 | /* ... do we need to do anything over and above that?? */ | 322 | /* ... do we need to do anything over and above that?? */ |
320 | } /* comparehosts */ | 323 | } /* comparehosts */ |
321 | 324 | ||
322 | /* gethostpoop : | 325 | /* gethostpoop : |
323 | resolve a host 8 ways from sunday; return a new host_poop struct with its | 326 | resolve a host 8 ways from sunday; return a new host_poop struct with its |
324 | info. The argument can be a name or [ascii] IP address; it will try its | 327 | info. The argument can be a name or [ascii] IP address; it will try its |
325 | damndest to deal with it. "numeric" governs whether we do any DNS at all, | 328 | damndest to deal with it. "numeric" governs whether we do any DNS at all, |
326 | and we also check o_verbose for what's appropriate work to do. */ | 329 | and we also check o_verbose for what's appropriate work to do. */ |
327 | HINF * gethostpoop (name, numeric) | 330 | HINF * |
328 | char * name; | 331 | gethostpoop(name, numeric) |
329 | USHORT numeric; | 332 | char *name; |
333 | USHORT numeric; | ||
330 | { | 334 | { |
331 | struct hostent * hostent; | 335 | struct hostent *hostent; |
332 | struct in_addr iaddr; | 336 | struct in_addr iaddr; |
333 | register HINF * poop = NULL; | 337 | register HINF *poop = NULL; |
334 | register int x; | 338 | register int x; |
335 | 339 | ||
336 | /* I really want to strangle the twit who dreamed up all these sockaddr and | 340 | /* I really want to strangle the twit who dreamed up all these sockaddr and |
337 | hostent abstractions, and then forced them all to be incompatible with | 341 | hostent abstractions, and then forced them all to be incompatible with |
@@ -352,72 +356,73 @@ HINF * gethostpoop (name, numeric) | |||
352 | as we're here, do a complete DNS check on these clowns. Yes, it slows | 356 | as we're here, do a complete DNS check on these clowns. Yes, it slows |
353 | things down a bit for a first run, but once it's cached, who cares? */ | 357 | things down a bit for a first run, but once it's cached, who cares? */ |
354 | 358 | ||
355 | errno = 0; | 359 | errno = 0; |
356 | h_errno = 0; | 360 | h_errno = 0; |
357 | if (name) | 361 | if (name) |
358 | poop = (HINF *) Hmalloc (sizeof (HINF)); | 362 | poop = (HINF *) Hmalloc(sizeof(HINF)); |
359 | if (! poop) | 363 | if (!poop) |
360 | bail ("gethostpoop fuxored"); | 364 | bail("gethostpoop fuxored"); |
361 | strlcpy (poop->name, unknown, sizeof(poop->name)); /* preload it */ | 365 | strlcpy(poop->name, unknown, sizeof(poop->name)); /* preload it */ |
362 | if (inet_aton (name, &iaddr) == 0) { /* here's the great split: names... */ | 366 | if (inet_aton(name, &iaddr) == 0) { /* here's the great split: |
363 | 367 | * names... */ | |
364 | if (numeric) | 368 | |
365 | bail ("Can't parse %s as an IP address", name); | 369 | if (numeric) |
366 | hostent = gethostbyname (name); | 370 | bail("Can't parse %s as an IP address", name); |
367 | if (! hostent) | 371 | hostent = gethostbyname(name); |
372 | if (!hostent) | ||
368 | /* failure to look up a name is fatal, since we can't do anything with it */ | 373 | /* failure to look up a name is fatal, since we can't do anything with it */ |
369 | bail ("%s: forward host lookup failed: ", name); | 374 | bail("%s: forward host lookup failed: ", name); |
370 | strncpy (poop->name, hostent->h_name, MAXHOSTNAMELEN - 1); | 375 | strncpy(poop->name, hostent->h_name, MAXHOSTNAMELEN - 1); |
371 | poop->name[MAXHOSTNAMELEN - 1] = '\0'; | 376 | poop->name[MAXHOSTNAMELEN - 1] = '\0'; |
372 | for (x = 0; hostent->h_addr_list[x] && (x < 8); x++) { | 377 | for (x = 0; hostent->h_addr_list[x] && (x < 8); x++) { |
373 | memcpy (&poop->iaddrs[x], hostent->h_addr_list[x], sizeof (IA)); | 378 | memcpy(&poop->iaddrs[x], hostent->h_addr_list[x], sizeof(IA)); |
374 | strncpy (poop->addrs[x], inet_ntoa (poop->iaddrs[x]), | 379 | strncpy(poop->addrs[x], inet_ntoa(poop->iaddrs[x]), |
375 | sizeof (poop->addrs[0])-1); | 380 | sizeof(poop->addrs[0]) - 1); |
376 | poop->addrs[x][sizeof (poop->addrs[0]) - 1] = '\0'; | 381 | poop->addrs[x][sizeof(poop->addrs[0]) - 1] = '\0'; |
377 | } /* for x -> addrs, part A */ | 382 | } /* for x -> addrs, part A */ |
378 | if (! o_verbose) /* if we didn't want to see the */ | 383 | if (!o_verbose) /* if we didn't want to see the */ |
379 | return (poop); /* inverse stuff, we're done. */ | 384 | return (poop); /* inverse stuff, we're done. */ |
380 | /* do inverse lookups in separate loop based on our collected forward addrs, | 385 | /* do inverse lookups in separate loop based on our collected forward addrs, |
381 | since gethostby* tends to crap into the same buffer over and over */ | 386 | since gethostby* tends to crap into the same buffer over and over */ |
382 | for (x = 0; poop->iaddrs[x].s_addr && (x < 8); x++) { | 387 | for (x = 0; poop->iaddrs[x].s_addr && (x < 8); x++) { |
383 | hostent = gethostbyaddr ((char *)&poop->iaddrs[x], | 388 | hostent = gethostbyaddr((char *) &poop->iaddrs[x], |
384 | sizeof (IA), AF_INET); | 389 | sizeof(IA), AF_INET); |
385 | if ((! hostent) || (! hostent-> h_name)) | 390 | if ((!hostent) || (!hostent->h_name)) |
386 | holler ("Warning: inverse host lookup failed for %s: ", | 391 | holler("Warning: inverse host lookup failed for %s: ", |
387 | poop->addrs[x]); | 392 | poop->addrs[x]); |
388 | else | 393 | else |
389 | (void) comparehosts (poop, hostent); | 394 | (void) comparehosts(poop, hostent); |
390 | } /* for x -> addrs, part B */ | 395 | } /* for x -> addrs, part B */ |
391 | 396 | ||
392 | } else { /* not INADDR_NONE: numeric addresses... */ | 397 | } else { /* not INADDR_NONE: numeric addresses... */ |
393 | memcpy (poop->iaddrs, &iaddr, sizeof (IA)); | 398 | memcpy(poop->iaddrs, &iaddr, sizeof(IA)); |
394 | strncpy (poop->addrs[0], inet_ntoa (iaddr), sizeof (poop->addrs)-1); | 399 | strncpy(poop->addrs[0], inet_ntoa(iaddr), sizeof(poop->addrs) - 1); |
395 | poop->addrs[0][sizeof (poop->addrs)-1] = '\0'; | 400 | poop->addrs[0][sizeof(poop->addrs) - 1] = '\0'; |
396 | if (numeric) /* if numeric-only, we're done */ | 401 | if (numeric) /* if numeric-only, we're done */ |
397 | return (poop); | 402 | return (poop); |
398 | if (! o_verbose) /* likewise if we don't want */ | 403 | if (!o_verbose) /* likewise if we don't want */ |
399 | return (poop); /* the full DNS hair */ | 404 | return (poop); /* the full DNS hair */ |
400 | hostent = gethostbyaddr ((char *) &iaddr, sizeof (IA), AF_INET); | 405 | hostent = gethostbyaddr((char *) &iaddr, sizeof(IA), AF_INET); |
401 | /* numeric or not, failure to look up a PTR is *not* considered fatal */ | 406 | /* numeric or not, failure to look up a PTR is *not* considered fatal */ |
402 | if (! hostent) | 407 | if (!hostent) |
403 | holler ("%s: inverse host lookup failed: ", name); | 408 | holler("%s: inverse host lookup failed: ", name); |
404 | else { | 409 | else { |
405 | strncpy (poop->name, hostent->h_name, MAXHOSTNAMELEN - 1); | 410 | strncpy(poop->name, hostent->h_name, MAXHOSTNAMELEN - 1); |
406 | poop->name[MAXHOSTNAMELEN-1] = '\0'; | 411 | poop->name[MAXHOSTNAMELEN - 1] = '\0'; |
407 | hostent = gethostbyname (poop->name); | 412 | hostent = gethostbyname(poop->name); |
408 | if ((! hostent) || (! hostent->h_addr_list[0])) | 413 | if ((!hostent) || (!hostent->h_addr_list[0])) |
409 | holler ("Warning: forward host lookup failed for %s: ", | 414 | holler("Warning: forward host lookup failed for %s: ", |
410 | poop->name); | 415 | poop->name); |
411 | else | 416 | else |
412 | (void) comparehosts (poop, hostent); | 417 | (void) comparehosts(poop, hostent); |
413 | } /* if hostent */ | 418 | } /* if hostent */ |
414 | } /* INADDR_NONE Great Split */ | 419 | } /* INADDR_NONE Great Split */ |
415 | 420 | ||
416 | /* whatever-all went down previously, we should now have a host_poop struct | 421 | /* whatever-all went down previously, we should now have a host_poop struct |
417 | with at least one IP address in it. */ | 422 | with at least one IP address in it. */ |
418 | h_errno = 0; | 423 | h_errno = 0; |
419 | return (poop); | 424 | return (poop); |
420 | } /* gethostpoop */ | 425 | } /* gethostpoop */ |
421 | 426 | ||
422 | /* getportpoop : | 427 | /* getportpoop : |
423 | Same general idea as gethostpoop -- look up a port in /etc/services, fill | 428 | Same general idea as gethostpoop -- look up a port in /etc/services, fill |
@@ -426,61 +431,62 @@ HINF * gethostpoop (name, numeric) | |||
426 | pnum to reverse-resolve something that's already a number. | 431 | pnum to reverse-resolve something that's already a number. |
427 | If o_nflag is on, fill in what we can but skip the getservby??? stuff. | 432 | If o_nflag is on, fill in what we can but skip the getservby??? stuff. |
428 | Might as well have consistent behavior here, and it *is* faster. */ | 433 | Might as well have consistent behavior here, and it *is* faster. */ |
429 | USHORT getportpoop (pstring, pnum) | 434 | USHORT |
430 | char * pstring; | 435 | getportpoop(pstring, pnum) |
431 | unsigned int pnum; | 436 | char *pstring; |
437 | unsigned int pnum; | ||
432 | { | 438 | { |
433 | struct servent * servent; | 439 | struct servent *servent; |
434 | register int x; | 440 | register int x; |
435 | register int y; | 441 | register int y; |
436 | char * whichp = p_tcp; | 442 | char *whichp = p_tcp; |
437 | if (o_udpmode) | 443 | if (o_udpmode) |
438 | whichp = p_udp; | 444 | whichp = p_udp; |
439 | portpoop->name[0] = '?'; /* fast preload */ | 445 | portpoop->name[0] = '?';/* fast preload */ |
440 | portpoop->name[1] = '\0'; | 446 | portpoop->name[1] = '\0'; |
441 | 447 | ||
442 | /* case 1: reverse-lookup of a number; placed first since this case is much | 448 | /* case 1: reverse-lookup of a number; placed first since this case is much |
443 | more frequent if we're scanning */ | 449 | more frequent if we're scanning */ |
444 | if (pnum) { | 450 | if (pnum) { |
445 | if (pstring) /* one or the other, pleeze */ | 451 | if (pstring) /* one or the other, pleeze */ |
446 | return (0); | 452 | return (0); |
447 | x = pnum; | 453 | x = pnum; |
448 | if (o_nflag) /* go faster, skip getservbyblah */ | 454 | if (o_nflag) /* go faster, skip getservbyblah */ |
449 | goto gp_finish; | 455 | goto gp_finish; |
450 | y = htons (x); /* gotta do this -- see Fig.1 below */ | 456 | y = htons(x); /* gotta do this -- see Fig.1 below */ |
451 | servent = getservbyport (y, whichp); | 457 | servent = getservbyport(y, whichp); |
452 | if (servent) { | 458 | if (servent) { |
453 | y = ntohs (servent->s_port); | 459 | y = ntohs(servent->s_port); |
454 | if (x != y) /* "never happen" */ | 460 | if (x != y) /* "never happen" */ |
455 | holler ("Warning: port-bynum mismatch, %d != %d", x, y); | 461 | holler("Warning: port-bynum mismatch, %d != %d", x, y); |
456 | strncpy (portpoop->name, servent->s_name, sizeof (portpoop->name)-1); | 462 | strncpy(portpoop->name, servent->s_name, sizeof(portpoop->name) - 1); |
457 | portpoop->name[sizeof (portpoop->name)-1] = '\0'; | 463 | portpoop->name[sizeof(portpoop->name) - 1] = '\0'; |
458 | } /* if servent */ | 464 | } /* if servent */ |
459 | goto gp_finish; | 465 | goto gp_finish; |
460 | } /* if pnum */ | 466 | } /* if pnum */ |
461 | 467 | /* case 2: resolve a string, but we still give preference to numbers | |
462 | /* case 2: resolve a string, but we still give preference to numbers instead | 468 | * instead of trying to resolve conflicts. None of the entries in *my* |
463 | of trying to resolve conflicts. None of the entries in *my* extensive | 469 | * extensive /etc/services begins with a digit, so this should "always |
464 | /etc/services begins with a digit, so this should "always work" unless | 470 | * work" unless you're at 3com and have some company-internal services |
465 | you're at 3com and have some company-internal services defined... */ | 471 | * defined... */ |
466 | if (pstring) { | 472 | if (pstring) { |
467 | if (pnum) /* one or the other, pleeze */ | 473 | if (pnum) /* one or the other, pleeze */ |
468 | return (0); | 474 | return (0); |
469 | x = atoi (pstring); | 475 | x = atoi(pstring); |
470 | if (x) | 476 | if (x) |
471 | return (getportpoop (NULL, x)); /* recurse for numeric-string-arg */ | 477 | return (getportpoop(NULL, x)); /* recurse for |
472 | if (o_nflag) /* can't use names! */ | 478 | * numeric-string-arg */ |
473 | return (0); | 479 | if (o_nflag) /* can't use names! */ |
474 | servent = getservbyname (pstring, whichp); | 480 | return (0); |
475 | if (servent) { | 481 | servent = getservbyname(pstring, whichp); |
476 | strncpy (portpoop->name, servent->s_name, sizeof (portpoop->name)-1); | 482 | if (servent) { |
477 | portpoop->name[sizeof (portpoop->name)-1] = '\0'; | 483 | strncpy(portpoop->name, servent->s_name, sizeof(portpoop->name) - 1); |
478 | x = ntohs (servent->s_port); | 484 | portpoop->name[sizeof(portpoop->name) - 1] = '\0'; |
479 | goto gp_finish; | 485 | x = ntohs(servent->s_port); |
480 | } /* if servent */ | 486 | goto gp_finish; |
481 | } /* if pstring */ | 487 | } /* if servent */ |
482 | 488 | } /* if pstring */ | |
483 | return (0); /* catches any problems so far */ | 489 | return (0); /* catches any problems so far */ |
484 | 490 | ||
485 | /* Obligatory netdb.h-inspired rant: servent.s_port is supposed to be an int. | 491 | /* Obligatory netdb.h-inspired rant: servent.s_port is supposed to be an int. |
486 | Despite this, we still have to treat it as a short when copying it around. | 492 | Despite this, we still have to treat it as a short when copying it around. |
@@ -496,10 +502,11 @@ USHORT getportpoop (pstring, pnum) | |||
496 | gp_finish: | 502 | gp_finish: |
497 | /* Fall here whether or not we have a valid servent at this point, with | 503 | /* Fall here whether or not we have a valid servent at this point, with |
498 | x containing our [host-order and therefore useful, dammit] port number */ | 504 | x containing our [host-order and therefore useful, dammit] port number */ |
499 | sprintf (portpoop->anum, "%d", x); /* always load any numeric specs! */ | 505 | sprintf(portpoop->anum, "%d", x); /* always load any numeric |
500 | portpoop->num = (x & 0xffff); /* ushort, remember... */ | 506 | * specs! */ |
501 | return (portpoop->num); | 507 | portpoop->num = (x & 0xffff); /* ushort, remember... */ |
502 | } /* getportpoop */ | 508 | return (portpoop->num); |
509 | } /* getportpoop */ | ||
503 | 510 | ||
504 | /* nextport : | 511 | /* nextport : |
505 | Come up with the next port to try, be it random or whatever. "block" is | 512 | Come up with the next port to try, be it random or whatever. "block" is |
@@ -508,62 +515,63 @@ gp_finish: | |||
508 | 1 to be tested | 515 | 1 to be tested |
509 | 2 tested [which is set as we find them here] | 516 | 2 tested [which is set as we find them here] |
510 | returns a USHORT random port, or 0 if all the t-b-t ones are used up. */ | 517 | returns a USHORT random port, or 0 if all the t-b-t ones are used up. */ |
511 | USHORT nextport (block) | 518 | USHORT |
512 | char * block; | 519 | nextport(block) |
520 | char *block; | ||
513 | { | 521 | { |
514 | register unsigned int x; | 522 | register unsigned int x; |
515 | register unsigned int y; | 523 | register unsigned int y; |
516 | 524 | ||
517 | y = 70000; /* high safety count for rnd-tries */ | 525 | y = 70000; /* high safety count for rnd-tries */ |
518 | while (y > 0) { | 526 | while (y > 0) { |
519 | x = (RAND() & 0xffff); | 527 | x = (RAND() & 0xffff); |
520 | if (block[x] == 1) { /* try to find a not-done one... */ | 528 | if (block[x] == 1) { /* try to find a not-done one... */ |
521 | block[x] = 2; | 529 | block[x] = 2; |
522 | break; | 530 | break; |
523 | } | 531 | } |
524 | x = 0; /* bummer. */ | 532 | x = 0; /* bummer. */ |
525 | y--; | 533 | y--; |
526 | } /* while y */ | 534 | } /* while y */ |
527 | if (x) | 535 | if (x) |
528 | return (x); | 536 | return (x); |
529 | 537 | ||
530 | y = 65535; /* no random one, try linear downsearch */ | 538 | y = 65535; /* no random one, try linear downsearch */ |
531 | while (y > 0) { /* if they're all used, we *must* be sure! */ | 539 | while (y > 0) { /* if they're all used, we *must* be sure! */ |
532 | if (block[y] == 1) { | 540 | if (block[y] == 1) { |
533 | block[y] = 2; | 541 | block[y] = 2; |
534 | break; | 542 | break; |
535 | } | 543 | } |
536 | y--; | 544 | y--; |
537 | } /* while y */ | 545 | } /* while y */ |
538 | if (y) | 546 | if (y) |
539 | return (y); /* at least one left */ | 547 | return (y); /* at least one left */ |
540 | 548 | ||
541 | return (0); /* no more left! */ | 549 | return (0); /* no more left! */ |
542 | } /* nextport */ | 550 | } /* nextport */ |
543 | 551 | ||
544 | /* loadports : | 552 | /* loadports : |
545 | set "to be tested" indications in BLOCK, from LO to HI. Almost too small | 553 | set "to be tested" indications in BLOCK, from LO to HI. Almost too small |
546 | to be a separate routine, but makes main() a little cleaner... */ | 554 | to be a separate routine, but makes main() a little cleaner... */ |
547 | void loadports (block, lo, hi) | 555 | void |
548 | char * block; | 556 | loadports(block, lo, hi) |
549 | USHORT lo; | 557 | char *block; |
550 | USHORT hi; | 558 | USHORT lo; |
559 | USHORT hi; | ||
551 | { | 560 | { |
552 | USHORT x; | 561 | USHORT x; |
553 | 562 | ||
554 | if (! block) | 563 | if (!block) |
555 | bail ("loadports: no block?!"); | 564 | bail("loadports: no block?!"); |
556 | if ((! lo) || (! hi)) | 565 | if ((!lo) || (!hi)) |
557 | bail ("loadports: bogus values %d, %d", lo, hi); | 566 | bail("loadports: bogus values %d, %d", lo, hi); |
558 | x = hi; | 567 | x = hi; |
559 | while (lo <= x) { | 568 | while (lo <= x) { |
560 | block[x] = 1; | 569 | block[x] = 1; |
561 | x--; | 570 | x--; |
562 | } | 571 | } |
563 | } /* loadports */ | 572 | } /* loadports */ |
564 | |||
565 | #ifdef GAPING_SECURITY_HOLE | 573 | #ifdef GAPING_SECURITY_HOLE |
566 | char * pr00gie = NULL; /* global ptr to -e arg */ | 574 | char *pr00gie = NULL; /* global ptr to -e arg */ |
567 | 575 | ||
568 | /* doexec : | 576 | /* doexec : |
569 | fiddle all the file descriptors around, and hand off to another prog. Sort | 577 | fiddle all the file descriptors around, and hand off to another prog. Sort |
@@ -571,25 +579,25 @@ char * pr00gie = NULL; /* global ptr to -e arg */ | |||
571 | that would be security-critical, which is why it's ifdefed out by default. | 579 | that would be security-critical, which is why it's ifdefed out by default. |
572 | Use at your own hairy risk; if you leave shells lying around behind open | 580 | Use at your own hairy risk; if you leave shells lying around behind open |
573 | listening ports you deserve to lose!! */ | 581 | listening ports you deserve to lose!! */ |
574 | doexec (fd) | 582 | doexec(fd) |
575 | int fd; | 583 | int fd; |
576 | { | 584 | { |
577 | register char * p; | 585 | register char *p; |
578 | 586 | ||
579 | dup2 (fd, 0); /* the precise order of fiddlage */ | 587 | dup2(fd, 0); /* the precise order of fiddlage */ |
580 | close (fd); /* is apparently crucial; this is */ | 588 | close(fd); /* is apparently crucial; this is */ |
581 | dup2 (0, 1); /* swiped directly out of "inetd". */ | 589 | dup2(0, 1); /* swiped directly out of "inetd". */ |
582 | dup2 (0, 2); | 590 | dup2(0, 2); |
583 | p = strrchr (pr00gie, '/'); /* shorter argv[0] */ | 591 | p = strrchr(pr00gie, '/'); /* shorter argv[0] */ |
584 | if (p) | 592 | if (p) |
585 | p++; | 593 | p++; |
586 | else | 594 | else |
587 | p = pr00gie; | 595 | p = pr00gie; |
588 | Debug (("gonna exec %s as %s...", pr00gie, p)) | 596 | Debug(("gonna exec %s as %s...", pr00gie, p)) |
589 | execl (pr00gie, p, NULL); | 597 | execl(pr00gie, p, NULL); |
590 | bail ("exec %s failed", pr00gie); /* this gets sent out. Hmm... */ | 598 | bail("exec %s failed", pr00gie); /* this gets sent out. Hmm... */ |
591 | } /* doexec */ | 599 | } /* doexec */ |
592 | #endif /* GAPING_SECURITY_HOLE */ | 600 | #endif /* GAPING_SECURITY_HOLE */ |
593 | 601 | ||
594 | /* doconnect : | 602 | /* doconnect : |
595 | do all the socket stuff, and return an fd for one of | 603 | do all the socket stuff, and return an fd for one of |
@@ -598,83 +606,84 @@ Debug (("gonna exec %s as %s...", pr00gie, p)) | |||
598 | with appropriate socket options set up if we wanted source-routing, or | 606 | with appropriate socket options set up if we wanted source-routing, or |
599 | an unconnected TCP or UDP socket to listen on. | 607 | an unconnected TCP or UDP socket to listen on. |
600 | Examines various global o_blah flags to figure out what-all to do. */ | 608 | Examines various global o_blah flags to figure out what-all to do. */ |
601 | int doconnect (rad, rp, lad, lp) | 609 | int |
602 | IA * rad; | 610 | doconnect(rad, rp, lad, lp) |
603 | USHORT rp; | 611 | IA *rad; |
604 | IA * lad; | 612 | USHORT rp; |
605 | USHORT lp; | 613 | IA *lad; |
614 | USHORT lp; | ||
606 | { | 615 | { |
607 | register int nnetfd; | 616 | register int nnetfd; |
608 | register int rr; | 617 | register int rr; |
609 | int x, y; | 618 | int x, y; |
610 | errno = 0; | 619 | errno = 0; |
611 | 620 | ||
612 | /* grab a socket; set opts */ | 621 | /* grab a socket; set opts */ |
613 | newskt: | 622 | newskt: |
614 | if (o_udpmode) | 623 | if (o_udpmode) |
615 | nnetfd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); | 624 | nnetfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
616 | else | 625 | else |
617 | nnetfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); | 626 | nnetfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
618 | if (nnetfd < 0) | 627 | if (nnetfd < 0) |
619 | bail ("Can't get socket"); | 628 | bail("Can't get socket"); |
620 | if (nnetfd == 0) /* if stdin was closed this might *be* 0, */ | 629 | if (nnetfd == 0) /* if stdin was closed this might *be* 0, */ |
621 | goto newskt; /* so grab another. See text for why... */ | 630 | goto newskt; /* so grab another. See text for why... */ |
622 | x = 1; | 631 | x = 1; |
623 | rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)); | 632 | rr = setsockopt(nnetfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); |
624 | if (rr == -1) | 633 | if (rr == -1) |
625 | holler ("nnetfd reuseaddr failed"); /* ??? */ | 634 | holler("nnetfd reuseaddr failed"); /* ??? */ |
626 | #ifdef SO_REUSEPORT /* doesnt exist everywhere... */ | 635 | #ifdef SO_REUSEPORT /* doesnt exist everywhere... */ |
627 | rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEPORT, &x, sizeof (x)); | 636 | rr = setsockopt(nnetfd, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); |
628 | if (rr == -1) | 637 | if (rr == -1) |
629 | holler ("nnetfd reuseport failed"); /* ??? */ | 638 | holler("nnetfd reuseport failed"); /* ??? */ |
630 | #endif | 639 | #endif |
631 | #if 0 | 640 | #if 0 |
632 | /* If you want to screw with RCVBUF/SNDBUF, do it here. Liudvikas Bukys at | 641 | /* If you want to screw with RCVBUF/SNDBUF, do it here. Liudvikas Bukys at |
633 | Rochester sent this example, which would involve YET MORE options and is | 642 | Rochester sent this example, which would involve YET MORE options and is |
634 | just archived here in case you want to mess with it. o_xxxbuf are global | 643 | just archived here in case you want to mess with it. o_xxxbuf are global |
635 | integers set in main() getopt loop, and check for rr == 0 afterward. */ | 644 | integers set in main() getopt loop, and check for rr == 0 afterward. */ |
636 | rr = setsockopt(nnetfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); | 645 | rr = setsockopt(nnetfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); |
637 | rr = setsockopt(nnetfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); | 646 | rr = setsockopt(nnetfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); |
638 | #endif | 647 | #endif |
639 | 648 | ||
640 | /* fill in all the right sockaddr crud */ | 649 | /* fill in all the right sockaddr crud */ |
641 | lclend->sin_family = AF_INET; | 650 | lclend->sin_family = AF_INET; |
642 | 651 | ||
643 | /* fill in all the right sockaddr crud */ | 652 | /* fill in all the right sockaddr crud */ |
644 | lclend->sin_family = AF_INET; | 653 | lclend->sin_family = AF_INET; |
645 | remend->sin_family = AF_INET; | 654 | remend->sin_family = AF_INET; |
646 | 655 | ||
647 | /* if lad/lp, do appropriate binding */ | 656 | /* if lad/lp, do appropriate binding */ |
648 | if (lad) | 657 | if (lad) |
649 | memcpy (&lclend->sin_addr.s_addr, lad, sizeof (IA)); | 658 | memcpy(&lclend->sin_addr.s_addr, lad, sizeof(IA)); |
650 | if (lp) | 659 | if (lp) |
651 | lclend->sin_port = htons (lp); | 660 | lclend->sin_port = htons(lp); |
652 | rr = 0; | 661 | rr = 0; |
653 | if (lad || lp) { | 662 | if (lad || lp) { |
654 | x = (int) lp; | 663 | x = (int) lp; |
655 | /* try a few times for the local bind, a la ftp-data-port... */ | 664 | /* try a few times for the local bind, a la ftp-data-port... */ |
656 | for (y = 4; y > 0; y--) { | 665 | for (y = 4; y > 0; y--) { |
657 | rr = bind (nnetfd, (SA *)lclend, sizeof (SA)); | 666 | rr = bind(nnetfd, (SA *) lclend, sizeof(SA)); |
658 | if (rr == 0) | 667 | if (rr == 0) |
659 | break; | 668 | break; |
660 | if (errno != EADDRINUSE) | 669 | if (errno != EADDRINUSE) |
661 | break; | 670 | break; |
662 | else { | 671 | else { |
663 | holler ("retrying local %s:%d", inet_ntoa (lclend->sin_addr), lp); | 672 | holler("retrying local %s:%d", inet_ntoa(lclend->sin_addr), lp); |
664 | sleep (2); | 673 | sleep(2); |
665 | errno = 0; /* clear from sleep */ | 674 | errno = 0; /* clear from sleep */ |
666 | } /* if EADDRINUSE */ | 675 | } /* if EADDRINUSE */ |
667 | } /* for y counter */ | 676 | } /* for y counter */ |
668 | } /* if lad or lp */ | 677 | } /* if lad or lp */ |
669 | if (rr) | 678 | if (rr) |
670 | bail ("Can't grab %s:%d with bind", | 679 | bail("Can't grab %s:%d with bind", |
671 | inet_ntoa(lclend->sin_addr), lp); | 680 | inet_ntoa(lclend->sin_addr), lp); |
672 | 681 | ||
673 | if (o_listen) | 682 | if (o_listen) |
674 | return (nnetfd); /* thanks, that's all for today */ | 683 | return (nnetfd);/* thanks, that's all for today */ |
675 | 684 | ||
676 | memcpy (&remend->sin_addr.s_addr, rad, sizeof (IA)); | 685 | memcpy(&remend->sin_addr.s_addr, rad, sizeof(IA)); |
677 | remend->sin_port = htons (rp); | 686 | remend->sin_port = htons(rp); |
678 | 687 | ||
679 | /* rough format of LSRR option and explanation of weirdness. | 688 | /* rough format of LSRR option and explanation of weirdness. |
680 | Option comes after IP-hdr dest addr in packet, padded to *4, and ihl > 5. | 689 | Option comes after IP-hdr dest addr in packet, padded to *4, and ihl > 5. |
@@ -713,84 +722,85 @@ Linux is also still a loss at 1.3.x it looks like; the lsrr code is { }... | |||
713 | /* if any -g arguments were given, set up source-routing. We hit this after | 722 | /* if any -g arguments were given, set up source-routing. We hit this after |
714 | the gates are all looked up and ready to rock, any -G pointer is set, | 723 | the gates are all looked up and ready to rock, any -G pointer is set, |
715 | and gatesidx is now the *number* of hops */ | 724 | and gatesidx is now the *number* of hops */ |
716 | if (gatesidx) { /* if we wanted any srcrt hops ... */ | 725 | if (gatesidx) { /* if we wanted any srcrt hops ... */ |
717 | /* don't even bother compiling if we can't do IP options here! */ | 726 | /* don't even bother compiling if we can't do IP options here! */ |
718 | #ifdef IP_OPTIONS | 727 | #ifdef IP_OPTIONS |
719 | if (! optbuf) { /* and don't already *have* a srcrt set */ | 728 | if (!optbuf) { /* and don't already *have* a srcrt set */ |
720 | char * opp; /* then do all this setup hair */ | 729 | char *opp; /* then do all this setup hair */ |
721 | optbuf = Hmalloc (48); | 730 | optbuf = Hmalloc(48); |
722 | opp = optbuf; | 731 | opp = optbuf; |
723 | *opp++ = IPOPT_LSRR; /* option */ | 732 | *opp++ = IPOPT_LSRR; /* option */ |
724 | *opp++ = (char) | 733 | *opp++ = (char) |
725 | (((gatesidx + 1) * sizeof (IA)) + 3) & 0xff; /* length */ | 734 | (((gatesidx + 1) * sizeof(IA)) + 3) & 0xff; /* length */ |
726 | *opp++ = gatesptr; /* pointer */ | 735 | *opp++ = gatesptr; /* pointer */ |
727 | /* opp now points at first hop addr -- insert the intermediate gateways */ | 736 | /* opp now points at first hop addr -- insert the intermediate gateways */ |
728 | for ( x = 0; x < gatesidx; x++) { | 737 | for (x = 0; x < gatesidx; x++) { |
729 | memcpy (opp, gates[x]->iaddrs, sizeof (IA)); | 738 | memcpy(opp, gates[x]->iaddrs, sizeof(IA)); |
730 | opp += sizeof (IA); | 739 | opp += sizeof(IA); |
731 | } | 740 | } |
732 | /* and tack the final destination on the end [needed!] */ | 741 | /* and tack the final destination on the end [needed!] */ |
733 | memcpy (opp, rad, sizeof (IA)); | 742 | memcpy(opp, rad, sizeof(IA)); |
734 | opp += sizeof (IA); | 743 | opp += sizeof(IA); |
735 | *opp = IPOPT_NOP; /* alignment filler */ | 744 | *opp = IPOPT_NOP; /* alignment filler */ |
736 | } /* if empty optbuf */ | 745 | } /* if empty optbuf */ |
737 | /* calculate length of whole option mess, which is (3 + [hops] + [final] + 1), | 746 | /* calculate length of whole option mess, which is (3 + [hops] |
738 | and apply it [have to do this every time through, of course] */ | 747 | * + [final] + 1), and apply it [have to do this every time |
739 | x = ((gatesidx + 1) * sizeof (IA)) + 4; | 748 | * through, of course] */ |
740 | rr = setsockopt (nnetfd, IPPROTO_IP, IP_OPTIONS, optbuf, x); | 749 | x = ((gatesidx + 1) * sizeof(IA)) + 4; |
741 | if (rr == -1) | 750 | rr = setsockopt(nnetfd, IPPROTO_IP, IP_OPTIONS, optbuf, x); |
742 | bail ("srcrt setsockopt fuxored"); | 751 | if (rr == -1) |
743 | #else /* IP_OPTIONS */ | 752 | bail("srcrt setsockopt fuxored"); |
744 | holler ("Warning: source routing unavailable on this machine, ignoring"); | 753 | #else /* IP_OPTIONS */ |
745 | #endif /* IP_OPTIONS*/ | 754 | holler("Warning: source routing unavailable on this machine, ignoring"); |
746 | } /* if gatesidx */ | 755 | #endif /* IP_OPTIONS */ |
747 | 756 | } /* if gatesidx */ | |
748 | /* wrap connect inside a timer, and hit it */ | 757 | /* wrap connect inside a timer, and hit it */ |
749 | arm (1, o_wait); | 758 | arm(1, o_wait); |
750 | if (setjmp (jbuf) == 0) { | 759 | if (setjmp(jbuf) == 0) { |
751 | rr = connect (nnetfd, (SA *)remend, sizeof (SA)); | 760 | rr = connect(nnetfd, (SA *) remend, sizeof(SA)); |
752 | } else { /* setjmp: connect failed... */ | 761 | } else { /* setjmp: connect failed... */ |
753 | rr = -1; | 762 | rr = -1; |
754 | errno = ETIMEDOUT; /* fake it */ | 763 | errno = ETIMEDOUT; /* fake it */ |
755 | } | 764 | } |
756 | arm (0, 0); | 765 | arm(0, 0); |
757 | if (rr == 0) | 766 | if (rr == 0) |
758 | return (nnetfd); | 767 | return (nnetfd); |
759 | close (nnetfd); /* clean up junked socket FD!! */ | 768 | close(nnetfd); /* clean up junked socket FD!! */ |
760 | return (-1); | 769 | return (-1); |
761 | } /* doconnect */ | 770 | } /* doconnect */ |
762 | 771 | ||
763 | /* dolisten : | 772 | /* dolisten : |
764 | just like doconnect, and in fact calls a hunk of doconnect, but listens for | 773 | just like doconnect, and in fact calls a hunk of doconnect, but listens for |
765 | incoming and returns an open connection *from* someplace. If we were | 774 | incoming and returns an open connection *from* someplace. If we were |
766 | given host/port args, any connections from elsewhere are rejected. This | 775 | given host/port args, any connections from elsewhere are rejected. This |
767 | in conjunction with local-address binding should limit things nicely... */ | 776 | in conjunction with local-address binding should limit things nicely... */ |
768 | int dolisten (rad, rp, lad, lp) | 777 | int |
769 | IA * rad; | 778 | dolisten(rad, rp, lad, lp) |
770 | USHORT rp; | 779 | IA *rad; |
771 | IA * lad; | 780 | USHORT rp; |
772 | USHORT lp; | 781 | IA *lad; |
782 | USHORT lp; | ||
773 | { | 783 | { |
774 | register int nnetfd; | 784 | register int nnetfd; |
775 | register int rr; | 785 | register int rr; |
776 | HINF * whozis = NULL; | 786 | HINF *whozis = NULL; |
777 | int x; | 787 | int x; |
778 | char * cp; | 788 | char *cp; |
779 | USHORT z; | 789 | USHORT z; |
780 | errno = 0; | 790 | errno = 0; |
781 | 791 | ||
782 | /* Pass everything off to doconnect, who in o_listen mode just gets a socket */ | 792 | /* Pass everything off to doconnect, who in o_listen mode just gets a socket */ |
783 | nnetfd = doconnect (rad, rp, lad, lp); | 793 | nnetfd = doconnect(rad, rp, lad, lp); |
784 | if (nnetfd <= 0) | 794 | if (nnetfd <= 0) |
785 | return (-1); | 795 | return (-1); |
786 | if (o_udpmode) { /* apparently UDP can listen ON */ | 796 | if (o_udpmode) { /* apparently UDP can listen ON */ |
787 | if (! lp) /* "port 0", but that's not useful */ | 797 | if (!lp) /* "port 0", but that's not useful */ |
788 | bail ("UDP listen needs -p arg"); | 798 | bail("UDP listen needs -p arg"); |
789 | } else { | 799 | } else { |
790 | rr = listen (nnetfd, 1); /* gotta listen() before we can get */ | 800 | rr = listen(nnetfd, 1); /* gotta listen() before we can get */ |
791 | if (rr < 0) /* our local random port. sheesh. */ | 801 | if (rr < 0) /* our local random port. sheesh. */ |
792 | bail ("local listen fuxored"); | 802 | bail("local listen fuxored"); |
793 | } | 803 | } |
794 | 804 | ||
795 | /* Various things that follow temporarily trash bigbuf_net, which might contain | 805 | /* Various things that follow temporarily trash bigbuf_net, which might contain |
796 | a copy of any recvfrom()ed packet, but we'll read() another copy later. */ | 806 | a copy of any recvfrom()ed packet, but we'll read() another copy later. */ |
@@ -801,36 +811,37 @@ int dolisten (rad, rp, lad, lp) | |||
801 | said -p we *know* what port we're listening on. At any rate we won't bother | 811 | said -p we *know* what port we're listening on. At any rate we won't bother |
802 | with it all unless we wanted to see it, although listening quietly on a | 812 | with it all unless we wanted to see it, although listening quietly on a |
803 | random unknown port is probably not very useful without "netstat". */ | 813 | random unknown port is probably not very useful without "netstat". */ |
804 | if (o_verbose) { | 814 | if (o_verbose) { |
805 | x = sizeof (SA); /* how 'bout getsockNUM instead, pinheads?! */ | 815 | x = sizeof(SA); /* how 'bout getsockNUM instead, pinheads?! */ |
806 | rr = getsockname (nnetfd, (SA *) lclend, &x); | 816 | rr = getsockname(nnetfd, (SA *) lclend, &x); |
807 | if (rr < 0) | 817 | if (rr < 0) |
808 | holler ("local getsockname failed"); | 818 | holler("local getsockname failed"); |
809 | strcpy (bigbuf_net, "listening on ["); /* buffer reuse... */ | 819 | strcpy(bigbuf_net, "listening on ["); /* buffer reuse... */ |
810 | if (lclend->sin_addr.s_addr) | 820 | if (lclend->sin_addr.s_addr) |
811 | strcat (bigbuf_net, inet_ntoa (lclend->sin_addr)); | 821 | strcat(bigbuf_net, inet_ntoa(lclend->sin_addr)); |
812 | else | 822 | else |
813 | strcat (bigbuf_net, "any"); | 823 | strcat(bigbuf_net, "any"); |
814 | strcat (bigbuf_net, "] %d ..."); | 824 | strcat(bigbuf_net, "] %d ..."); |
815 | z = ntohs (lclend->sin_port); | 825 | z = ntohs(lclend->sin_port); |
816 | holler (bigbuf_net, z); | 826 | holler(bigbuf_net, z); |
817 | } /* verbose -- whew!! */ | 827 | } /* verbose -- whew!! */ |
818 | 828 | /* UDP is a speeeeecial case -- we have to do I/O *and* get the | |
819 | /* UDP is a speeeeecial case -- we have to do I/O *and* get the calling | 829 | * calling party's particulars all at once, listen() and accept() |
820 | party's particulars all at once, listen() and accept() don't apply. | 830 | * don't apply. At least in the BSD universe, however, recvfrom/PEEK |
821 | At least in the BSD universe, however, recvfrom/PEEK is enough to tell | 831 | * is enough to tell us something came in, and we can set things up so |
822 | us something came in, and we can set things up so straight read/write | 832 | * straight read/write actually does work after all. Yow. YMMV on |
823 | actually does work after all. Yow. YMMV on strange platforms! */ | 833 | * strange platforms! */ |
824 | if (o_udpmode) { | 834 | if (o_udpmode) { |
825 | x = sizeof (SA); /* retval for recvfrom */ | 835 | x = sizeof(SA); /* retval for recvfrom */ |
826 | arm (2, o_wait); /* might as well timeout this, too */ | 836 | arm(2, o_wait); /* might as well timeout this, too */ |
827 | if (setjmp (jbuf) == 0) { /* do timeout for initial connect */ | 837 | if (setjmp(jbuf) == 0) { /* do timeout for initial |
828 | rr = recvfrom /* and here we block... */ | 838 | * connect */ |
829 | (nnetfd, bigbuf_net, BIGSIZ, MSG_PEEK, (SA *) remend, &x); | 839 | rr = recvfrom /* and here we block... */ |
830 | Debug (("dolisten/recvfrom ding, rr = %d, netbuf %s ", rr, bigbuf_net)) | 840 | (nnetfd, bigbuf_net, BIGSIZ, MSG_PEEK, (SA *) remend, &x); |
831 | } else | 841 | Debug(("dolisten/recvfrom ding, rr = %d, netbuf %s ", rr, bigbuf_net)) |
832 | goto dol_tmo; /* timeout */ | 842 | } else |
833 | arm (0, 0); | 843 | goto dol_tmo; /* timeout */ |
844 | arm(0, 0); | ||
834 | /* I'm not completely clear on how this works -- BSD seems to make UDP | 845 | /* I'm not completely clear on how this works -- BSD seems to make UDP |
835 | just magically work in a connect()ed context, but we'll undoubtedly run | 846 | just magically work in a connect()ed context, but we'll undoubtedly run |
836 | into systems this deal doesn't work on. For now, we apparently have to | 847 | into systems this deal doesn't work on. For now, we apparently have to |
@@ -842,24 +853,23 @@ Debug (("dolisten/recvfrom ding, rr = %d, netbuf %s ", rr, bigbuf_net)) | |||
842 | different port on the other end won't show up and will cause ICMP errors. | 853 | different port on the other end won't show up and will cause ICMP errors. |
843 | I guess that's what they meant by "connect". | 854 | I guess that's what they meant by "connect". |
844 | Let's try to remember what the "U" is *really* for, eh? */ | 855 | Let's try to remember what the "U" is *really* for, eh? */ |
845 | rr = connect (nnetfd, (SA *)remend, sizeof (SA)); | 856 | rr = connect(nnetfd, (SA *) remend, sizeof(SA)); |
846 | goto whoisit; | 857 | goto whoisit; |
847 | } /* o_udpmode */ | 858 | } /* o_udpmode */ |
848 | 859 | /* fall here for TCP */ | |
849 | /* fall here for TCP */ | 860 | x = sizeof(SA); /* retval for accept */ |
850 | x = sizeof (SA); /* retval for accept */ | 861 | arm(2, o_wait); /* wrap this in a timer, too; 0 = forever */ |
851 | arm (2, o_wait); /* wrap this in a timer, too; 0 = forever */ | 862 | if (setjmp(jbuf) == 0) { |
852 | if (setjmp (jbuf) == 0) { | 863 | rr = accept(nnetfd, (SA *) remend, &x); |
853 | rr = accept (nnetfd, (SA *)remend, &x); | 864 | } else |
854 | } else | 865 | goto dol_tmo; /* timeout */ |
855 | goto dol_tmo; /* timeout */ | 866 | arm(0, 0); |
856 | arm (0, 0); | 867 | close(nnetfd); /* dump the old socket */ |
857 | close (nnetfd); /* dump the old socket */ | 868 | nnetfd = rr; /* here's our new one */ |
858 | nnetfd = rr; /* here's our new one */ | ||
859 | 869 | ||
860 | whoisit: | 870 | whoisit: |
861 | if (rr < 0) | 871 | if (rr < 0) |
862 | goto dol_err; /* bail out if any errors so far */ | 872 | goto dol_err; /* bail out if any errors so far */ |
863 | 873 | ||
864 | /* If we can, look for any IP options. Useful for testing the receiving end of | 874 | /* If we can, look for any IP options. Useful for testing the receiving end of |
865 | such things, and is a good exercise in dealing with it. We do this before | 875 | such things, and is a good exercise in dealing with it. We do this before |
@@ -867,41 +877,44 @@ whoisit: | |||
867 | thing to emerge after all the intervening crud. Doesn't work for UDP on | 877 | thing to emerge after all the intervening crud. Doesn't work for UDP on |
868 | any machines I've tested, but feel free to surprise me. */ | 878 | any machines I've tested, but feel free to surprise me. */ |
869 | #ifdef IP_OPTIONS | 879 | #ifdef IP_OPTIONS |
870 | if (! o_verbose) /* if we wont see it, we dont care */ | 880 | if (!o_verbose) /* if we wont see it, we dont care */ |
871 | goto dol_noop; | 881 | goto dol_noop; |
872 | optbuf = Hmalloc (40); | 882 | optbuf = Hmalloc(40); |
873 | x = 40; | 883 | x = 40; |
874 | rr = getsockopt (nnetfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); | 884 | rr = getsockopt(nnetfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); |
875 | if (rr < 0) | 885 | if (rr < 0) |
876 | holler ("getsockopt failed"); | 886 | holler("getsockopt failed"); |
877 | Debug (("ipoptions ret len %d", x)) | 887 | Debug(("ipoptions ret len %d", x)) |
878 | if (x) { /* we've got options, lessee em... */ | 888 | if (x) { /* we've got options, lessee em... */ |
879 | unsigned char * q = (unsigned char *) optbuf; | 889 | unsigned char *q = (unsigned char *) optbuf; |
880 | char * p = bigbuf_net; /* local variables, yuk! */ | 890 | char *p = bigbuf_net; /* local variables, yuk! */ |
881 | char * pp = &bigbuf_net[128]; /* get random space farther out... */ | 891 | char *pp = &bigbuf_net[128]; /* get random space farther |
882 | memset (bigbuf_net, 0, 256); /* clear it all first */ | 892 | * out... */ |
883 | while (x > 0) { | 893 | memset(bigbuf_net, 0, 256); /* clear it all first */ |
884 | sprintf (pp, "%2.2x ", *q); /* clumsy, but works: turn into hex */ | 894 | while (x > 0) { |
885 | strcat (p, pp); /* and build the final string */ | 895 | sprintf(pp, "%2.2x ", *q); /* clumsy, but works: |
886 | q++; p++; | 896 | * turn into hex */ |
887 | x--; | 897 | strcat(p, pp); /* and build the final string */ |
888 | } | 898 | q++; |
889 | holler ("IP options: %s", bigbuf_net); | 899 | p++; |
890 | } /* if x, i.e. any options */ | 900 | x--; |
901 | } | ||
902 | holler("IP options: %s", bigbuf_net); | ||
903 | } /* if x, i.e. any options */ | ||
891 | dol_noop: | 904 | dol_noop: |
892 | #endif /* IP_OPTIONS */ | 905 | #endif /* IP_OPTIONS */ |
893 | 906 | ||
894 | /* find out what address the connection was *to* on our end, in case we're | 907 | /* find out what address the connection was *to* on our end, in case we're |
895 | doing a listen-on-any on a multihomed machine. This allows one to | 908 | doing a listen-on-any on a multihomed machine. This allows one to |
896 | offer different services via different alias addresses, such as the | 909 | offer different services via different alias addresses, such as the |
897 | "virtual web site" hack. */ | 910 | "virtual web site" hack. */ |
898 | memset (bigbuf_net, 0, 64); | 911 | memset(bigbuf_net, 0, 64); |
899 | cp = &bigbuf_net[32]; | 912 | cp = &bigbuf_net[32]; |
900 | x = sizeof (SA); | 913 | x = sizeof(SA); |
901 | rr = getsockname (nnetfd, (SA *) lclend, &x); | 914 | rr = getsockname(nnetfd, (SA *) lclend, &x); |
902 | if (rr < 0) | 915 | if (rr < 0) |
903 | holler ("post-rcv getsockname failed"); | 916 | holler("post-rcv getsockname failed"); |
904 | strcpy (cp, inet_ntoa (lclend->sin_addr)); | 917 | strcpy(cp, inet_ntoa(lclend->sin_addr)); |
905 | 918 | ||
906 | /* now check out who it is. We don't care about mismatched DNS names here, | 919 | /* now check out who it is. We don't care about mismatched DNS names here, |
907 | but any ADDR and PORT we specified had better fucking well match the caller. | 920 | but any ADDR and PORT we specified had better fucking well match the caller. |
@@ -912,30 +925,31 @@ dol_noop: | |||
912 | connections *from* specific hosts/ports, instead of requiring the caller to | 925 | connections *from* specific hosts/ports, instead of requiring the caller to |
913 | accept the connection and then reject undesireable ones by closing. In | 926 | accept the connection and then reject undesireable ones by closing. In |
914 | other words, we need a TCP MSG_PEEK. */ | 927 | other words, we need a TCP MSG_PEEK. */ |
915 | z = ntohs (remend->sin_port); | 928 | z = ntohs(remend->sin_port); |
916 | strcpy (bigbuf_net, inet_ntoa (remend->sin_addr)); | 929 | strcpy(bigbuf_net, inet_ntoa(remend->sin_addr)); |
917 | whozis = gethostpoop (bigbuf_net, o_nflag); | 930 | whozis = gethostpoop(bigbuf_net, o_nflag); |
918 | errno = 0; | 931 | errno = 0; |
919 | x = 0; /* use as a flag... */ | 932 | x = 0; /* use as a flag... */ |
920 | if (rad) /* xxx: fix to go down the *list* if we have one? */ | 933 | if (rad) /* xxx: fix to go down the *list* if we have |
921 | if (memcmp (rad, whozis->iaddrs, sizeof (SA))) | 934 | * one? */ |
922 | x = 1; | 935 | if (memcmp(rad, whozis->iaddrs, sizeof(SA))) |
923 | if (rp) | 936 | x = 1; |
924 | if (z != rp) | 937 | if (rp) |
925 | x = 1; | 938 | if (z != rp) |
926 | if (x) /* guilty! */ | 939 | x = 1; |
927 | bail ("invalid connection to [%s] from %s [%s] %d", | 940 | if (x) /* guilty! */ |
928 | cp, whozis->name, whozis->addrs[0], z); | 941 | bail("invalid connection to [%s] from %s [%s] %d", |
929 | holler ("connect to [%s] from %s [%s] %d", /* oh, you're okay.. */ | 942 | cp, whozis->name, whozis->addrs[0], z); |
930 | cp, whozis->name, whozis->addrs[0], z); | 943 | holler("connect to [%s] from %s [%s] %d", /* oh, you're okay.. */ |
931 | return (nnetfd); /* open! */ | 944 | cp, whozis->name, whozis->addrs[0], z); |
945 | return (nnetfd); /* open! */ | ||
932 | 946 | ||
933 | dol_tmo: | 947 | dol_tmo: |
934 | errno = ETIMEDOUT; /* fake it */ | 948 | errno = ETIMEDOUT; /* fake it */ |
935 | dol_err: | 949 | dol_err: |
936 | close (nnetfd); | 950 | close(nnetfd); |
937 | return (-1); | 951 | return (-1); |
938 | } /* dolisten */ | 952 | } /* dolisten */ |
939 | 953 | ||
940 | /* udptest : | 954 | /* udptest : |
941 | fire a couple of packets at a UDP target port, just to see if it's really | 955 | fire a couple of packets at a UDP target port, just to see if it's really |
@@ -947,39 +961,38 @@ dol_err: | |||
947 | Use the time delay between writes if given, otherwise use the "tcp ping" | 961 | Use the time delay between writes if given, otherwise use the "tcp ping" |
948 | trick for getting the RTT. [I got that idea from pluvius, and warped it.] | 962 | trick for getting the RTT. [I got that idea from pluvius, and warped it.] |
949 | Return either the original fd, or clean up and return -1. */ | 963 | Return either the original fd, or clean up and return -1. */ |
950 | udptest (fd, where) | 964 | udptest(fd, where) |
951 | int fd; | 965 | int fd; |
952 | IA * where; | 966 | IA *where; |
953 | { | 967 | { |
954 | register int rr; | 968 | register int rr; |
955 | 969 | ||
956 | rr = write (fd, bigbuf_in, 1); | 970 | rr = write(fd, bigbuf_in, 1); |
957 | if (rr != 1) | 971 | if (rr != 1) |
958 | holler ("udptest first write failed?! errno %d", errno); | 972 | holler("udptest first write failed?! errno %d", errno); |
959 | if (o_wait) | 973 | if (o_wait) |
960 | sleep (o_wait); | 974 | sleep(o_wait); |
961 | else { | 975 | else { |
962 | /* use the tcp-ping trick: try connecting to a normally refused port, which | 976 | /* use the tcp-ping trick: try connecting to a normally refused port, which |
963 | causes us to block for the time that SYN gets there and RST gets back. | 977 | causes us to block for the time that SYN gets there and RST gets back. |
964 | Not completely reliable, but it *does* mostly work. */ | 978 | Not completely reliable, but it *does* mostly work. */ |
965 | o_udpmode = 0; /* so doconnect does TCP this time */ | 979 | o_udpmode = 0; /* so doconnect does TCP this time */ |
966 | /* Set a temporary connect timeout, so packet filtration doesnt cause | 980 | /* Set a temporary connect timeout, so packet filtration doesnt cause |
967 | us to hang forever, and hit it */ | 981 | us to hang forever, and hit it */ |
968 | o_wait = 5; /* enough that we'll notice?? */ | 982 | o_wait = 5; /* enough that we'll notice?? */ |
969 | rr = doconnect (where, SLEAZE_PORT, 0, 0); | 983 | rr = doconnect(where, SLEAZE_PORT, 0, 0); |
970 | if (rr > 0) | 984 | if (rr > 0) |
971 | close (rr); /* in case it *did* open */ | 985 | close(rr); /* in case it *did* open */ |
972 | o_wait = 0; /* reset it */ | 986 | o_wait = 0; /* reset it */ |
973 | o_udpmode++; /* we *are* still doing UDP, right? */ | 987 | o_udpmode++; /* we *are* still doing UDP, right? */ |
974 | } /* if o_wait */ | 988 | } /* if o_wait */ |
975 | errno = 0; /* clear from sleep */ | 989 | errno = 0; /* clear from sleep */ |
976 | rr = write (fd, bigbuf_in, 1); | 990 | rr = write(fd, bigbuf_in, 1); |
977 | if (rr == 1) /* if write error, no UDP listener */ | 991 | if (rr == 1) /* if write error, no UDP listener */ |
978 | return (fd); | 992 | return (fd); |
979 | close (fd); /* use it or lose it! */ | 993 | close(fd); /* use it or lose it! */ |
980 | return (-1); | 994 | return (-1); |
981 | } /* udptest */ | 995 | } /* udptest */ |
982 | |||
983 | /* oprint : | 996 | /* oprint : |
984 | Hexdump bytes shoveled either way to a running logfile, in the format: | 997 | Hexdump bytes shoveled either way to a running logfile, in the format: |
985 | D offset - - - - --- 16 bytes --- - - - - # .... ascii ..... | 998 | D offset - - - - --- 16 bytes --- - - - - # .... ascii ..... |
@@ -990,650 +1003,686 @@ D offset - - - - --- 16 bytes --- - - - - # .... ascii ..... | |||
990 | a partial line, so be it; we *want* that lockstep indication of who sent | 1003 | a partial line, so be it; we *want* that lockstep indication of who sent |
991 | what when. Adapted from dgaudet's original example -- but must be ripping | 1004 | what when. Adapted from dgaudet's original example -- but must be ripping |
992 | *fast*, since we don't want to be too disk-bound... */ | 1005 | *fast*, since we don't want to be too disk-bound... */ |
993 | void oprint (which, buf, n) | 1006 | void |
994 | int which; | 1007 | oprint(which, buf, n) |
995 | char * buf; | 1008 | int which; |
996 | int n; | 1009 | char *buf; |
1010 | int n; | ||
997 | { | 1011 | { |
998 | int bc; /* in buffer count */ | 1012 | int bc; /* in buffer count */ |
999 | int obc; /* current "global" offset */ | 1013 | int obc; /* current "global" offset */ |
1000 | int soc; /* stage write count */ | 1014 | int soc; /* stage write count */ |
1001 | register unsigned char * p; /* main buf ptr; m.b. unsigned here */ | 1015 | register unsigned char *p; /* main buf ptr; m.b. unsigned here */ |
1002 | register unsigned char * op; /* out hexdump ptr */ | 1016 | register unsigned char *op; /* out hexdump ptr */ |
1003 | register unsigned char * a; /* out asc-dump ptr */ | 1017 | register unsigned char *a; /* out asc-dump ptr */ |
1004 | register int x; | 1018 | register int x; |
1005 | register unsigned int y; | 1019 | register unsigned int y; |
1006 | 1020 | ||
1007 | if (! ofd) | 1021 | if (!ofd) |
1008 | bail ("oprint called with no open fd?!"); | 1022 | bail("oprint called with no open fd?!"); |
1009 | if (n == 0) | 1023 | if (n == 0) |
1010 | return; | 1024 | return; |
1011 | 1025 | ||
1012 | op = stage; | 1026 | op = stage; |
1013 | if (which) { | 1027 | if (which) { |
1014 | *op = '<'; | 1028 | *op = '<'; |
1015 | obc = wrote_out; /* use the globals! */ | 1029 | obc = wrote_out;/* use the globals! */ |
1016 | } else { | 1030 | } else { |
1017 | *op = '>'; | 1031 | *op = '>'; |
1018 | obc = wrote_net; | 1032 | obc = wrote_net; |
1019 | } | 1033 | } |
1020 | op++; /* preload "direction" */ | 1034 | op++; /* preload "direction" */ |
1021 | *op = ' '; | 1035 | *op = ' '; |
1022 | p = (unsigned char *) buf; | 1036 | p = (unsigned char *) buf; |
1023 | bc = n; | 1037 | bc = n; |
1024 | stage[59] = '#'; /* preload separator */ | 1038 | stage[59] = '#'; /* preload separator */ |
1025 | stage[60] = ' '; | 1039 | stage[60] = ' '; |
1026 | 1040 | ||
1027 | while (bc) { /* for chunk-o-data ... */ | 1041 | while (bc) { /* for chunk-o-data ... */ |
1028 | x = 16; | 1042 | x = 16; |
1029 | soc = 78; /* len of whole formatted line */ | 1043 | soc = 78; /* len of whole formatted line */ |
1030 | if (bc < x) { | 1044 | if (bc < x) { |
1031 | soc = soc - 16 + bc; /* fiddle for however much is left */ | 1045 | soc = soc - 16 + bc; /* fiddle for however much is |
1032 | x = (bc * 3) + 11; /* 2 digits + space per, after D & offset */ | 1046 | * left */ |
1033 | op = &stage[x]; | 1047 | x = (bc * 3) + 11; /* 2 digits + space per, after |
1034 | x = 16 - bc; | 1048 | * D & offset */ |
1035 | while (x) { | 1049 | op = &stage[x]; |
1036 | *op++ = ' '; /* preload filler spaces */ | 1050 | x = 16 - bc; |
1037 | *op++ = ' '; | 1051 | while (x) { |
1038 | *op++ = ' '; | 1052 | *op++ = ' '; /* preload filler spaces */ |
1039 | x--; | 1053 | *op++ = ' '; |
1040 | } | 1054 | *op++ = ' '; |
1041 | x = bc; /* re-fix current linecount */ | 1055 | x--; |
1042 | } /* if bc < x */ | 1056 | } |
1043 | 1057 | x = bc; /* re-fix current linecount */ | |
1044 | bc -= x; /* fix wrt current line size */ | 1058 | } /* if bc < x */ |
1045 | sprintf (&stage[2], "%8.8x ", obc); /* xxx: still slow? */ | 1059 | bc -= x; /* fix wrt current line size */ |
1046 | obc += x; /* fix current offset */ | 1060 | sprintf(&stage[2], "%8.8x ", obc); /* xxx: still slow? */ |
1047 | op = &stage[11]; /* where hex starts */ | 1061 | obc += x; /* fix current offset */ |
1048 | a = &stage[61]; /* where ascii starts */ | 1062 | op = &stage[11];/* where hex starts */ |
1049 | 1063 | a = &stage[61]; /* where ascii starts */ | |
1050 | while (x) { /* for line of dump, however long ... */ | 1064 | |
1051 | y = (int)(*p >> 4); /* hi half */ | 1065 | while (x) { /* for line of dump, however long ... */ |
1052 | *op = hexnibs[y]; | 1066 | y = (int) (*p >> 4); /* hi half */ |
1053 | op++; | 1067 | *op = hexnibs[y]; |
1054 | y = (int)(*p & 0x0f); /* lo half */ | 1068 | op++; |
1055 | *op = hexnibs[y]; | 1069 | y = (int) (*p & 0x0f); /* lo half */ |
1056 | op++; | 1070 | *op = hexnibs[y]; |
1057 | *op = ' '; | 1071 | op++; |
1058 | op++; | 1072 | *op = ' '; |
1059 | if ((*p > 31) && (*p < 127)) | 1073 | op++; |
1060 | *a = *p; /* printing */ | 1074 | if ((*p > 31) && (*p < 127)) |
1061 | else | 1075 | *a = *p; /* printing */ |
1062 | *a = '.'; /* nonprinting, loose def */ | 1076 | else |
1063 | a++; | 1077 | *a = '.'; /* nonprinting, loose def */ |
1064 | p++; | 1078 | a++; |
1065 | x--; | 1079 | p++; |
1066 | } /* while x */ | 1080 | x--; |
1067 | *a = '\n'; /* finish the line */ | 1081 | } /* while x */ |
1068 | x = write (ofd, stage, soc); | 1082 | *a = '\n'; /* finish the line */ |
1069 | if (x < 0) | 1083 | x = write(ofd, stage, soc); |
1070 | bail ("ofd write err"); | 1084 | if (x < 0) |
1071 | } /* while bc */ | 1085 | bail("ofd write err"); |
1072 | } /* oprint */ | 1086 | } /* while bc */ |
1073 | 1087 | } /* oprint */ | |
1074 | #ifdef TELNET | 1088 | #ifdef TELNET |
1075 | USHORT o_tn = 0; /* global -t option */ | 1089 | USHORT o_tn = 0; /* global -t option */ |
1076 | 1090 | ||
1077 | /* atelnet : | 1091 | /* atelnet : |
1078 | Answer anything that looks like telnet negotiation with don't/won't. | 1092 | Answer anything that looks like telnet negotiation with don't/won't. |
1079 | This doesn't modify any data buffers, update the global output count, | 1093 | This doesn't modify any data buffers, update the global output count, |
1080 | or show up in a hexdump -- it just shits into the outgoing stream. | 1094 | or show up in a hexdump -- it just shits into the outgoing stream. |
1081 | Idea and codebase from Mudge@l0pht.com. */ | 1095 | Idea and codebase from Mudge@l0pht.com. */ |
1082 | void atelnet (buf, size) | 1096 | void |
1083 | unsigned char * buf; /* has to be unsigned here! */ | 1097 | atelnet(buf, size) |
1084 | unsigned int size; | 1098 | unsigned char *buf; /* has to be unsigned here! */ |
1099 | unsigned int size; | ||
1085 | { | 1100 | { |
1086 | static unsigned char obuf [4]; /* tiny thing to build responses into */ | 1101 | static unsigned char obuf[4]; /* tiny thing to build responses into */ |
1087 | register int x; | 1102 | register int x; |
1088 | register unsigned char y; | 1103 | register unsigned char y; |
1089 | register unsigned char * p; | 1104 | register unsigned char *p; |
1090 | 1105 | ||
1091 | y = 0; | 1106 | y = 0; |
1092 | p = buf; | 1107 | p = buf; |
1093 | x = size; | 1108 | x = size; |
1094 | while (x > 0) { | 1109 | while (x > 0) { |
1095 | if (*p != 255) /* IAC? */ | 1110 | if (*p != 255) /* IAC? */ |
1096 | goto notiac; | 1111 | goto notiac; |
1097 | obuf[0] = 255; | 1112 | obuf[0] = 255; |
1098 | p++; x--; | 1113 | p++; |
1099 | if ((*p == 251) || (*p == 252)) /* WILL or WONT */ | 1114 | x--; |
1100 | y = 254; /* -> DONT */ | 1115 | if ((*p == 251) || (*p == 252)) /* WILL or WONT */ |
1101 | if ((*p == 253) || (*p == 254)) /* DO or DONT */ | 1116 | y = 254;/* -> DONT */ |
1102 | y = 252; /* -> WONT */ | 1117 | if ((*p == 253) || (*p == 254)) /* DO or DONT */ |
1103 | if (y) { | 1118 | y = 252;/* -> WONT */ |
1104 | obuf[1] = y; | 1119 | if (y) { |
1105 | p++; x--; | 1120 | obuf[1] = y; |
1106 | obuf[2] = *p; /* copy actual option byte */ | 1121 | p++; |
1107 | (void) write (netfd, obuf, 3); | 1122 | x--; |
1123 | obuf[2] = *p; /* copy actual option byte */ | ||
1124 | (void) write(netfd, obuf, 3); | ||
1108 | /* if one wanted to bump wrote_net or do a hexdump line, here's the place */ | 1125 | /* if one wanted to bump wrote_net or do a hexdump line, here's the place */ |
1109 | y = 0; | 1126 | y = 0; |
1110 | } /* if y */ | 1127 | } /* if y */ |
1111 | notiac: | 1128 | notiac: |
1112 | p++; x--; | 1129 | p++; |
1113 | } /* while x */ | 1130 | x--; |
1114 | } /* atelnet */ | 1131 | } /* while x */ |
1115 | #endif /* TELNET */ | 1132 | } /* atelnet */ |
1133 | #endif /* TELNET */ | ||
1116 | 1134 | ||
1117 | /* readwrite : | 1135 | /* readwrite : |
1118 | handle stdin/stdout/network I/O. Bwahaha!! -- the select loop from hell. | 1136 | handle stdin/stdout/network I/O. Bwahaha!! -- the select loop from hell. |
1119 | In this instance, return what might become our exit status. */ | 1137 | In this instance, return what might become our exit status. */ |
1120 | int readwrite (fd) | 1138 | int |
1121 | int fd; | 1139 | readwrite(fd) |
1140 | int fd; | ||
1122 | { | 1141 | { |
1123 | register int rr; | 1142 | register int rr; |
1124 | register char * zp; /* stdin buf ptr */ | 1143 | register char *zp; /* stdin buf ptr */ |
1125 | register char * np; /* net-in buf ptr */ | 1144 | register char *np; /* net-in buf ptr */ |
1126 | unsigned int rzleft; | 1145 | unsigned int rzleft; |
1127 | unsigned int rnleft; | 1146 | unsigned int rnleft; |
1128 | USHORT netretry; /* net-read retry counter */ | 1147 | USHORT netretry; /* net-read retry counter */ |
1129 | USHORT wretry; /* net-write sanity counter */ | 1148 | USHORT wretry; /* net-write sanity counter */ |
1130 | USHORT wfirst; /* one-shot flag to skip first net read */ | 1149 | USHORT wfirst; /* one-shot flag to skip first net read */ |
1131 | 1150 | ||
1132 | /* if you don't have all this FD_* macro hair in sys/types.h, you'll have to | 1151 | /* if you don't have all this FD_* macro hair in sys/types.h, you'll have to |
1133 | either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */ | 1152 | either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */ |
1134 | if (fd > FD_SETSIZE) { | 1153 | if (fd > FD_SETSIZE) { |
1135 | holler ("Preposterous fd value %d", fd); | 1154 | holler("Preposterous fd value %d", fd); |
1136 | return (1); | 1155 | return (1); |
1137 | } | 1156 | } |
1138 | FD_SET (fd, ding1); /* global: the net is open */ | 1157 | FD_SET(fd, ding1); /* global: the net is open */ |
1139 | netretry = 2; | 1158 | netretry = 2; |
1140 | wfirst = 0; | 1159 | wfirst = 0; |
1141 | rzleft = rnleft = 0; | 1160 | rzleft = rnleft = 0; |
1142 | if (insaved) { | 1161 | if (insaved) { |
1143 | rzleft = insaved; /* preload multi-mode fakeouts */ | 1162 | rzleft = insaved; /* preload multi-mode fakeouts */ |
1144 | zp = bigbuf_in; | 1163 | zp = bigbuf_in; |
1145 | wfirst = 1; | 1164 | wfirst = 1; |
1146 | if (Single) /* if not scanning, this is a one-off first */ | 1165 | if (Single) /* if not scanning, this is a one-off first */ |
1147 | insaved = 0; /* buffer left over from argv construction, */ | 1166 | insaved = 0; /* buffer left over from argv |
1148 | else { | 1167 | * construction, */ |
1149 | FD_CLR (0, ding1); /* OR we've already got our repeat chunk, */ | 1168 | else { |
1150 | close (0); /* so we won't need any more stdin */ | 1169 | FD_CLR(0, ding1); /* OR we've already got our |
1151 | } /* Single */ | 1170 | * repeat chunk, */ |
1152 | } /* insaved */ | 1171 | close(0); /* so we won't need any more stdin */ |
1153 | if (o_interval) | 1172 | } /* Single */ |
1154 | sleep (o_interval); /* pause *before* sending stuff, too */ | 1173 | } /* insaved */ |
1155 | errno = 0; /* clear from sleep, close, whatever */ | 1174 | if (o_interval) |
1175 | sleep(o_interval); /* pause *before* sending stuff, too */ | ||
1176 | errno = 0; /* clear from sleep, close, whatever */ | ||
1156 | 1177 | ||
1157 | /* and now the big ol' select shoveling loop ... */ | 1178 | /* and now the big ol' select shoveling loop ... */ |
1158 | while (FD_ISSET (fd, ding1)) { /* i.e. till the *net* closes! */ | 1179 | while (FD_ISSET(fd, ding1)) { /* i.e. till the *net* closes! */ |
1159 | wretry = 8200; /* more than we'll ever hafta write */ | 1180 | wretry = 8200; /* more than we'll ever hafta write */ |
1160 | if (wfirst) { /* any saved stdin buffer? */ | 1181 | if (wfirst) { /* any saved stdin buffer? */ |
1161 | wfirst = 0; /* clear flag for the duration */ | 1182 | wfirst = 0; /* clear flag for the duration */ |
1162 | goto shovel; /* and go handle it first */ | 1183 | goto shovel; /* and go handle it first */ |
1163 | } | 1184 | } |
1164 | *ding2 = *ding1; /* FD_COPY ain't portable... */ | 1185 | *ding2 = *ding1;/* FD_COPY ain't portable... */ |
1165 | /* some systems, notably linux, crap into their select timers on return, so | 1186 | /* some systems, notably linux, crap into their select timers on return, so |
1166 | we create a expendable copy and give *that* to select. *Fuck* me ... */ | 1187 | we create a expendable copy and give *that* to select. *Fuck* me ... */ |
1167 | if (timer1) | 1188 | if (timer1) |
1168 | memcpy (timer2, timer1, sizeof (struct timeval)); | 1189 | memcpy(timer2, timer1, sizeof(struct timeval)); |
1169 | rr = select (16, ding2, 0, 0, timer2); /* here it is, kiddies */ | 1190 | rr = select(16, ding2, 0, 0, timer2); /* here it is, kiddies */ |
1170 | if (rr < 0) { | 1191 | if (rr < 0) { |
1171 | if (errno != EINTR) { /* might have gotten ^Zed, etc ?*/ | 1192 | if (errno != EINTR) { /* might have gotten ^Zed, etc |
1172 | holler ("select fuxored"); | 1193 | * ? */ |
1173 | close (fd); | 1194 | holler("select fuxored"); |
1174 | return (1); | 1195 | close(fd); |
1175 | } | 1196 | return (1); |
1176 | } /* select fuckup */ | 1197 | } |
1177 | /* if we have a timeout AND stdin is closed AND we haven't heard anything | 1198 | } /* select fuckup */ |
1178 | from the net during that time, assume it's dead and close it too. */ | 1199 | /* if we have a timeout AND stdin is closed AND we haven't |
1179 | if (rr == 0) { | 1200 | * heard anything from the net during that time, assume it's |
1180 | if (! FD_ISSET (0, ding1)) | 1201 | * dead and close it too. */ |
1181 | netretry--; /* we actually try a coupla times. */ | 1202 | if (rr == 0) { |
1182 | if (! netretry) { | 1203 | if (!FD_ISSET(0, ding1)) |
1183 | if (o_verbose > 1) /* normally we don't care */ | 1204 | netretry--; /* we actually try a coupla |
1184 | holler ("net timeout"); | 1205 | * times. */ |
1185 | close (fd); | 1206 | if (!netretry) { |
1186 | return (0); /* not an error! */ | 1207 | if (o_verbose > 1) /* normally we don't |
1187 | } | 1208 | * care */ |
1188 | } /* select timeout */ | 1209 | holler("net timeout"); |
1189 | /* xxx: should we check the exception fds too? The read fds seem to give | 1210 | close(fd); |
1190 | us the right info, and none of the examples I found bothered. */ | 1211 | return (0); /* not an error! */ |
1191 | 1212 | } | |
1192 | /* Ding!! Something arrived, go check all the incoming hoppers, net first */ | 1213 | } /* select timeout */ |
1193 | if (FD_ISSET (fd, ding2)) { /* net: ding! */ | 1214 | /* xxx: should we check the exception fds too? The read fds |
1194 | rr = read (fd, bigbuf_net, BIGSIZ); | 1215 | * seem to give us the right info, and none of the examples I |
1195 | if (rr <= 0) { | 1216 | * found bothered. */ |
1196 | FD_CLR (fd, ding1); /* net closed, we'll finish up... */ | 1217 | /* Ding!! Something arrived, go check all the incoming |
1197 | rzleft = 0; /* can't write anymore: broken pipe */ | 1218 | * hoppers, net first */ |
1198 | } else { | 1219 | if (FD_ISSET(fd, ding2)) { /* net: ding! */ |
1199 | rnleft = rr; | 1220 | rr = read(fd, bigbuf_net, BIGSIZ); |
1200 | np = bigbuf_net; | 1221 | if (rr <= 0) { |
1222 | FD_CLR(fd, ding1); /* net closed, we'll | ||
1223 | * finish up... */ | ||
1224 | rzleft = 0; /* can't write anymore: broken | ||
1225 | * pipe */ | ||
1226 | } else { | ||
1227 | rnleft = rr; | ||
1228 | np = bigbuf_net; | ||
1201 | #ifdef TELNET | 1229 | #ifdef TELNET |
1202 | if (o_tn) | 1230 | if (o_tn) |
1203 | atelnet (np, rr); /* fake out telnet stuff */ | 1231 | atelnet(np, rr); /* fake out telnet stuff */ |
1204 | #endif /* TELNET */ | 1232 | #endif /* TELNET */ |
1205 | } /* if rr */ | 1233 | } /* if rr */ |
1206 | Debug (("got %d from the net, errno %d", rr, errno)) | 1234 | Debug(("got %d from the net, errno %d", rr, errno)) |
1207 | } /* net:ding */ | 1235 | } /* net:ding */ |
1208 | 1236 | /* if we're in "slowly" mode there's probably still stuff in | |
1209 | /* if we're in "slowly" mode there's probably still stuff in the stdin | 1237 | * the stdin buffer, so don't read unless we really need MORE |
1210 | buffer, so don't read unless we really need MORE INPUT! MORE INPUT! */ | 1238 | * INPUT! MORE INPUT! */ |
1211 | if (rzleft) | 1239 | if (rzleft) |
1212 | goto shovel; | 1240 | goto shovel; |
1213 | 1241 | ||
1214 | /* okay, suck more stdin */ | 1242 | /* okay, suck more stdin */ |
1215 | if (FD_ISSET (0, ding2)) { /* stdin: ding! */ | 1243 | if (FD_ISSET(0, ding2)) { /* stdin: ding! */ |
1216 | rr = read (0, bigbuf_in, BIGSIZ); | 1244 | rr = read(0, bigbuf_in, BIGSIZ); |
1217 | /* Considered making reads here smaller for UDP mode, but 8192-byte | 1245 | /* Considered making reads here smaller for UDP mode, but 8192-byte |
1218 | mobygrams are kinda fun and exercise the reassembler. */ | 1246 | mobygrams are kinda fun and exercise the reassembler. */ |
1219 | if (rr <= 0) { /* at end, or fukt, or ... */ | 1247 | if (rr <= 0) { /* at end, or fukt, or ... */ |
1220 | FD_CLR (0, ding1); /* disable and close stdin */ | 1248 | FD_CLR(0, ding1); /* disable and close |
1221 | close (0); | 1249 | * stdin */ |
1222 | } else { | 1250 | close(0); |
1223 | rzleft = rr; | 1251 | } else { |
1224 | zp = bigbuf_in; | 1252 | rzleft = rr; |
1253 | zp = bigbuf_in; | ||
1225 | /* special case for multi-mode -- we'll want to send this one buffer to every | 1254 | /* special case for multi-mode -- we'll want to send this one buffer to every |
1226 | open TCP port or every UDP attempt, so save its size and clean up stdin */ | 1255 | open TCP port or every UDP attempt, so save its size and clean up stdin */ |
1227 | if (! Single) { /* we might be scanning... */ | 1256 | if (!Single) { /* we might be scanning... */ |
1228 | insaved = rr; /* save len */ | 1257 | insaved = rr; /* save len */ |
1229 | FD_CLR (0, ding1); /* disable further junk from stdin */ | 1258 | FD_CLR(0, ding1); /* disable further junk |
1230 | close (0); /* really, I mean it */ | 1259 | * from stdin */ |
1231 | } /* Single */ | 1260 | close(0); /* really, I mean it */ |
1232 | } /* if rr/read */ | 1261 | } /* Single */ |
1233 | } /* stdin:ding */ | 1262 | } /* if rr/read */ |
1234 | 1263 | } /* stdin:ding */ | |
1235 | shovel: | 1264 | shovel: |
1236 | /* now that we've dingdonged all our thingdings, send off the results. | 1265 | /* now that we've dingdonged all our thingdings, send off the results. |
1237 | Geez, why does this look an awful lot like the big loop in "rsh"? ... | 1266 | Geez, why does this look an awful lot like the big loop in "rsh"? ... |
1238 | not sure if the order of this matters, but write net -> stdout first. */ | 1267 | not sure if the order of this matters, but write net -> stdout first. */ |
1239 | 1268 | ||
1240 | /* sanity check. Works because they're both unsigned... */ | 1269 | /* sanity check. Works because they're both unsigned... */ |
1241 | if ((rzleft > 8200) || (rnleft > 8200)) { | 1270 | if ((rzleft > 8200) || (rnleft > 8200)) { |
1242 | holler ("Bogus buffers: %d, %d", rzleft, rnleft); | 1271 | holler("Bogus buffers: %d, %d", rzleft, rnleft); |
1243 | rzleft = rnleft = 0; | 1272 | rzleft = rnleft = 0; |
1244 | } | 1273 | } |
1245 | /* net write retries sometimes happen on UDP connections */ | 1274 | /* net write retries sometimes happen on UDP connections */ |
1246 | if (! wretry) { /* is something hung? */ | 1275 | if (!wretry) { /* is something hung? */ |
1247 | holler ("too many output retries"); | 1276 | holler("too many output retries"); |
1248 | return (1); | 1277 | return (1); |
1249 | } | 1278 | } |
1250 | if (rnleft) { | 1279 | if (rnleft) { |
1251 | rr = write (1, np, rnleft); | 1280 | rr = write(1, np, rnleft); |
1252 | if (rr > 0) { | 1281 | if (rr > 0) { |
1253 | if (o_wfile) | 1282 | if (o_wfile) |
1254 | oprint (1, np, rr); /* log the stdout */ | 1283 | oprint(1, np, rr); /* log the stdout */ |
1255 | np += rr; /* fix up ptrs and whatnot */ | 1284 | np += rr; /* fix up ptrs and whatnot */ |
1256 | rnleft -= rr; /* will get sanity-checked above */ | 1285 | rnleft -= rr; /* will get sanity-checked |
1257 | wrote_out += rr; /* global count */ | 1286 | * above */ |
1258 | } | 1287 | wrote_out += rr; /* global count */ |
1259 | Debug (("wrote %d to stdout, errno %d", rr, errno)) | 1288 | } |
1260 | } /* rnleft */ | 1289 | Debug(("wrote %d to stdout, errno %d", rr, errno)) |
1261 | if (rzleft) { | 1290 | } /* rnleft */ |
1262 | if (o_interval) /* in "slowly" mode ?? */ | 1291 | if (rzleft) { |
1263 | rr = findline (zp, rzleft); | 1292 | if (o_interval) /* in "slowly" mode ?? */ |
1264 | else | 1293 | rr = findline(zp, rzleft); |
1265 | rr = rzleft; | 1294 | else |
1266 | rr = write (fd, zp, rr); /* one line, or the whole buffer */ | 1295 | rr = rzleft; |
1267 | if (rr > 0) { | 1296 | rr = write(fd, zp, rr); /* one line, or the whole |
1268 | if (o_wfile) | 1297 | * buffer */ |
1269 | oprint (0, zp, rr); /* log what got sent */ | 1298 | if (rr > 0) { |
1270 | zp += rr; | 1299 | if (o_wfile) |
1271 | rzleft -= rr; | 1300 | oprint(0, zp, rr); /* log what got sent */ |
1272 | wrote_net += rr; /* global count */ | 1301 | zp += rr; |
1273 | } | 1302 | rzleft -= rr; |
1274 | Debug (("wrote %d to net, errno %d", rr, errno)) | 1303 | wrote_net += rr; /* global count */ |
1275 | } /* rzleft */ | 1304 | } |
1276 | if (o_interval) { /* cycle between slow lines, or ... */ | 1305 | Debug(("wrote %d to net, errno %d", rr, errno)) |
1277 | sleep (o_interval); | 1306 | } /* rzleft */ |
1278 | errno = 0; /* clear from sleep */ | 1307 | if (o_interval) { /* cycle between slow lines, or ... */ |
1279 | continue; /* ...with hairy select loop... */ | 1308 | sleep(o_interval); |
1280 | } | 1309 | errno = 0; /* clear from sleep */ |
1281 | if ((rzleft) || (rnleft)) { /* shovel that shit till they ain't */ | 1310 | continue; /* ...with hairy select loop... */ |
1282 | wretry--; /* none left, and get another load */ | 1311 | } |
1283 | goto shovel; | 1312 | if ((rzleft) || (rnleft)) { /* shovel that shit till they |
1284 | } | 1313 | * ain't */ |
1285 | } /* while ding1:netfd is open */ | 1314 | wretry--; /* none left, and get another load */ |
1315 | goto shovel; | ||
1316 | } | ||
1317 | } /* while ding1:netfd is open */ | ||
1286 | 1318 | ||
1287 | /* XXX: maybe want a more graceful shutdown() here, or screw around with | 1319 | /* XXX: maybe want a more graceful shutdown() here, or screw around with |
1288 | linger times?? I suspect that I don't need to since I'm always doing | 1320 | linger times?? I suspect that I don't need to since I'm always doing |
1289 | blocking reads and writes and my own manual "last ditch" efforts to read | 1321 | blocking reads and writes and my own manual "last ditch" efforts to read |
1290 | the net again after a timeout. I haven't seen any screwups yet, but it's | 1322 | the net again after a timeout. I haven't seen any screwups yet, but it's |
1291 | not like my test network is particularly busy... */ | 1323 | not like my test network is particularly busy... */ |
1292 | close (fd); | 1324 | close(fd); |
1293 | return (0); | 1325 | return (0); |
1294 | } /* readwrite */ | 1326 | } /* readwrite */ |
1295 | 1327 | ||
1296 | /* main : | 1328 | /* main : |
1297 | now we pull it all together... */ | 1329 | now we pull it all together... */ |
1298 | main (argc, argv) | 1330 | main(argc, argv) |
1299 | int argc; | 1331 | int argc; |
1300 | char ** argv; | 1332 | char **argv; |
1301 | { | 1333 | { |
1302 | #ifndef HAVE_GETOPT | 1334 | #ifndef HAVE_GETOPT |
1303 | extern char * optarg; | 1335 | extern char *optarg; |
1304 | extern int optind, optopt; | 1336 | extern int optind, optopt; |
1305 | #endif | 1337 | #endif |
1306 | register int x; | 1338 | register int x; |
1307 | register char *cp; | 1339 | register char *cp; |
1308 | HINF * gp; | 1340 | HINF *gp; |
1309 | HINF * whereto = NULL; | 1341 | HINF *whereto = NULL; |
1310 | HINF * wherefrom = NULL; | 1342 | HINF *wherefrom = NULL; |
1311 | IA * ouraddr = NULL; | 1343 | IA *ouraddr = NULL; |
1312 | IA * themaddr = NULL; | 1344 | IA *themaddr = NULL; |
1313 | USHORT o_lport = 0; | 1345 | USHORT o_lport = 0; |
1314 | USHORT ourport = 0; | 1346 | USHORT ourport = 0; |
1315 | USHORT loport = 0; /* for scanning stuff */ | 1347 | USHORT loport = 0; /* for scanning stuff */ |
1316 | USHORT hiport = 0; | 1348 | USHORT hiport = 0; |
1317 | USHORT curport = 0; | 1349 | USHORT curport = 0; |
1318 | char * randports = NULL; | 1350 | char *randports = NULL; |
1319 | 1351 | ||
1320 | #ifdef HAVE_BIND | 1352 | #ifdef HAVE_BIND |
1321 | /* can *you* say "cc -yaddayadda netcat.c -lresolv -l44bsd" on SunLOSs? */ | 1353 | /* can *you* say "cc -yaddayadda netcat.c -lresolv -l44bsd" on SunLOSs? */ |
1322 | res_init(); | 1354 | res_init(); |
1323 | #endif | 1355 | #endif |
1324 | /* I was in this barbershop quartet in Skokie IL ... */ | 1356 | /* I was in this barbershop quartet in Skokie IL ... */ |
1325 | /* round up the usual suspects, i.e. malloc up all the stuff we need */ | 1357 | /* round up the usual suspects, i.e. malloc up all the stuff we need */ |
1326 | lclend = (SAI *) Hmalloc (sizeof (SA)); | 1358 | lclend = (SAI *) Hmalloc(sizeof(SA)); |
1327 | remend = (SAI *) Hmalloc (sizeof (SA)); | 1359 | remend = (SAI *) Hmalloc(sizeof(SA)); |
1328 | bigbuf_in = Hmalloc (BIGSIZ); | 1360 | bigbuf_in = Hmalloc(BIGSIZ); |
1329 | bigbuf_net = Hmalloc (BIGSIZ); | 1361 | bigbuf_net = Hmalloc(BIGSIZ); |
1330 | ding1 = (fd_set *) Hmalloc (sizeof (fd_set)); | 1362 | ding1 = (fd_set *) Hmalloc(sizeof(fd_set)); |
1331 | ding2 = (fd_set *) Hmalloc (sizeof (fd_set)); | 1363 | ding2 = (fd_set *) Hmalloc(sizeof(fd_set)); |
1332 | portpoop = (PINF *) Hmalloc (sizeof (PINF)); | 1364 | portpoop = (PINF *) Hmalloc(sizeof(PINF)); |
1333 | 1365 | ||
1334 | errno = 0; | 1366 | errno = 0; |
1335 | gatesptr = 4; | 1367 | gatesptr = 4; |
1336 | h_errno = 0; | 1368 | h_errno = 0; |
1337 | 1369 | ||
1338 | /* catch a signal or two for cleanup */ | 1370 | /* catch a signal or two for cleanup */ |
1339 | signal (SIGINT, catch); | 1371 | signal(SIGINT, catch); |
1340 | signal (SIGQUIT, catch); | 1372 | signal(SIGQUIT, catch); |
1341 | signal (SIGTERM, catch); | 1373 | signal(SIGTERM, catch); |
1342 | /* and suppress others... */ | 1374 | /* and suppress others... */ |
1343 | #ifdef SIGURG | 1375 | #ifdef SIGURG |
1344 | signal (SIGURG, SIG_IGN); | 1376 | signal(SIGURG, SIG_IGN); |
1345 | #endif | 1377 | #endif |
1346 | #ifdef SIGPIPE | 1378 | #ifdef SIGPIPE |
1347 | signal (SIGPIPE, SIG_IGN); /* important! */ | 1379 | signal(SIGPIPE, SIG_IGN); /* important! */ |
1348 | #endif | 1380 | #endif |
1349 | 1381 | ||
1350 | /* if no args given at all, get 'em from stdin, construct an argv, and hand | 1382 | /* if no args given at all, get 'em from stdin, construct an argv, and hand |
1351 | anything left over to readwrite(). */ | 1383 | anything left over to readwrite(). */ |
1352 | if (argc == 1) { | 1384 | if (argc == 1) { |
1353 | cp = argv[0]; | 1385 | cp = argv[0]; |
1354 | argv = (char **) Hmalloc (128 * sizeof (char *)); /* XXX: 128? */ | 1386 | argv = (char **) Hmalloc(128 * sizeof(char *)); /* XXX: 128? */ |
1355 | argv[0] = cp; /* leave old prog name intact */ | 1387 | argv[0] = cp; /* leave old prog name intact */ |
1356 | cp = Hmalloc (BIGSIZ); | 1388 | cp = Hmalloc(BIGSIZ); |
1357 | argv[1] = cp; /* head of new arg block */ | 1389 | argv[1] = cp; /* head of new arg block */ |
1358 | fprintf (stderr, "Cmd line: "); | 1390 | fprintf(stderr, "Cmd line: "); |
1359 | fflush (stderr); /* I dont care if it's unbuffered or not! */ | 1391 | fflush(stderr); /* I dont care if it's unbuffered or not! */ |
1360 | insaved = read (0, cp, BIGSIZ); /* we're gonna fake fgets() here */ | 1392 | insaved = read(0, cp, BIGSIZ); /* we're gonna fake fgets() |
1361 | if (insaved <= 0) | 1393 | * here */ |
1362 | bail ("wrong"); | 1394 | if (insaved <= 0) |
1363 | x = findline (cp, insaved); | 1395 | bail("wrong"); |
1364 | if (x) | 1396 | x = findline(cp, insaved); |
1365 | insaved -= x; /* remaining chunk size to be sent */ | 1397 | if (x) |
1366 | if (insaved) /* which might be zero... */ | 1398 | insaved -= x; /* remaining chunk size to be sent */ |
1367 | memcpy (bigbuf_in, &cp[x], insaved); | 1399 | if (insaved) /* which might be zero... */ |
1368 | cp = strchr (argv[1], '\n'); | 1400 | memcpy(bigbuf_in, &cp[x], insaved); |
1369 | if (cp) | 1401 | cp = strchr(argv[1], '\n'); |
1370 | *cp = '\0'; | 1402 | if (cp) |
1371 | cp = strchr (argv[1], '\r'); /* look for ^M too */ | 1403 | *cp = '\0'; |
1372 | if (cp) | 1404 | cp = strchr(argv[1], '\r'); /* look for ^M too */ |
1373 | *cp = '\0'; | 1405 | if (cp) |
1406 | *cp = '\0'; | ||
1374 | 1407 | ||
1375 | /* find and stash pointers to remaining new "args" */ | 1408 | /* find and stash pointers to remaining new "args" */ |
1376 | cp = argv[1]; | 1409 | cp = argv[1]; |
1377 | cp++; /* skip past first char */ | 1410 | cp++; /* skip past first char */ |
1378 | x = 2; /* we know argv 0 and 1 already */ | 1411 | x = 2; /* we know argv 0 and 1 already */ |
1379 | for (; *cp != '\0'; cp++) { | 1412 | for (; *cp != '\0'; cp++) { |
1380 | if (*cp == ' ') { | 1413 | if (*cp == ' ') { |
1381 | *cp = '\0'; /* smash all spaces */ | 1414 | *cp = '\0'; /* smash all spaces */ |
1382 | continue; | 1415 | continue; |
1383 | } else { | 1416 | } else { |
1384 | if (*(cp-1) == '\0') { | 1417 | if (*(cp - 1) == '\0') { |
1385 | argv[x] = cp; | 1418 | argv[x] = cp; |
1386 | x++; | 1419 | x++; |
1387 | } | 1420 | } |
1388 | } /* if space */ | 1421 | } /* if space */ |
1389 | } /* for cp */ | 1422 | } /* for cp */ |
1390 | argc = x; | 1423 | argc = x; |
1391 | } /* if no args given */ | 1424 | } /* if no args given */ |
1392 | 1425 | /* If your shitbox doesn't have getopt, step into the nineties | |
1393 | /* If your shitbox doesn't have getopt, step into the nineties already. */ | 1426 | * already. */ |
1394 | /* optarg, optind = next-argv-component [i.e. flag arg]; optopt = last-char */ | 1427 | /* optarg, optind = next-argv-component [i.e. flag arg]; optopt = |
1395 | while ((x = getopt (argc, argv, "ae:g:G:hi:lno:p:rs:tuvw:z")) != -1) { | 1428 | * last-char */ |
1429 | while ((x = getopt(argc, argv, "ae:g:G:hi:lno:p:rs:tuvw:z")) != -1) { | ||
1396 | /* Debug (("in go: x now %c, optarg %x optind %d", x, optarg, optind)) */ | 1430 | /* Debug (("in go: x now %c, optarg %x optind %d", x, optarg, optind)) */ |
1397 | switch (x) { | 1431 | switch (x) { |
1398 | case 'a': | 1432 | case 'a': |
1399 | bail ("all-A-records NIY"); | 1433 | bail("all-A-records NIY"); |
1400 | o_alla++; break; | 1434 | o_alla++; |
1435 | break; | ||
1401 | #ifdef GAPING_SECURITY_HOLE | 1436 | #ifdef GAPING_SECURITY_HOLE |
1402 | case 'e': /* prog to exec */ | 1437 | case 'e': /* prog to exec */ |
1403 | pr00gie = optarg; | 1438 | pr00gie = optarg; |
1404 | break; | 1439 | break; |
1405 | #endif | 1440 | #endif |
1406 | case 'G': /* srcrt gateways pointer val */ | 1441 | case 'G': /* srcrt gateways pointer val */ |
1407 | x = atoi (optarg); | 1442 | x = atoi(optarg); |
1408 | if ((x) && (x == (x & 0x1c))) /* mask off bits of fukt values */ | 1443 | if ((x) && (x == (x & 0x1c))) /* mask off bits of fukt |
1409 | gatesptr = x; | 1444 | * values */ |
1410 | else | 1445 | gatesptr = x; |
1411 | bail ("invalid hop pointer %d, must be multiple of 4 <= 28", x); | 1446 | else |
1412 | break; | 1447 | bail("invalid hop pointer %d, must be multiple of 4 <= 28", x); |
1413 | case 'g': /* srcroute hop[s] */ | 1448 | break; |
1414 | if (gatesidx > 8) | 1449 | case 'g': /* srcroute hop[s] */ |
1415 | bail ("too many -g hops"); | 1450 | if (gatesidx > 8) |
1416 | if (gates == NULL) /* eat this, Billy-boy */ | 1451 | bail("too many -g hops"); |
1417 | gates = (HINF **) Hmalloc (sizeof (HINF *) * 10); | 1452 | if (gates == NULL) /* eat this, Billy-boy */ |
1418 | gp = gethostpoop (optarg, o_nflag); | 1453 | gates = (HINF **) Hmalloc(sizeof(HINF *) * 10); |
1419 | if (gp) | 1454 | gp = gethostpoop(optarg, o_nflag); |
1420 | gates[gatesidx] = gp; | 1455 | if (gp) |
1421 | gatesidx++; | 1456 | gates[gatesidx] = gp; |
1422 | break; | 1457 | gatesidx++; |
1423 | case 'h': | 1458 | break; |
1424 | errno = 0; | 1459 | case 'h': |
1460 | errno = 0; | ||
1425 | #ifdef HAVE_HELP | 1461 | #ifdef HAVE_HELP |
1426 | helpme(); /* exits by itself */ | 1462 | helpme(); /* exits by itself */ |
1427 | #else | 1463 | #else |
1428 | bail ("no help available, dork -- RTFS"); | 1464 | bail("no help available, dork -- RTFS"); |
1429 | #endif | 1465 | #endif |
1430 | case 'i': /* line-interval time */ | 1466 | case 'i': /* line-interval time */ |
1431 | o_interval = atoi (optarg) & 0xffff; | 1467 | o_interval = atoi(optarg) & 0xffff; |
1432 | if (! o_interval) | 1468 | if (!o_interval) |
1433 | bail ("invalid interval time %s", optarg); | 1469 | bail("invalid interval time %s", optarg); |
1434 | break; | 1470 | break; |
1435 | case 'l': /* listen mode */ | 1471 | case 'l': /* listen mode */ |
1436 | o_listen++; break; | 1472 | o_listen++; |
1437 | case 'n': /* numeric-only, no DNS lookups */ | 1473 | break; |
1438 | o_nflag++; break; | 1474 | case 'n': /* numeric-only, no DNS lookups */ |
1439 | case 'o': /* hexdump log */ | 1475 | o_nflag++; |
1440 | stage = (unsigned char *) optarg; | 1476 | break; |
1441 | o_wfile++; break; | 1477 | case 'o': /* hexdump log */ |
1442 | case 'p': /* local source port */ | 1478 | stage = (unsigned char *) optarg; |
1443 | o_lport = getportpoop (optarg, 0); | 1479 | o_wfile++; |
1444 | if (o_lport == 0) | 1480 | break; |
1445 | bail ("invalid local port %s", optarg); | 1481 | case 'p': /* local source port */ |
1446 | break; | 1482 | o_lport = getportpoop(optarg, 0); |
1447 | case 'r': /* randomize various things */ | 1483 | if (o_lport == 0) |
1448 | o_random++; break; | 1484 | bail("invalid local port %s", optarg); |
1449 | case 's': /* local source address */ | 1485 | break; |
1486 | case 'r': /* randomize various things */ | ||
1487 | o_random++; | ||
1488 | break; | ||
1489 | case 's': /* local source address */ | ||
1450 | /* do a full lookup [since everything else goes through the same mill], | 1490 | /* do a full lookup [since everything else goes through the same mill], |
1451 | unless -n was previously specified. In fact, careful placement of -n can | 1491 | unless -n was previously specified. In fact, careful placement of -n can |
1452 | be useful, so we'll still pass o_nflag here instead of forcing numeric. */ | 1492 | be useful, so we'll still pass o_nflag here instead of forcing numeric. */ |
1453 | wherefrom = gethostpoop (optarg, o_nflag); | 1493 | wherefrom = gethostpoop(optarg, o_nflag); |
1454 | ouraddr = &wherefrom->iaddrs[0]; | 1494 | ouraddr = &wherefrom->iaddrs[0]; |
1455 | break; | 1495 | break; |
1456 | #ifdef TELNET | 1496 | #ifdef TELNET |
1457 | case 't': /* do telnet fakeout */ | 1497 | case 't': /* do telnet fakeout */ |
1458 | o_tn++; break; | 1498 | o_tn++; |
1459 | #endif /* TELNET */ | 1499 | break; |
1460 | case 'u': /* use UDP */ | 1500 | #endif /* TELNET */ |
1461 | o_udpmode++; break; | 1501 | case 'u': /* use UDP */ |
1462 | case 'v': /* verbose */ | 1502 | o_udpmode++; |
1463 | o_verbose++; break; | 1503 | break; |
1464 | case 'w': /* wait time */ | 1504 | case 'v': /* verbose */ |
1465 | o_wait = atoi (optarg); | 1505 | o_verbose++; |
1466 | if (o_wait <= 0) | 1506 | break; |
1467 | bail ("invalid wait-time %s", optarg); | 1507 | case 'w': /* wait time */ |
1468 | timer1 = (struct timeval *) Hmalloc (sizeof (struct timeval)); | 1508 | o_wait = atoi(optarg); |
1469 | timer2 = (struct timeval *) Hmalloc (sizeof (struct timeval)); | 1509 | if (o_wait <= 0) |
1470 | timer1->tv_sec = o_wait; /* we need two. see readwrite()... */ | 1510 | bail("invalid wait-time %s", optarg); |
1471 | break; | 1511 | timer1 = (struct timeval *) Hmalloc(sizeof(struct timeval)); |
1472 | case 'z': /* little or no data xfer */ | 1512 | timer2 = (struct timeval *) Hmalloc(sizeof(struct timeval)); |
1473 | o_zero++; | 1513 | timer1->tv_sec = o_wait; /* we need two. see |
1474 | break; | 1514 | * readwrite()... */ |
1475 | default: | 1515 | break; |
1476 | errno = 0; | 1516 | case 'z': /* little or no data xfer */ |
1477 | bail ("nc -h for help"); | 1517 | o_zero++; |
1478 | } /* switch x */ | 1518 | break; |
1479 | } /* while getopt */ | 1519 | default: |
1520 | errno = 0; | ||
1521 | bail("nc -h for help"); | ||
1522 | } /* switch x */ | ||
1523 | } /* while getopt */ | ||
1480 | 1524 | ||
1481 | /* other misc initialization */ | 1525 | /* other misc initialization */ |
1482 | Debug (("fd_set size %d", sizeof (*ding1))) /* how big *is* it? */ | 1526 | Debug(("fd_set size %d", sizeof(*ding1))) /* how big *is* it? */ |
1483 | FD_SET (0, ding1); /* stdin *is* initially open */ | 1527 | FD_SET(0, ding1); /* stdin *is* initially open */ |
1484 | if (o_random) { | 1528 | if (o_random) { |
1485 | SRAND (time (0)); | 1529 | SRAND(time(0)); |
1486 | randports = Hmalloc (65536); /* big flag array for ports */ | 1530 | randports = Hmalloc(65536); /* big flag array for ports */ |
1487 | } | 1531 | } |
1488 | #ifdef GAPING_SECURITY_HOLE | 1532 | #ifdef GAPING_SECURITY_HOLE |
1489 | if (pr00gie) { | 1533 | if (pr00gie) { |
1490 | close (0); /* won't need stdin */ | 1534 | close(0); /* won't need stdin */ |
1491 | o_wfile = 0; /* -o with -e is meaningless! */ | 1535 | o_wfile = 0; /* -o with -e is meaningless! */ |
1492 | ofd = 0; | 1536 | ofd = 0; |
1493 | } | 1537 | } |
1494 | #endif /* G_S_H */ | 1538 | #endif /* G_S_H */ |
1495 | if (o_wfile) { | 1539 | if (o_wfile) { |
1496 | ofd = open (stage, O_WRONLY | O_CREAT | O_TRUNC, 0664); | 1540 | ofd = open(stage, O_WRONLY | O_CREAT | O_TRUNC, 0664); |
1497 | if (ofd <= 0) /* must be > extant 0/1/2 */ | 1541 | if (ofd <= 0) /* must be > extant 0/1/2 */ |
1498 | bail ("can't open %s", stage); | 1542 | bail("can't open %s", stage); |
1499 | stage = (unsigned char *) Hmalloc (100); | 1543 | stage = (unsigned char *) Hmalloc(100); |
1500 | } | 1544 | } |
1501 | |||
1502 | /* optind is now index of first non -x arg */ | 1545 | /* optind is now index of first non -x arg */ |
1503 | Debug (("after go: x now %c, optarg %x optind %d", x, optarg, optind)) | 1546 | Debug(("after go: x now %c, optarg %x optind %d", x, optarg, optind)) |
1504 | /* Debug (("optind up to %d at host-arg %s", optind, argv[optind])) */ | 1547 | /* Debug (("optind up to %d at host-arg %s", optind, argv[optind])) */ |
1505 | /* gonna only use first addr of host-list, like our IQ was normal; if you wanna | 1548 | /* gonna only use first addr of host-list, like our IQ was normal; if you wanna |
1506 | get fancy with addresses, look up the list yourself and plug 'em in for now. | 1549 | get fancy with addresses, look up the list yourself and plug 'em in for now. |
1507 | unless we finally implement -a, that is. */ | 1550 | unless we finally implement -a, that is. */ |
1508 | if (argv[optind]) | 1551 | if (argv[optind]) |
1509 | whereto = gethostpoop (argv[optind], o_nflag); | 1552 | whereto = gethostpoop(argv[optind], o_nflag); |
1510 | if (whereto && whereto->iaddrs) | 1553 | if (whereto && whereto->iaddrs) |
1511 | themaddr = &whereto->iaddrs[0]; | 1554 | themaddr = &whereto->iaddrs[0]; |
1512 | if (themaddr) | 1555 | if (themaddr) |
1513 | optind++; /* skip past valid host lookup */ | 1556 | optind++; /* skip past valid host lookup */ |
1514 | errno = 0; | 1557 | errno = 0; |
1515 | h_errno = 0; | 1558 | h_errno = 0; |
1516 | 1559 | ||
1517 | /* Handle listen mode here, and exit afterward. Only does one connect; | 1560 | /* Handle listen mode here, and exit afterward. Only does one connect; |
1518 | this is arguably the right thing to do. A "persistent listen-and-fork" | 1561 | this is arguably the right thing to do. A "persistent listen-and-fork" |
1519 | mode a la inetd has been thought about, but not implemented. A tiny | 1562 | mode a la inetd has been thought about, but not implemented. A tiny |
1520 | wrapper script can handle such things... */ | 1563 | wrapper script can handle such things... */ |
1521 | if (o_listen) { | 1564 | if (o_listen) { |
1522 | curport = 0; /* rem port *can* be zero here... */ | 1565 | curport = 0; /* rem port *can* be zero here... */ |
1523 | if (argv[optind]) { /* any rem-port-arg? */ | 1566 | if (argv[optind]) { /* any rem-port-arg? */ |
1524 | curport = getportpoop (argv[optind], 0); | 1567 | curport = getportpoop(argv[optind], 0); |
1525 | if (curport == 0) /* if given, demand correctness */ | 1568 | if (curport == 0) /* if given, demand |
1526 | bail ("invalid port %s", argv[optind]); | 1569 | * correctness */ |
1527 | } /* if port-arg */ | 1570 | bail("invalid port %s", argv[optind]); |
1528 | netfd = dolisten (themaddr, curport, ouraddr, o_lport); | 1571 | } /* if port-arg */ |
1572 | netfd = dolisten(themaddr, curport, ouraddr, o_lport); | ||
1529 | /* dolisten does its own connect reporting, so we don't holler anything here */ | 1573 | /* dolisten does its own connect reporting, so we don't holler anything here */ |
1530 | if (netfd > 0) { | 1574 | if (netfd > 0) { |
1531 | #ifdef GAPING_SECURITY_HOLE | 1575 | #ifdef GAPING_SECURITY_HOLE |
1532 | if (pr00gie) /* -e given? */ | 1576 | if (pr00gie) /* -e given? */ |
1533 | doexec (netfd); | 1577 | doexec(netfd); |
1534 | #endif /* GAPING_SECURITY_HOLE */ | 1578 | #endif /* GAPING_SECURITY_HOLE */ |
1535 | x = readwrite (netfd); /* it even works with UDP! */ | 1579 | x = readwrite(netfd); /* it even works with UDP! */ |
1536 | if (o_verbose > 1) /* normally we don't care */ | 1580 | if (o_verbose > 1) /* normally we don't care */ |
1537 | holler (wrote_txt, wrote_net, wrote_out); | 1581 | holler(wrote_txt, wrote_net, wrote_out); |
1538 | exit (x); /* "pack out yer trash" */ | 1582 | exit(x);/* "pack out yer trash" */ |
1539 | } else /* if no netfd */ | 1583 | } else /* if no netfd */ |
1540 | bail ("no connection"); | 1584 | bail("no connection"); |
1541 | } /* o_listen */ | 1585 | } /* o_listen */ |
1542 | 1586 | /* fall thru to outbound connects. Now we're more picky about args... */ | |
1543 | /* fall thru to outbound connects. Now we're more picky about args... */ | 1587 | if (!themaddr) |
1544 | if (! themaddr) | 1588 | bail("no destination"); |
1545 | bail ("no destination"); | 1589 | if (argv[optind] == NULL) |
1546 | if (argv[optind] == NULL) | 1590 | bail("no port[s] to connect to"); |
1547 | bail ("no port[s] to connect to"); | 1591 | if (argv[optind + 1]) /* look ahead: any more port args given? */ |
1548 | if (argv[optind + 1]) /* look ahead: any more port args given? */ | 1592 | Single = 0; /* multi-mode, case A */ |
1549 | Single = 0; /* multi-mode, case A */ | 1593 | ourport = o_lport; /* which can be 0 */ |
1550 | ourport = o_lport; /* which can be 0 */ | ||
1551 | 1594 | ||
1552 | /* everything from here down is treated as as ports and/or ranges thereof, so | 1595 | /* everything from here down is treated as as ports and/or ranges thereof, so |
1553 | it's all enclosed in this big ol' argv-parsin' loop. Any randomization is | 1596 | it's all enclosed in this big ol' argv-parsin' loop. Any randomization is |
1554 | done within each given *range*, but in separate chunks per each succeeding | 1597 | done within each given *range*, but in separate chunks per each succeeding |
1555 | argument, so we can control the pattern somewhat. */ | 1598 | argument, so we can control the pattern somewhat. */ |
1556 | while (argv[optind]) { | 1599 | while (argv[optind]) { |
1557 | hiport = loport = 0; | 1600 | hiport = loport = 0; |
1558 | cp = strchr (argv[optind], '-'); /* nn-mm range? */ | 1601 | cp = strchr(argv[optind], '-'); /* nn-mm range? */ |
1559 | if (cp) { | 1602 | if (cp) { |
1560 | *cp = '\0'; | 1603 | *cp = '\0'; |
1561 | cp++; | 1604 | cp++; |
1562 | hiport = getportpoop (cp, 0); | 1605 | hiport = getportpoop(cp, 0); |
1563 | if (hiport == 0) | 1606 | if (hiport == 0) |
1564 | bail ("invalid port %s", cp); | 1607 | bail("invalid port %s", cp); |
1565 | } /* if found a dash */ | 1608 | } /* if found a dash */ |
1566 | loport = getportpoop (argv[optind], 0); | 1609 | loport = getportpoop(argv[optind], 0); |
1567 | if (loport == 0) | 1610 | if (loport == 0) |
1568 | bail ("invalid port %s", argv[optind]); | 1611 | bail("invalid port %s", argv[optind]); |
1569 | if (hiport > loport) { /* was it genuinely a range? */ | 1612 | if (hiport > loport) { /* was it genuinely a range? */ |
1570 | Single = 0; /* multi-mode, case B */ | 1613 | Single = 0; /* multi-mode, case B */ |
1571 | curport = hiport; /* start high by default */ | 1614 | curport = hiport; /* start high by default */ |
1572 | if (o_random) { /* maybe populate the random array */ | 1615 | if (o_random) { /* maybe populate the random array */ |
1573 | loadports (randports, loport, hiport); | 1616 | loadports(randports, loport, hiport); |
1574 | curport = nextport (randports); | 1617 | curport = nextport(randports); |
1575 | } | 1618 | } |
1576 | } else /* not a range, including args like "25-25" */ | 1619 | } else /* not a range, including args like "25-25" */ |
1577 | curport = loport; | 1620 | curport = loport; |
1578 | Debug (("Single %d, curport %d", Single, curport)) | 1621 | Debug(("Single %d, curport %d", Single, curport)) |
1579 | |||
1580 | /* Now start connecting to these things. curport is already preloaded. */ | 1622 | /* Now start connecting to these things. curport is already preloaded. */ |
1581 | while (loport <= curport) { | 1623 | while (loport <= curport) { |
1582 | if ((! o_lport) && (o_random)) { /* -p overrides random local-port */ | 1624 | if ((!o_lport) && (o_random)) { /* -p overrides random |
1583 | ourport = (RAND() & 0xffff); /* random local-bind -- well above */ | 1625 | * local-port */ |
1584 | if (ourport < 8192) /* resv and any likely listeners??? */ | 1626 | ourport = (RAND() & 0xffff); /* random local-bind -- |
1585 | ourport += 8192; /* if it *still* conflicts, use -s. */ | 1627 | * well above */ |
1586 | } | 1628 | if (ourport < 8192) /* resv and any likely |
1587 | curport = getportpoop (NULL, curport); | 1629 | * listeners??? */ |
1588 | netfd = doconnect (themaddr, curport, ouraddr, ourport); | 1630 | ourport += 8192; /* if it *still* |
1589 | Debug (("netfd %d from port %d to port %d", netfd, ourport, curport)) | 1631 | * conflicts, use -s. */ |
1590 | if (netfd > 0) | 1632 | } |
1591 | if (o_zero && o_udpmode) /* if UDP scanning... */ | 1633 | curport = getportpoop(NULL, curport); |
1592 | netfd = udptest (netfd, themaddr); | 1634 | netfd = doconnect(themaddr, curport, ouraddr, ourport); |
1593 | if (netfd > 0) { /* Yow, are we OPEN YET?! */ | 1635 | Debug(("netfd %d from port %d to port %d", netfd, ourport, curport)) |
1594 | x = 0; /* pre-exit status */ | 1636 | if (netfd > 0) |
1595 | holler ("%s [%s] %d (%s) open", | 1637 | if (o_zero && o_udpmode) /* if UDP scanning... */ |
1596 | whereto->name, whereto->addrs[0], curport, portpoop->name); | 1638 | netfd = udptest(netfd, themaddr); |
1639 | if (netfd > 0) { /* Yow, are we OPEN YET?! */ | ||
1640 | x = 0; /* pre-exit status */ | ||
1641 | holler("%s [%s] %d (%s) open", | ||
1642 | whereto->name, whereto->addrs[0], curport, portpoop->name); | ||
1597 | #ifdef GAPING_SECURITY_HOLE | 1643 | #ifdef GAPING_SECURITY_HOLE |
1598 | if (pr00gie) /* exec is valid for outbound, too */ | 1644 | if (pr00gie) /* exec is valid for outbound, |
1599 | doexec (netfd); | 1645 | * too */ |
1600 | #endif /* GAPING_SECURITY_HOLE */ | 1646 | doexec(netfd); |
1601 | if (! o_zero) | 1647 | #endif /* GAPING_SECURITY_HOLE */ |
1602 | x = readwrite (netfd); /* go shovel shit */ | 1648 | if (!o_zero) |
1603 | } else { /* no netfd... */ | 1649 | x = readwrite(netfd); /* go shovel shit */ |
1604 | x = 1; /* preload exit status for later */ | 1650 | } else {/* no netfd... */ |
1651 | x = 1; /* preload exit status for later */ | ||
1605 | /* if we're scanning at a "one -v" verbosity level, don't print refusals. | 1652 | /* if we're scanning at a "one -v" verbosity level, don't print refusals. |
1606 | Give it another -v if you want to see everything. */ | 1653 | Give it another -v if you want to see everything. */ |
1607 | if ((Single || (o_verbose > 1)) || (errno != ECONNREFUSED)) | 1654 | if ((Single || (o_verbose > 1)) || (errno != ECONNREFUSED)) |
1608 | holler ("%s [%s] %d (%s)", | 1655 | holler("%s [%s] %d (%s)", |
1609 | whereto->name, whereto->addrs[0], curport, portpoop->name); | 1656 | whereto->name, whereto->addrs[0], curport, portpoop->name); |
1610 | } /* if netfd */ | 1657 | } /* if netfd */ |
1611 | close (netfd); /* just in case we didn't already */ | 1658 | close(netfd); /* just in case we didn't already */ |
1612 | if (o_interval) | 1659 | if (o_interval) |
1613 | sleep (o_interval); /* if -i, delay between ports too */ | 1660 | sleep(o_interval); /* if -i, delay between |
1614 | if (o_random) | 1661 | * ports too */ |
1615 | curport = nextport (randports); | 1662 | if (o_random) |
1616 | else | 1663 | curport = nextport(randports); |
1617 | curport--; /* just decrement... */ | 1664 | else |
1618 | } /* while curport within current range */ | 1665 | curport--; /* just decrement... */ |
1619 | optind++; | 1666 | } /* while curport within current range */ |
1620 | } /* while remaining port-args -- end of big argv-ports loop*/ | 1667 | optind++; |
1621 | 1668 | } /* while remaining port-args -- end of big | |
1622 | errno = 0; | 1669 | * argv-ports loop */ |
1623 | if (o_verbose > 1) /* normally we don't care */ | 1670 | |
1624 | holler (wrote_txt, wrote_net, wrote_out); | 1671 | errno = 0; |
1625 | if (Single) | 1672 | if (o_verbose > 1) /* normally we don't care */ |
1626 | exit (x); /* give us status on one connection */ | 1673 | holler(wrote_txt, wrote_net, wrote_out); |
1627 | exit (0); /* otherwise, we're just done */ | 1674 | if (Single) |
1628 | } /* main */ | 1675 | exit(x); /* give us status on one connection */ |
1676 | exit(0); /* otherwise, we're just done */ | ||
1677 | } /* main */ | ||
1629 | 1678 | ||
1630 | #ifdef HAVE_HELP /* unless we wanna be *really* cryptic */ | 1679 | #ifdef HAVE_HELP /* unless we wanna be *really* cryptic */ |
1631 | /* helpme : | 1680 | /* helpme : |
1632 | the obvious */ | 1681 | the obvious */ |
1633 | helpme() | 1682 | helpme() |
1634 | { | 1683 | { |
1635 | o_verbose = 1; | 1684 | o_verbose = 1; |
1636 | holler ("[v1.10]\n\ | 1685 | holler("[v1.10]\n\ |
1637 | connect to somewhere: nc [-options] hostname port[s] [ports] ... \n\ | 1686 | connect to somewhere: nc [-options] hostname port[s] [ports] ... \n\ |
1638 | listen for inbound: nc -l -p port [-options] [hostname] [port]\n\ | 1687 | listen for inbound: nc -l -p port [-options] [hostname] [port]\n\ |
1639 | options:"); | 1688 | options:"); |
@@ -1641,10 +1690,10 @@ options:"); | |||
1641 | interpreted oddly by some compilers, generating or not generating extra | 1690 | interpreted oddly by some compilers, generating or not generating extra |
1642 | newlines as they bloody please. u-fix... */ | 1691 | newlines as they bloody please. u-fix... */ |
1643 | #ifdef GAPING_SECURITY_HOLE /* needs to be separate holler() */ | 1692 | #ifdef GAPING_SECURITY_HOLE /* needs to be separate holler() */ |
1644 | holler ("\ | 1693 | holler("\ |
1645 | -e prog program to exec after connect [dangerous!!]"); | 1694 | -e prog program to exec after connect [dangerous!!]"); |
1646 | #endif | 1695 | #endif |
1647 | holler ("\ | 1696 | holler("\ |
1648 | -g gateway source-routing hop point[s], up to 8\n\ | 1697 | -g gateway source-routing hop point[s], up to 8\n\ |
1649 | -G num source-routing pointer: 4, 8, 12, ...\n\ | 1698 | -G num source-routing pointer: 4, 8, 12, ...\n\ |
1650 | -h this cruft\n\ | 1699 | -h this cruft\n\ |
@@ -1656,16 +1705,16 @@ options:"); | |||
1656 | -r randomize local and remote ports\n\ | 1705 | -r randomize local and remote ports\n\ |
1657 | -s addr local source address"); | 1706 | -s addr local source address"); |
1658 | #ifdef TELNET | 1707 | #ifdef TELNET |
1659 | holler ("\ | 1708 | holler("\ |
1660 | -t answer TELNET negotiation"); | 1709 | -t answer TELNET negotiation"); |
1661 | #endif | 1710 | #endif |
1662 | holler ("\ | 1711 | holler("\ |
1663 | -u UDP mode\n\ | 1712 | -u UDP mode\n\ |
1664 | -v verbose [use twice to be more verbose]\n\ | 1713 | -v verbose [use twice to be more verbose]\n\ |
1665 | -w secs timeout for connects and final net reads\n\ | 1714 | -w secs timeout for connects and final net reads\n\ |
1666 | -z zero-I/O mode [used for scanning]"); | 1715 | -z zero-I/O mode [used for scanning]"); |
1667 | bail ("port numbers can be individual or ranges: lo-hi [inclusive]"); | 1716 | bail("port numbers can be individual or ranges: lo-hi [inclusive]"); |
1668 | } /* helpme */ | 1717 | } /* helpme */ |
1669 | #endif /* HAVE_HELP */ | 1718 | #endif /* HAVE_HELP */ |
1670 | 1719 | ||
1671 | /* None genuine without this seal! _H*/ | 1720 | /* None genuine without this seal! _H*/ |