Lines 55-60
Link Here
|
55 |
* |
55 |
* |
56 |
*/ |
56 |
*/ |
57 |
|
57 |
|
|
|
58 |
/* |
59 |
* 19990727 - Nick Johnson <freebsd@spatula.net> |
60 |
* Added -r and -w flags, cleaned up the code a bit, |
61 |
* made writes more robust (return values were not being |
62 |
* checked) |
63 |
*/ |
64 |
|
58 |
#ifndef lint |
65 |
#ifndef lint |
59 |
static const char rcsid[] = |
66 |
static const char rcsid[] = |
60 |
"$Id: nos-tun.c,v 1.5 1999/03/29 13:58:27 phk Exp $"; |
67 |
"$Id: nos-tun.c,v 1.5 1999/03/29 13:58:27 phk Exp $"; |
Lines 186-192
Link Here
|
186 |
return(1); |
193 |
return(1); |
187 |
} |
194 |
} |
188 |
|
195 |
|
189 |
void Finish(int signum) |
196 |
void Cleanup() |
190 |
{ |
197 |
{ |
191 |
int s; |
198 |
int s; |
192 |
|
199 |
|
Lines 227-234
Link Here
|
227 |
close(s); |
234 |
close(s); |
228 |
closing_tun: |
235 |
closing_tun: |
229 |
close(tun); |
236 |
close(tun); |
|
|
237 |
} |
238 |
|
239 |
void Finish() |
240 |
{ |
241 |
Cleanup(); |
230 |
closelog(); |
242 |
closelog(); |
231 |
exit(signum); |
243 |
} |
|
|
244 |
|
245 |
void sighandle(int signum) |
246 |
{ |
247 |
Finish(); |
248 |
exit(signum); |
249 |
} |
250 |
|
251 |
int Setup (char *devname, struct sockaddr *t_laddr, char *to_point, |
252 |
struct sockaddr *whereto, char *target, struct sockaddr_in *to, |
253 |
int protnum) |
254 |
{ |
255 |
if(tun_open(devname, t_laddr, to_point)) { |
256 |
closelog(); |
257 |
return(3); |
258 |
} |
259 |
|
260 |
to = (struct sockaddr_in *)&whereto; |
261 |
if(Set_address(target, to)) |
262 |
return(4); |
263 |
|
264 |
if ((net = socket(AF_INET, SOCK_RAW, protnum)) < 0) { |
265 |
syslog(LOG_ERR,"can't open socket - %m"); |
266 |
return(5); |
267 |
} |
268 |
|
269 |
if (connect(net,whereto,sizeof(struct sockaddr_in)) < 0 ) { |
270 |
syslog(LOG_ERR,"can't connect to target - %m"); |
271 |
close(net); |
272 |
return(6); |
273 |
} |
274 |
return(0); |
232 |
} |
275 |
} |
233 |
|
276 |
|
234 |
int main (int argc, char **argv) |
277 |
int main (int argc, char **argv) |
Lines 252-259
Link Here
|
252 |
fd_set rfds, wfds, efds; /* File descriptors for select() */ |
295 |
fd_set rfds, wfds, efds; /* File descriptors for select() */ |
253 |
int nfds; /* Return from select() */ |
296 |
int nfds; /* Return from select() */ |
254 |
|
297 |
|
|
|
298 |
ssize_t woff, wsize; /* offset & Return values for write */ |
299 |
int reset = 0; /* try to re-setup when writes fail */ |
300 |
int sleeplen = 60; /* how long to sleep before retrying */ |
301 |
int retries = 0; /* how many times to try to set up */ |
302 |
int werror = 0; /* write error flag */ |
303 |
int retcnt = 0; /* retry counter */ |
304 |
int ret; /* generic return value */ |
255 |
|
305 |
|
256 |
while ((c = getopt(argc, argv, "d:s:t:p:")) != -1) { |
306 |
while ((c = getopt(argc, argv, "d:s:t:p:r:w:")) != -1) { |
257 |
switch (c) { |
307 |
switch (c) { |
258 |
case 'd': |
308 |
case 'd': |
259 |
to_point = optarg; |
309 |
to_point = optarg; |
Lines 267-272
Link Here
|
267 |
case 'p': |
317 |
case 'p': |
268 |
protocol = optarg; |
318 |
protocol = optarg; |
269 |
break; |
319 |
break; |
|
|
320 |
case 'r': |
321 |
reset = 1; |
322 |
if (optarg[0] != ':') |
323 |
retries = atoi(optarg); |
324 |
break; |
325 |
case 'w': |
326 |
if (optarg[0] != ':') |
327 |
sleeplen = atoi(optarg); |
328 |
else |
329 |
usage(); |
330 |
break; |
270 |
} |
331 |
} |
271 |
} |
332 |
} |
272 |
argc -= optind; |
333 |
argc -= optind; |
Lines 292-326
Link Here
|
292 |
exit(2); |
353 |
exit(2); |
293 |
} |
354 |
} |
294 |
|
355 |
|
295 |
if(tun_open(devname, &t_laddr, to_point)) { |
|
|
296 |
closelog(); |
297 |
exit(3); |
298 |
} |
299 |
|
300 |
to = (struct sockaddr_in *)&whereto; |
301 |
if(Set_address(target, to)) |
302 |
Finish(4); |
303 |
|
304 |
if ((net = socket(AF_INET, SOCK_RAW, protnum)) < 0) { |
305 |
syslog(LOG_ERR,"can't open socket - %m"); |
306 |
Finish(5); |
307 |
} |
308 |
|
309 |
if (connect(net,&whereto,sizeof(struct sockaddr_in)) < 0 ) { |
310 |
syslog(LOG_ERR,"can't connect to target - %m"); |
311 |
close(net); |
312 |
Finish(6); |
313 |
} |
314 |
|
315 |
/* Demonize it */ |
356 |
/* Demonize it */ |
316 |
daemon(0,0); |
357 |
daemon(0,0); |
317 |
|
358 |
|
318 |
/* Install signal handlers */ |
359 |
/* Install signal handlers */ |
319 |
(void)signal(SIGHUP,Finish); |
360 |
(void)signal(SIGHUP,sighandle); |
320 |
(void)signal(SIGINT,Finish); |
361 |
(void)signal(SIGINT,sighandle); |
321 |
(void)signal(SIGTERM,Finish); |
362 |
(void)signal(SIGTERM,sighandle); |
|
|
363 |
|
364 |
/* Set up the tunnel */ |
365 |
if ((ret=Setup(devname, &t_laddr, to_point, &whereto, target, to, protnum))) { |
366 |
Finish(); |
367 |
exit(ret); |
368 |
} |
322 |
|
369 |
|
323 |
for (;;) { |
370 |
for (;;) { |
|
|
371 |
fortop: |
372 |
if (werror) { |
373 |
if (!reset) { |
374 |
syslog(LOG_ERR,"write error, exiting"); |
375 |
Finish(); |
376 |
exit(8); |
377 |
} |
378 |
/* We got a write error and we're trying to maintain the tunnel */ |
379 |
/* Clean out the old and try to set it up again */ |
380 |
do { |
381 |
Cleanup(); |
382 |
syslog(LOG_NOTICE,"waiting to retry tunnel setup"); |
383 |
sleep(sleeplen); |
384 |
retcnt++; |
385 |
} while((ret = Setup(devname, &t_laddr, to_point, &whereto, target, |
386 |
to, protnum)) |
387 |
&& (retcnt < retries) |
388 |
&& (werror < retries)); |
389 |
if (ret) { |
390 |
syslog(LOG_ERR,"unable to re-establish tunnel"); |
391 |
Finish(); |
392 |
exit(8); |
393 |
} else { |
394 |
retcnt = 0; /* werror does not get reset until we successfully write */ |
395 |
} |
396 |
} |
324 |
/* Set file descriptors for select() */ |
397 |
/* Set file descriptors for select() */ |
325 |
FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); |
398 |
FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); |
326 |
FD_SET(tun,&rfds); FD_SET(net,&rfds); |
399 |
FD_SET(tun,&rfds); FD_SET(net,&rfds); |
Lines 329-340
Link Here
|
329 |
if(nfds < 0) { |
402 |
if(nfds < 0) { |
330 |
syslog(LOG_ERR,"interrupted select"); |
403 |
syslog(LOG_ERR,"interrupted select"); |
331 |
close(net); |
404 |
close(net); |
332 |
Finish(7); |
405 |
Finish(); |
|
|
406 |
exit(7); |
333 |
} |
407 |
} |
334 |
if(nfds == 0) { /* Impossible ? */ |
408 |
if(nfds == 0) { /* Impossible ? */ |
335 |
syslog(LOG_ERR,"timeout in select"); |
409 |
syslog(LOG_ERR,"timeout in select"); |
336 |
close(net); |
410 |
close(net); |
337 |
Finish(8); |
411 |
Finish(); |
|
|
412 |
exit(8); |
338 |
} |
413 |
} |
339 |
|
414 |
|
340 |
|
415 |
|
Lines 346-352
Link Here
|
346 |
/* ... skip encapsulation headers ... */ |
421 |
/* ... skip encapsulation headers ... */ |
347 |
ipoff = (ip->ip_hl << 2); |
422 |
ipoff = (ip->ip_hl << 2); |
348 |
/* ... and write to tun-device */ |
423 |
/* ... and write to tun-device */ |
349 |
write(tun,buf+ipoff,len-ipoff); |
424 |
woff = 0; |
|
|
425 |
while (woff < (len-ipoff)) { |
426 |
if((wsize = write(tun, buf+ipoff+woff, len-ipoff-woff))<1) { |
427 |
syslog(LOG_ERR, "can't send - %m"); |
428 |
werror++; |
429 |
goto fortop; |
430 |
} else { |
431 |
werror = 0; |
432 |
} |
433 |
woff += wsize; |
434 |
} |
350 |
} |
435 |
} |
351 |
} |
436 |
} |
352 |
|
437 |
|
Lines 354-361
Link Here
|
354 |
/* Read from tun ... */ |
439 |
/* Read from tun ... */ |
355 |
len = read(tun, buf, sizeof(buf)); |
440 |
len = read(tun, buf, sizeof(buf)); |
356 |
/* ... and send to network */ |
441 |
/* ... and send to network */ |
357 |
if(send(net, buf, len,0) <= 0) { |
442 |
woff = 0; |
358 |
syslog(LOG_ERR,"can't send - %m"); |
443 |
while (woff < len) { |
|
|
444 |
if((wsize = send(net, buf+woff, len-woff,0)) < 1) { |
445 |
syslog(LOG_ERR,"can't send - %m"); |
446 |
werror++; |
447 |
goto fortop; |
448 |
} else { |
449 |
werror = 0; |
450 |
} |
451 |
woff += wsize; |
359 |
} |
452 |
} |
360 |
} |
453 |
} |
361 |
} |
454 |
} |
Lines 365-371
Link Here
|
365 |
usage() |
458 |
usage() |
366 |
{ |
459 |
{ |
367 |
fprintf(stderr, |
460 |
fprintf(stderr, |
368 |
"usage: nos_tun -t <tun_name> -s <source_addr> -d <dest_addr> -p <protocol_number> <target_addr>\n"); |
461 |
"usage: nos_tun -t <tun_name> -s <source_addr> -d <dest_addr> -p <protocol_number> [-r [retry count] -w <retry delay>] <target_addr>\n"); |
369 |
exit(1); |
462 |
exit(1); |
370 |
} |
463 |
} |