Главная страница


ru.unix.bsd

 
 - RU.UNIX.BSD ------------------------------------------------------------------
 From : Vadim Goncharov                      2:5020/400     04 Mar 2008  12:00:53
 To : Alex Semenyaka
 Subject : Re: mpd: traffic shaping & ttl changing
 -------------------------------------------------------------------------------- 
 
 Hi Alex Semenyaka! 
 
 On Mon, 03 Mar 2008 08:32:38 +0300; Alex Semenyaka wrote about 'mpd: traffic
 shaping & ttl changing':
 
  DM>>> Именно этим и плох. Чтобы не было никаких роутеров-мыльниц, wifi,
  DM>>> случайно поставленных галочек "разрешить другим пользователям
  DM>>> сети..." У меня не интернет через VPN, у меня просто VPN.
  EG>> Можно тупо блокировать исходящие от клиента запросы с "неправильным"
  EG>> ttl, man ipfw про ipttl.
  AS> Тут человеку законно хочется не проверять пришедший ttl, а управлять своим 
  AS> (что в Linuxе легко делается в iptables, замечу). Какие-то патчи для этого 
  AS> были на http://totalterror.net/src/, но надо проверять их живость.
 
 Сейчас в ipfw@ обсуждают приделывание функционала, который позволял бы менять
 tos, dscp, ttl и df-бит. А так - ну я вон когда мне надо было, быстренько на
 коленке переделал divert-демона, который умеет фичи iptables по этой части:
 
 $ cat ttlchgd.c
 /*-
  * Copyright (c) 2000 Ruslan Ermilov
  * Copyright (c) 2006 Vadim Goncharov
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * $Id$
  */
 
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <paths.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <sysexits.h>
 
 #define MAXPIDLEN  9  /* Max decimal pid length in characters. */
 
 char pidfile[MAXPATHLEN] = { '\0' };
 char *prog = NULL;
 
 static void
 sigterm_handler(int sig)
 {
 
   (void)unlink(pidfile);
   exit(0);
 }
 
 /*
  * Do the "paper work".
  *  - fork and detach from terminal, if needed.
  *  - save my own pid in /var/run/$0.{port#}.pid.
  */
 void 
 okay(int pn, int detach)
 {
   int pf;
   char *p, strpid[MAXPIDLEN + 1];
   pid_t pid;
 
   if (pidfile[0] == '\0') {
    p = (char *)rindex(prog, '/');
    p = (p == NULL) ? prog : p+1 ;
 
    snprintf(pidfile, sizeof(pidfile)-1,
       "%s%s.%d.pid", _PATH_VARRUN, p, pn);
   }
 
   pf = open(pidfile, O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK, 0644);
 
   /*
    * We couldn't create pid file
    */
   if (pf == -1) {
    if (errno == EEXIST) {
       /*
        * If it is because it's already exists
        */
       bzero(strpid, MAXPIDLEN + 1);
       fprintf(stderr, "PID file already exists!\n");
 
       /*
        * Try to read the PID stored in the existing file
        */
       pf = open(pidfile, O_RDONLY);
       if (pf == -1) {
        perror("Error opening PID file for reading");
        exit(EX_IOERR);
       }
       if (read(pf, strpid, MAXPIDLEN) < 0) {
        perror("Error reading PID file");
        exit(EX_IOERR);
       }
       pid = atol(strpid);
       close(pf);
 
       /*
        * We found PID, try to determine, whether process
        * is running
        */
       if (kill(pid, 0) == 0) {
        /*
         * Signal is delivered, though process with
         * such PID exists
         */
        fprintf(stderr, "%s already running with PID=%d, exiting...\n", prog,
 pid);
        exit(1);
       } else {
        /*
         * It seems, like the process is killed, so
         * we can proceed...
         */
        fprintf(stderr, "Stale PID file, overwriting...\n");
        pf = open(pidfile, O_WRONLY | O_TRUNC | O_EXLOCK);
        if (pf == -1) {
           perror("Error opening PID file for writing");
           exit(EX_IOERR);
        }
       }
    } else {
       perror("Error creating PID file");
       exit(EX_IOERR);
    }
   }
 
   if (detach) {
    if (daemon(0, 0) != 0) {
       close(pf);
       (void)unlink(pidfile);
       perror("daemon");
       exit(EX_OSERR);
    }
   }
 
   /*
    * Set signal handlers and system behaviour.  This must be done
    * before saving PID to prevent small, but possible race condition
    * when another instance failed to create PID, reads it and tries
    * to send signal to us.
    */
   siginterrupt(SIGTERM, 1);
   siginterrupt(SIGHUP, 1);
 
   /* Ignore 0th signal, or process may be killed with it by default... */
   signal(0, SIG_IGN);
   signal(SIGINT, sigterm_handler);
   signal(SIGTERM, sigterm_handler);
 
   /* Save our PID to pidfile. */
   bzero(strpid, MAXPIDLEN + 1);
   snprintf(strpid, MAXPIDLEN, "%ld\n", getpid());
   if (write(pf, strpid, strlen(strpid)) < 0) {
    perror("Error writing PID file");
    exit(EX_IOERR);
   }
   close(pf);
 }
 
 void
 usage(void)
 {
 
   fprintf(stderr, "usage: %s [-v] [-i] -p port ttl\n", prog);
   exit(1);
 }
 
 int
 main(int argc, char *argv[])
 {
   char pkt[IP_MAXPACKET];
   ssize_t pktlen, hlen;
   struct ip *pip = (struct ip *)pkt;
   struct sockaddr_in sin;
   socklen_t sinlen;
   int s;
   int pflag = 0;
   int verbose = 0;
   int increment = 0;
   u_short port = 0;
   int ttl;
   unsigned long sum;
   uint16_t old;
   char ch;
   fd_set fdset;
 
   prog = argv[0];
 
   while ((ch = getopt(argc, argv, "ip:v")) != -1)
    switch (ch) {
    case 'i':
       increment = 1;
       break;
    case 'p':
       port = htons(atoi(optarg));
       pflag++;
       break;
    case 'v':
       verbose = 1;
       break;
    case '?':
    default:
       usage();
       /* NOTREACHED */
    }
 
   ttl = atoi(argv[optind]);
 
   if (!pflag || ((argc - optind) != 1)) {
    usage();
    /* NOTREACHED */
   }
 
   if ((s = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) {
    err(1, "can't create divert socket");
    /* NOTREACHED */
   }
 
   bzero(&sin, sizeof(sin));
   sin.sin_family = PF_INET;
   sin.sin_addr.s_addr = INADDR_ANY;
   sin.sin_port = port;
 
   if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
    err(1, "can't bind divert socket");
    /* NOTREACHED */
   }
 
   okay(port, !verbose);
 
   for (;;) {
    FD_ZERO(&fdset);
    FD_SET(s, &fdset);
    if (select(s + 1, &fdset, (fd_set *)NULL, (fd_set *)NULL, (struct timeval
 *)NULL) == -1) {
       if (errno == EINTR)
        continue;
       perror("select");
       exit(EX_OSERR);
    }
 
    if (!FD_ISSET(s, &fdset))
       continue;
 
    sinlen = sizeof(sin);
 
    if ((pktlen = recvfrom(s, pkt, sizeof(pkt), 0,
               (struct sockaddr *)&sin, &sinlen)) == -1)
       if (errno != EINTR) {
        warn("read from divert socket failed");
        continue;
       }
 
    if (verbose) {
       fprintf(stderr, "recvfrom(%d) = %d\n", s, pktlen);
       fprintf(stderr, "packet: ip_src=%s ", inet_ntoa(pip->ip_src));
       fprintf(stderr, "ip_dst=%s proto=%d ipid=%d ttl=%d\n",
           inet_ntoa(pip->ip_dst),
           pip->ip_p,
           ntohs(pip->ip_id),
           pip->ip_ttl);
    }
 
    /* Save old TTL bytes for checksum recomputation. */
    old = ntohs(*(uint16_t*)&pip->ip_ttl);
 
    /* Actual work - change TTL, with saturation arithmetics. */
    if (!increment)
       pip->ip_ttl = ttl;  /* Unconditionally set. */
    else if ((long)(pip->ip_ttl + ttl) > 255)
       pip->ip_ttl = 255;
    else if ((long)(pip->ip_ttl + ttl) < 0)
       pip->ip_ttl = 0;
    else
       pip->ip_ttl += ttl;
 
    /* Adjust IP header checksum, as in RFC 1141. */
    sum = old + (~ntohs(*(unsigned short *)&pip->ip_ttl) & 0xffff);
    sum += ntohs(pip->ip_sum);
    sum = (sum & 0xffff) + (sum>>16);
    pip->ip_sum = htons(sum + (sum>>16));
 
    /* XXX Fix boundary zero case (see RFC 1624). */
    if (pip->ip_sum == 0xffff)
       pip->ip_sum = 0;
 
    if (verbose)
       fprintf(stderr, "new ttl = %d\n", pip->ip_ttl);
 
    if (sendto(s, pkt, pktlen, 0,
        (struct sockaddr *)&sin, sinlen) == -1)
       warn("write to divert socket failed");
   }
 }
 
 -- 
 WBR, Vadim Goncharov. ICQ#166852181       mailto:vadim_nuclight@mail.ru
 [Moderator of RU.ANTI-ECOLOGY][FreeBSD][http://antigreen.org][LJ:/nuclight]
 --- slrn/0.9.8.1 on FreeBSD 6.2/i386
  * Origin: Nuclear Lightning @ Tomsk, TPU AVTF Hostel (2:5020/400@fidonet)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Re: mpd: traffic shaping & ttl changing   Eugene Grosbein   02 Mar 2008 20:38:02 
 Re: mpd: traffic shaping & ttl changing   Mykola Dzham   03 Mar 2008 01:09:00 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   03 Mar 2008 09:32:38 
 Re: mpd: traffic shaping & ttl changing   Eugene Grosbein   03 Mar 2008 14:32:54 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   03 Mar 2008 17:56:42 
 Re: mpd: traffic shaping & ttl changing   Eugene Grosbein   03 Mar 2008 23:33:22 
 Re: mpd: traffic shaping & ttl changing   Vadim Goncharov   04 Mar 2008 12:00:53 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   06 Mar 2008 03:10:06 
 Re: mpd: traffic shaping & ttl changing   Vadim Goncharov   07 Mar 2008 09:54:28 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   07 Mar 2008 14:40:58 
 mpd: traffic shaping & ttl changing   Slawa Olhovchenkov   07 Mar 2008 14:55:26 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   07 Mar 2008 16:25:02 
 mpd: traffic shaping & ttl changing   Slawa Olhovchenkov   07 Mar 2008 17:04:40 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   07 Mar 2008 18:01:34 
 mpd: traffic shaping & ttl changing   Slawa Olhovchenkov   07 Mar 2008 21:11:22 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   09 Mar 2008 16:19:28 
 mpd: traffic shaping & ttl changing   Slawa Olhovchenkov   09 Mar 2008 16:33:48 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   09 Mar 2008 18:19:24 
 mpd: traffic shaping & ttl changing   Slawa Olhovchenkov   09 Mar 2008 18:39:52 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   10 Mar 2008 12:16:22 
 Re: mpd: traffic shaping & ttl changing   Vadim Goncharov   11 Mar 2008 19:57:49 
 Re: mpd: traffic shaping & ttl changing   Vadim Goncharov   07 Mar 2008 16:03:47 
 mpd: traffic shaping & ttl changing   Alex Semenyaka   07 Mar 2008 16:24:42 
 Re: mpd: traffic shaping & ttl changing   Vadim Goncharov   11 Mar 2008 19:50:44 
Архивное /ru.unix.bsd/336491ec65266.html, оценка 3 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional