View | Details | Raw Unified | Return to bug 13309 | Differences between
and this patch

Collapse All | Expand All

(-)nos-tun.c (-32 / +125 lines)
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
}

Return to bug 13309