Exemplo n.º 1
0
void
cleanup(void)
{
#ifndef __APPLE__
  if (timestamp) stamptime();
  ssystem("ifconfig %s down", tundev);
#ifndef linux
  ssystem("sysctl -w net.ipv6.conf.all.forwarding=1");
#endif
  /* ssystem("arp -d %s", ipaddr); */
  if (timestamp) stamptime();
  ssystem("netstat -nr"
	  " | awk '{ if ($2 == \"%s\") print \"route delete -net \"$1; }'"
	  " | sh",
	  tundev);
#else
  {
    char *  itfaddr = strdup(ipaddr);
    char *  prefix = index(itfaddr, '/');
    if (timestamp) stamptime();
    ssystem("ifconfig %s inet6 %s remove", tundev, ipaddr);
    if (timestamp) stamptime();
    ssystem("ifconfig %s down", tundev);
    if ( prefix != NULL ) *prefix = '\0';
    ssystem("route delete -inet6 %s", itfaddr);
    free(itfaddr);
  }
#endif
}
Exemplo n.º 2
0
void delAddress(const char * ifname, const char * ipaddr)
{
	char tmpaddr[42];

	strncpy(tmpaddr,ipaddr,sizeof(tmpaddr));
	strtok(tmpaddr,"/"); // Remove possible prefix length.
	if (timestamp) stamptime();	

	if(osVersionInfo.dwMajorVersion < 6){ // < Windows Vista (i.e., Windows XP; check if this command is ok for Windows Server 2003 too).
		char * substr;	
		
		execProcess(NULL,"netsh interface ipv6 delete address \"%s\" %s",if_name,tmpaddr);
		if (timestamp) stamptime();
		substr = strtok(NULL,"/");
		if(substr == NULL){ // A prefix length is not specified.
			// Use a 64 bit prefix
			strcat(tmpaddr,"/64");	
			execProcess(NULL,"netsh interface ipv6 delete route %s \"%s\"",tmpaddr,if_name);
		}
		else {
			execProcess(NULL,"netsh interface ipv6 delete route %s \"%s\"",ipaddr,if_name);
		}
		
	}
	else{
		strtok(tmpaddr,"/"); // Remove possible prefix length.
		execProcess(NULL,"netsh interface ipv6 delete address \"%s\" %s",if_name,tmpaddr);
	}
	
}
Exemplo n.º 3
0
void addLoWPANRoute(const char * ifname, const char * net, const char * gw)
{
	DWORD exitCode = -1;
	if (timestamp) stamptime();
	execProcess(&exitCode,"netsh interface ipv6 add route %s/64 \"%s\" %s", net, if_name, gw);
    if(exitCode==0){
        clean_route = true;
    }
    else {
	  if (timestamp) stamptime();
      fprintf(stderr, "WARNING: subprocess exited with code %ld\n", exitCode);
    }
}
Exemplo n.º 4
0
	void
cleanup(void)
{
	if (timestamp) stamptime();
	ssystem("ifconfig %s down", tundev);
#ifndef linux
	ssystem("sysctl -w net.ipv6.conf.all.forwarding=1");
#endif
	/* ssystem("arp -d %s", ipaddr); */
	if (timestamp) stamptime();
	ssystem("netstat -nr"
			" | awk '{ if ($2 == \"%s\") print \"route delete -net \"$1; }'"
			" | sh",
			tundev);
}
Exemplo n.º 5
0
void addNeighbor(const char * ifname, const char * neighb, const char * neighb_mac)
{
	DWORD exitCode = -1;

	if(osVersionInfo.dwMajorVersion >= 6){
		if (timestamp) stamptime();
        execProcess(&exitCode,"netsh interface ipv6 add neighbor \"%s\" %s \"%s\"", if_name, neighb, neighb_mac);
        if(exitCode==0){
            clean_neighb = true;
        }
        else {
		  if (timestamp) stamptime();
          fprintf(stderr, "WARNING: subprocess exited with code %ld\n", exitCode);
        }
	}
}
Exemplo n.º 6
0
void
sigcleanup(int signo)
{
	if (timestamp) stamptime();
	fprintf(stderr, "signal %d\n", signo);
	exit(0);			/* exit(0) will call cleanup() */
}
Exemplo n.º 7
0
void
sigalarm(int signo)
{
	if(!mac_received){
		if (timestamp) stamptime();
		fprintf(stderr, "Bridge/Router not found!\n");
		exit(2);
	}
}
Exemplo n.º 8
0
	void
ifconf(const char *tundev, const char *ipaddr)
{
#ifdef linux
	if (timestamp) stamptime();
	ssystem("ifconfig %s inet `hostname` up", tundev);
	if (timestamp) stamptime();
	ssystem("ifconfig %s add %s", tundev, ipaddr);
#else
	if (timestamp) stamptime();
	ssystem("ifconfig %s inet `hostname` %s up", tundev, ipaddr);
	if (timestamp) stamptime();
	ssystem("sysctl -w net.inet.ip.forwarding=1");
#endif /* !linux */

	if (timestamp) stamptime();
	ssystem("ifconfig %s\n", tundev);
}
Exemplo n.º 9
0
void addAddress(const char * ifname, const char * ipaddr)
{
	DWORD exitCode = -1;

	if(osVersionInfo.dwMajorVersion < 6){ // < Windows Vista (i.e., Windows XP; check if this command is ok for Windows Server 2003 too).
		char * substr;
		char tmpaddr[44];

		strncpy(tmpaddr,ipaddr,sizeof(tmpaddr));

		strtok(tmpaddr,"/"); // Remove possible prefix length.
		if (timestamp) stamptime();
		execProcess(&exitCode,"netsh interface ipv6 add address \"%s\" %s",if_name,tmpaddr);
		substr = strtok(NULL,"/");
		if(substr == NULL){ // A prefix length is not specified.
			// Use a 64 bit prefix
			strcat(tmpaddr,"/64");
			if (timestamp) stamptime();
			execProcess(NULL,"netsh interface ipv6 add route %s \"%s\"",tmpaddr,if_name);
		}
		else {
			if (timestamp) stamptime();
			execProcess(NULL,"netsh interface ipv6 add route %s \"%s\"",ipaddr,if_name);
		}
		
	}
	else{
		if (timestamp) stamptime();
		execProcess(&exitCode,"netsh interface ipv6 add address \"%s\" %s",if_name,ipaddr);
	}
	if(exitCode==0){
		clean_addr = true;
	}
	else {
	  if (timestamp) stamptime();
	  fprintf(stderr, "WARNING: subprocess exited with code %ld\n", exitCode);
	}
}
Exemplo n.º 10
0
void
write_to_serial(int outfd, void *inbuf, int len)
{
  u_int8_t *p = inbuf;
  int i;

  if(verbose>2) {
    if (timestamp) stamptime();
    printf("Packet from TUN of length %d - write SLIP\n", len);
    if (verbose>4) {
#if WIRESHARK_IMPORT_FORMAT
      printf("0000");
	  for(i = 0; i < len; i++) printf(" %02x", p[i]);
#else
      printf("         ");
      for(i = 0; i < len; i++) {
        printf("%02x", p[i]);
        if((i & 3) == 3) printf(" ");
        if((i & 15) == 15) printf("\n         ");
      }
#endif
      printf("\n");
    }
  }

  /* It would be ``nice'' to send a SLIP_END here but it's not
   * really necessary.
   */
  /* slip_send(outfd, SLIP_END); */

  for(i = 0; i < len; i++) {
    switch(p[i]) {
    case SLIP_END:
      slip_send(outfd, SLIP_ESC);
      slip_send(outfd, SLIP_ESC_END);
      break;
    case SLIP_ESC:
      slip_send(outfd, SLIP_ESC);
      slip_send(outfd, SLIP_ESC_ESC);
      break;
    default:
      slip_send(outfd, p[i]);
      break;
    }
  }
  slip_send(outfd, SLIP_END);
  PROGRESS("t");
}
Exemplo n.º 11
0
void delNeighbor(const char * ifname, const char * neighb)
{
	if (timestamp) stamptime();
    execProcess(NULL,"netsh interface ipv6 delete neighbor \"%s\" %s", if_name, neighb);
}
Exemplo n.º 12
0
void delLoWPANRoute(const char * ifname, const char * net)
{
	if (timestamp) stamptime();
    execProcess(NULL,"netsh interface ipv6 delete route %s/64 \"%s\"", net, if_name);
}
Exemplo n.º 13
0
void
ifconf(const char *tundev, const char *ipaddr)
{
#ifdef __linux__

    if (timestamp) {
        stamptime();
    }

    ssystem("ifconfig %s inet `hostname` up", tundev);

    if (timestamp) {
        stamptime();
    }

    ssystem("ifconfig %s add %s", tundev, ipaddr);

    /* radvd needs a link local address for routing */
#if 0
    /* fe80::1/64 is good enough */
    ssystem("ifconfig %s add fe80::1/64", tundev);
#elif 1
    /* Generate a link local address a la sixxs/aiccu */
    /* First a full parse, stripping off the prefix length */
    {
        char lladdr[40];
        char c, *ptr = (char *)ipaddr;
        uint16_t digit, ai, a[8], cc, scc, i;

        for (ai = 0; ai < 8; ai++) {
            a[ai] = 0;
        }

        ai = 0;
        cc = scc = 0;

        while ((c = *(ptr++))) {
            if (c == '/') {
                break;
            }

            if (c == ':') {
                if (cc) {
                    scc = ai;
                }

                cc = 1;

                if (++ai > 7) {
                    break;
                }
            }
            else {
                cc = 0;
                digit = c - '0';

                if (digit > 9) {
                    digit = 10 + (c & 0xdf) - 'A';
                }

                a[ai] = (a[ai] << 4) + digit;
            }
        }

        /* Get # elided and shift what's after to the end */
        cc = 8 - ai;

        for (i = 0; i < cc; i++) {
            if ((8 - i - cc) <= scc) {
                a[7 - i] = 0;
            }
            else {
                a[7 - i] = a[8 - i - cc];
                a[8 - i - cc] = 0;
            }
        }

        sprintf(lladdr, "fe80::%x:%x:%x:%x", a[1] & 0xfefd, a[2], a[3], a[7]);

        if (timestamp) {
            stamptime();
        }

        ssystem("ifconfig %s add %s/64", tundev, lladdr);
    }
#endif /* link local */
#elif defined(__APPLE__)
    {
        char *itfaddr = strdup(ipaddr);
        char *prefix = index(itfaddr, '/');

        if (prefix != NULL) {
            *prefix = '\0';
            prefix++;
        }
        else {
            prefix = "64";
        }

        if (timestamp) {
            stamptime();
        }

        ssystem("ifconfig %s inet6 up", tundev);

        if (timestamp) {
            stamptime();
        }

        ssystem("ifconfig %s inet6 %s add", tundev, ipaddr);

        if (timestamp) {
            stamptime();
        }

        ssystem("sysctl -w net.inet6.ip6.forwarding=1");
        free(itfaddr);
    }
#else

    if (timestamp) {
        stamptime();
    }

    ssystem("ifconfig %s inet `hostname` %s up", tundev, ipaddr);

    if (timestamp) {
        stamptime();
    }

    ssystem("sysctl -w net.inet.ip.forwarding=1");
#endif /* !__linux__ */

    if (timestamp) {
        stamptime();
    }

    ssystem("ifconfig %s\n", tundev);
}
Exemplo n.º 14
0
/*
 * Read from serial, when we have a packet write it to tun. No output
 * buffering, input buffered by stdio.
 */
	void
serial_to_tun(FILE *inslip, int outfd)
{
	static union {
		unsigned char inbuf[2000];
	} uip;
	static unsigned int inbufptr = 0;
	int ret;
	unsigned int i;
	unsigned char c;

#ifdef linux
	ret = fread(&c, 1, 1, inslip);
	if(ret == -1 || ret == 0) err(1, "serial_to_tun: read");
	goto after_fread;
#endif

read_more:
	if(inbufptr >= sizeof(uip.inbuf)) {
		inbufptr = 0;
		if(timestamp) stamptime();
		fprintf(stderr, "*** dropping too large packet\n");
	}
	ret = fread(&c, 1, 1, inslip);
#ifdef linux
after_fread:
#endif
	if(ret == -1) {
		err(1, "serial_to_tun: read");
	}
	if(ret == 0) {
		clearerr(inslip);
		return;
	}
	/*  fprintf(stderr, ".");*/
	switch(c) {
		case SLIP_END:
			if(inbufptr > 0) {
				if(uip.inbuf[0] == '!') {
					if (uip.inbuf[1] == 'M') {
						/* Read gateway MAC address and autoconfigure tap0 interface */
						char macs[24];
						int i, pos;
						for(i = 0, pos = 0; i < 16; i++) {
							macs[pos++] = uip.inbuf[2 + i];
							if ((i & 1) == 1 && i < 14) {
								macs[pos++] = ':';
							}
						}
						if(timestamp) stamptime();
						macs[pos] = '\0';
						//	  printf("*** Gateway's MAC address: %s\n", macs);
						fprintf(stderr,"*** Gateway's MAC address: %s\n", macs);
						if (timestamp) stamptime();
						ssystem("ifconfig %s down", tundev);
						if (timestamp) stamptime();
						ssystem("ifconfig %s hw ether %s", tundev, &macs[6]);
						if (timestamp) stamptime();
						ssystem("ifconfig %s up", tundev);
					} else if(uip.inbuf[1] == 'P') {
						/* Prefix info requested */
						struct in6_addr addr;
						int i;
						char *s = strchr(ipaddr, '/');
						if(s != NULL) {
							*s = '\0';
						}
						inet_pton(AF_INET6, ipaddr, &addr);
						if(timestamp)
							stamptime();
						fprintf(stderr,"*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
								ipaddr,
								addr.s6_addr[0], addr.s6_addr[1],
								addr.s6_addr[2], addr.s6_addr[3],
								addr.s6_addr[4], addr.s6_addr[5],
								addr.s6_addr[6], addr.s6_addr[7]);
						slip_send(slipfd, '!');
						slip_send(slipfd, 'P');
						for (i = 0; i < 8; i++) {
							//slip_send(slipfd, addr.s6_addr[i]);

							switch (addr.s6_addr[i]) {
								case SLIP_END:
									slip_send(outfd, SLIP_ESC);
									slip_send(outfd, SLIP_ESC_END);
									break;
								case SLIP_ESC:
									slip_send(outfd, SLIP_ESC);
									slip_send(outfd, SLIP_ESC_ESC);
									break;
								default:
									slip_send(outfd, addr.s6_addr[i]);
									break;
							}
						}
						slip_send(slipfd, SLIP_END);

						slip_flushbuf(slipfd); // DEBUG
					}
#define DEBUG_LINE_MARKER '\r'
				} else if(uip.inbuf[0] == DEBUG_LINE_MARKER) {
					fwrite(uip.inbuf + 1, inbufptr - 1, 1, stdout);
				} else if(is_sensible_string(uip.inbuf, inbufptr)) {
					if(verbose==1) {   /* strings already echoed below for verbose>1 */
						if (timestamp) stamptime();
						fwrite(uip.inbuf, inbufptr, 1, stdout);
					}
				} else {
					if(verbose>2) {
						if (timestamp) stamptime();
						printf("Packet from SLIP of length %d - write TUN\n", inbufptr);
						if (verbose>4) {
							printf("         ");
							for(i = 0; i < inbufptr; i++) {
								printf("%02x", uip.inbuf[i]);
								if((i & 3) == 3) {
									printf(" ");
								}
								if((i & 15) == 15)
									printf("\n         ");
							}
							printf("\n");
						}
					}
					if(write(outfd, uip.inbuf, inbufptr) != inbufptr) {
						err(1, "serial_to_tun: write");
					}
				}
				inbufptr = 0;
			}
			break;

		case SLIP_ESC:
			if(fread(&c, 1, 1, inslip) != 1) {
				clearerr(inslip);
				/* Put ESC back and give up! */
				ungetc(SLIP_ESC, inslip);
				return;
			}

			switch(c) {
				case SLIP_ESC_END:
					c = SLIP_END;
					break;
				case SLIP_ESC_ESC:
					c = SLIP_ESC;
					break;
			}
			/* FALLTHROUGH */
		default:
			uip.inbuf[inbufptr++] = c;

			/* Echo lines as they are received for verbose=2,3,5+ */
			/* Echo all printable characters for verbose==4 */
			if((verbose==2) || (verbose==3) || (verbose>4)) {
				if(c=='\n') {
					if(is_sensible_string(uip.inbuf, inbufptr)) {
						if (timestamp) stamptime();
						fwrite(uip.inbuf, inbufptr, 1, stdout);
						inbufptr=0;
					}
				}
			} else if(verbose==4) {
				if(c == 0 || c == '\r' || c == '\n' || c == '\t' || (c >= ' ' && c <= '~')) {
					fwrite(&c, 1, 1, stdout);
					if(c=='\n') if(timestamp) stamptime();
				}
			}

			break;
	}

	goto read_more;
}
Exemplo n.º 15
0
	int
main(int argc, char **argv)
{
	int c;
	int tunfd, maxfd;
	int ret;
	fd_set rset, wset;
	FILE *inslip;
	const char *siodev = NULL;
	const char *host = NULL;
	const char *port = NULL;
	const char *prog;
	int baudrate = -2;
	int tap = 0;
	slipfd = 0;

	prog = argv[0];
	setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */

	while((c = getopt(argc, argv, "B:D:Lhs:t:v::d::a:p:T")) != -1) {
		switch(c) {
			case 'B':
				baudrate = atoi(optarg);
				break;

			case 'L':
				timestamp=1;
				break;

			case 's':
				if(strncmp("/dev/", optarg, 5) == 0) {
					siodev = optarg + 5;
				} else {
					siodev = optarg;
				}
				break;

			case 't':
				if(strncmp("/dev/", optarg, 5) == 0) {
					strncpy(tundev, optarg + 5, sizeof(tundev));
				} else {
					strncpy(tundev, optarg, sizeof(tundev));
				}
				break;

			case 'a':
				host = optarg;
				break;

			case 'p':
				port = optarg;
				break;

			case 'd':
				basedelay = 10;
				if (optarg) basedelay = atoi(optarg);
				break;

			case 'v':
				verbose = 2;
				if (optarg) verbose = atoi(optarg);
				break;

			case 'T':
				tap = 1;
				break;

			case '?':
			case 'h':
			default:
				fprintf(stderr,"usage:  %s [options] ipaddress\n", prog);
				fprintf(stderr,"example: tunslip6 -L -v2 -s ttyUSB1 aaaa::1/64\n");
				fprintf(stderr,"Options are:\n");
				fprintf(stderr," -B baudrate    9600,19200,38400,57600,115200 (default)\n");
				fprintf(stderr," -L             Log output format (adds time stamps)\n");
				fprintf(stderr," -s siodev      Serial device (default /dev/ttyUSB0)\n");
				fprintf(stderr," -T             Make tap interface (default is tun interface)\n");
				//fprintf(stderr," -t tundev      Name of interface (default tap0 or tun0)\n");
				fprintf(stderr," -t tundev      Name of interface\n");
				fprintf(stderr," -v[level]      Verbosity level\n");
				fprintf(stderr,"    -v0         No messages\n");
				fprintf(stderr,"    -v1         Encapsulated SLIP debug messages (default)\n");
				fprintf(stderr,"    -v2         Printable strings after they are received\n");
				fprintf(stderr,"    -v3         Printable strings and SLIP packet notifications\n");
				fprintf(stderr,"    -v4         All printable characters as they are received\n");
				fprintf(stderr,"    -v5         All SLIP packets in hex\n");
				fprintf(stderr,"    -v          Equivalent to -v3\n");
				fprintf(stderr," -d[basedelay]  Minimum delay between outgoing SLIP packets.\n");
				fprintf(stderr,"                Actual delay is basedelay*(#6LowPAN fragments) milliseconds.\n");
				fprintf(stderr,"                -d is equivalent to -d10.\n");
				fprintf(stderr," -a serveraddr  \n");
				fprintf(stderr," -p serverport  \n");
				exit(1);
				break;
		}
	}
	argc -= (optind - 1);
	argv += (optind - 1);

	if(argc != 2 && argc != 3) {
		err(1, "usage: %s [-B baudrate] [-L] [-s siodev] [-t tundev] [-T] [-v verbosity] [-d delay] [-a serveraddress] [-p serverport] ipaddress", prog);
	}
	ipaddr = argv[1];

	switch(baudrate) {
		case -2:
			break;			/* Use default. */
		case 9600:
			b_rate = B9600;
			break;
		case 19200:
			b_rate = B19200;
			break;
		case 38400:
			b_rate = B38400;
			break;
		case 57600:
			b_rate = B57600;
			break;
		case 115200:
			b_rate = B115200;
			break;
		default:
			err(1, "unknown baudrate %d", baudrate);
			break;
	}

#if 0
	if(*tundev == '\0') {
		/* Use default. */
		if(tap) {
			strcpy(tundev, "tap0");
		} else {
			strcpy(tundev, "tun0");
		}
	}
#endif
	if(host != NULL) {
		struct addrinfo hints, *servinfo, *p;
		int rv;
		char s[INET6_ADDRSTRLEN];

		if(port == NULL) {
			port = "60001";
		}

		memset(&hints, 0, sizeof hints);
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;

		if((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
			err(1, "getaddrinfo: %s", gai_strerror(rv));
		}

		/* loop through all the results and connect to the first we can */
		for(p = servinfo; p != NULL; p = p->ai_next) {
			if((slipfd = socket(p->ai_family, p->ai_socktype,
							p->ai_protocol)) == -1) {
				perror("client: socket");
				continue;
			}

			if(connect(slipfd, p->ai_addr, p->ai_addrlen) == -1) {
				close(slipfd);
				perror("client: connect");
				continue;
			}
			break;
		}

		if(p == NULL) {
			err(1, "can't connect to ``%s:%s''", host, port);
		}

		fcntl(slipfd, F_SETFL, O_NONBLOCK);

		inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
				s, sizeof(s));
		fprintf(stderr, "slip connected to ``%s:%s''\n", s, port);

		/* all done with this structure */
		freeaddrinfo(servinfo);

	} else {
		if(siodev != NULL) {
			slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
			if(slipfd == -1) {
				err(1, "can't open siodev ``/dev/%s''", siodev);
			}
		} else {
			static const char *siodevs[] = {
				"ttyUSB0", "cuaU0", "ucom0" /* linux, fbsd6, fbsd5 */
			};
			int i;
			for(i = 0; i < 3; i++) {
				siodev = siodevs[i];
				slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
				if(slipfd != -1) {
					break;
				}
			}
			if(slipfd == -1) {
				err(1, "can't open siodev");
			}
		}
		if (timestamp) stamptime();
		fprintf(stderr, "********SLIP started on ``/dev/%s''\n", siodev);
		stty_telos(slipfd);
	}
	slip_send(slipfd, SLIP_END);
	inslip = fdopen(slipfd, "r");
	if(inslip == NULL) err(1, "main: fdopen");

	tunfd = tun_alloc(tundev, tap);
	if(tunfd == -1) err(1, "main: open");
	if (timestamp) stamptime();
	fprintf(stderr, "opened %s device ``/dev/%s''\n",
			tap ? "tap" : "tun", tundev);

	atexit(cleanup);
	signal(SIGHUP, sigcleanup);
	signal(SIGTERM, sigcleanup);
	signal(SIGINT, sigcleanup);
	signal(SIGALRM, sigalarm);
	ifconf(tundev, ipaddr);

	while(1) {
		maxfd = 0;
		FD_ZERO(&rset);
		FD_ZERO(&wset);

		/* do not send IPA all the time... - add get MAC later... */
		/*     if(got_sigalarm) { */
		/*       /\* Send "?IPA". *\/ */
		/*       slip_send(slipfd, '?'); */
		/*       slip_send(slipfd, 'I'); */
		/*       slip_send(slipfd, 'P'); */
		/*       slip_send(slipfd, 'A'); */
		/*       slip_send(slipfd, SLIP_END); */
		/*       got_sigalarm = 0; */
		/*     } */

		if(!slip_empty()) {		/* Anything to flush? */
			FD_SET(slipfd, &wset);
		}

		FD_SET(slipfd, &rset);	/* Read from slip ASAP! */
		if(slipfd > maxfd) maxfd = slipfd;

		/* We only have one packet at a time queued for slip output. */
		if(slip_empty()) {
			FD_SET(tunfd, &rset);
			if(tunfd > maxfd) maxfd = tunfd;
		}

		ret = select(maxfd + 1, &rset, &wset, NULL, NULL);
		if(ret == -1 && errno != EINTR) {
			err(1, "select");
		} else if(ret > 0) {
			if(FD_ISSET(slipfd, &rset)) {
				serial_to_tun(inslip, tunfd);
			}

			if(FD_ISSET(slipfd, &wset)) {
				slip_flushbuf(slipfd);
				sigalarm_reset();
			}

			/* Optional delay between outgoing packets */
			/* Base delay times number of 6lowpan fragments to be sent */
			if(delaymsec) {
				struct timeval tv;
				int dmsec;
				gettimeofday(&tv, NULL) ;
				dmsec=(tv.tv_sec-delaystartsec)*1000+tv.tv_usec/1000-delaystartmsec;
				if(dmsec<0) delaymsec=0;
				if(dmsec>delaymsec) delaymsec=0;
			}

			if(delaymsec==0) {
				//int size;

				if(slip_empty() && FD_ISSET(tunfd, &rset)) {
					//size = tun_to_serial(tunfd, slipfd);
					tun_to_serial(tunfd, slipfd);
					slip_flushbuf(slipfd);
					sigalarm_reset();

					if(basedelay) {
						struct timeval tv;
						gettimeofday(&tv, NULL) ;
						//         delaymsec=basedelay*(1+(size/120));//multiply by # of 6lowpan packets?
						delaymsec=basedelay;
						delaystartsec =tv.tv_sec;
						delaystartmsec=tv.tv_usec/1000;
					}
				}
			}
		}
	}
}
Exemplo n.º 16
0
int
main(int argc, char **argv)
{
	int c;
	int slipfd, maxfd;
	int ret;
	fd_set rset, wset;
	FILE *inslip;
	char siodev[10] = "";
	int baudrate = -2;

	char buf[4000];
    
    prog = argv[0];

	setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */

	memset(&osVersionInfo,0,sizeof(OSVERSIONINFO));
	osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&osVersionInfo);

    while((c = getopt(argc, argv, "B:D:L:hs:c:ra:p:vtb:")) != -1) {
		switch (c) {
	case 'B':
		baudrate = atoi(optarg);
		break;

	case 'L':
		if(strncmp("0", optarg, 1) == 0) {
		  timestamp = 0;
		} else {
		  timestamp = atoi(optarg);
		  if (timestamp==0) timestamp=1;
		}
		break;

	case 's':
		if(strncmp("/dev/", optarg, 5) == 0) {
			strncpy(siodev,optarg + 5,sizeof(siodev)-1);
		}
		else if(strncmp("COM", optarg, 3) == 0) {

			int portnum;

			portnum = atoi(optarg+3);

			if(portnum == 0){
				err(1,"port number is invalid");
			}
			sprintf(siodev,"ttyS%d",portnum-1);
		}
		else {
			strncpy(siodev,optarg,sizeof(siodev)-1);
		}
		break;

	case 'c':
		channel = atoi(optarg);
		set_channel = 1;
		break;
	case 'r':
		sniffer_mode = 1;
		break;

	case 'a':
		if(autoconf == true){
			print_help();
		}
		local_ipaddr = optarg;
        if (!validIPAddr(local_ipaddr, 0)){
			if (timestamp) stamptime();
            fprintf(stderr, "Invalid IPv6 address: %s", local_ipaddr);
            exit(1);
        }
		break;

	case 'p':
		if(local_ipaddr !=NULL){
			print_help();
		}
		autoconf = true;
		ipprefix = optarg;
        if (!validIPAddr(ipprefix, 0)){
			if (timestamp) stamptime();
            fprintf(stderr, "Invalid IPv6 prefix: %s", ipprefix);
            exit(1);
        }
		break;

	case 'v':
		verbose = true;
		break;

    case 't':
		tun = true;
		break;

    case 'b':
		br_prefix = optarg;
        send_prefix = true;
        send_mac = false;
        tun = true;

        if (!validIPAddr(br_prefix, 64)){
			if (timestamp) stamptime();
            fprintf(stderr, "Invalid IPv6 64-bit prefix: %s", br_prefix);
            exit(1);
        }
        strtok(br_prefix,"/"); // Remove prefix length if it is present.
		break;

	case '?':
	case 'h':
	default:
		print_help();
		break;
		}
	}
	argc -= (optind - 1);
	argv += (optind - 1);

	if(argc != 2 || *siodev == '\0') {
		print_help();
	}

    if(autoconf == true && br_prefix != NULL){
		if (timestamp) stamptime();
        fprintf(stderr, "-p and -b options cannot be used together.\r\n");
        print_help();
    }

	sscanf(argv[1],"%2X-%2X-%2X-%2X-%2X-%2X",
		(int *)&adapter_eth_addr.addr[0],(int *)&adapter_eth_addr.addr[1],
        (int *)&adapter_eth_addr.addr[2],(int *)&adapter_eth_addr.addr[3],
        (int *)&adapter_eth_addr.addr[4],(int *)&adapter_eth_addr.addr[5]);
	if_name = wpcap_start(&adapter_eth_addr, verbose);

	if(local_ipaddr!=NULL){
		addAddress(if_name, local_ipaddr);
	}

	switch(baudrate) {
  case -2:
	  break;			/* Use default. */
  case 9600:
	  b_rate = B9600;
	  break;
  case 19200:
	  b_rate = B19200;
	  break;
  case 38400:
	  b_rate = B38400;
	  break;
  case 57600:
	  b_rate = B57600;
	  break;
  case 115200:
	  b_rate = B115200;
	  break;
  case 230400:
	  b_rate = B230400;
	  break;
  case 460800:
	  b_rate = B460800;
	  break;
  case 921600:
	  b_rate = B921600;
	  break;
  default:
	  err(1, "unknown baudrate %d", baudrate);
	  break;
	}


	slipfd = devopen(siodev, O_RDWR | O_NONBLOCK | O_NOCTTY | O_NDELAY | O_DIRECT | O_SYNC );
	if(slipfd == -1) {
		err(1, "can't open siodev ``/dev/%s''", siodev);
	}
	if (timestamp) stamptime();
	fprintf(stderr, "wpcapslip6 started on ``/dev/%s''\n", siodev);
	stty_telos(slipfd);
	slip_send(SLIP_END);
	inslip = fdopen(slipfd, "r");
	if(inslip == NULL) err(1, "main: fdopen");


	atexit(cleanup);
	signal(SIGHUP, sigcleanup);
	signal(SIGTERM, sigcleanup);
	signal(SIGINT, sigcleanup);
	signal(SIGALRM, sigalarm);

	/* Request mac address from gateway. It may be useful for setting the best 
	IPv6 address of the local interface. */


	while(1) {
		maxfd = 0;
		FD_ZERO(&rset);
		FD_ZERO(&wset);

		send_commands();		

		if(!slip_empty()) {		/* Anything to flush? */
			FD_SET(slipfd, &wset);
		}

		FD_SET(slipfd, &rset);	/* Read from slip ASAP! */
		if(slipfd > maxfd) maxfd = slipfd;
#ifdef WITH_STDIN
		FD_SET(STDIN_FILENO, &rset);  /* Read from stdin too. */
		if(STDIN_FILENO > maxfd) maxfd = STDIN_FILENO;   /* This would not be necessary, since we know STDIN_FILENO is 0. */
#endif

		if(slip_empty()) {
			char *pbuf = buf;

			ret = wpcap_poll(pbuf);
			if( ret > 0 ){
				struct uip_eth_hdr * eth_hdr = (struct uip_eth_hdr *)pbuf;

				if(eth_hdr->type == htons(UIP_ETHTYPE_IPV6)){
					// We forward only IPv6 packet.
                    
                    if(tun){
                        // Cut away ethernet header.
                        pbuf += sizeof(struct uip_eth_hdr);
                        ret -= sizeof(struct uip_eth_hdr);
                    }

					write_to_serial(pbuf, ret);
					/*print_packet(pbuf, ret);*/
					slip_flushbuf(slipfd);
				}
			}
		}
		{
			struct timeval tv;
			tv.tv_sec = 0;
			tv.tv_usec = 10;
			ret = select(maxfd + 1, &rset, &wset, NULL, &tv);
		}
		if(ret == -1 && errno != EINTR && errno != EAGAIN) {
			err(1, "select");
		}
		else if(ret > 0) {
			if(FD_ISSET(slipfd, &rset)) {
				/* printf("serial_to_wpcap\n"); */
				serial_to_wpcap(inslip);
				/*	printf("End of serial_to_wpcap\n");*/
			}  

			if(FD_ISSET(slipfd, &wset)) {
				slip_flushbuf(slipfd);				
			}
#ifdef WITH_STDIN
			if(FD_ISSET(STDIN_FILENO, &rset)) {
				char inbuf;
				if(fread(&inbuf,1,1,stdin)){
					if(inbuf=='q'){
						exit(0);
					}
				}
			}
#endif
		}
	}
}
Exemplo n.º 17
0
void send_commands(void)
{
	char buf[3];

	if (request_mac) {
		slip_send('?');
		slip_send('M');
		slip_send(SLIP_END);

		request_mac = 0;
		alarm(REQUEST_MAC_TIMEOUT);
	}
	/* Send our mac to the device. If it knows our address, it is not needed to change
	the MAC address of our local interface (this can be also unsupported, especially under
	Windows).
	*/
	else if(send_mac && slip_empty()){
		short i;
		PRINTF("Sending our MAC.\n");

		slip_send('!');
		slip_send('M');

		for(i=0; i < 6; i++){
			sprintf(buf,"%02X",adapter_eth_addr.addr[i]);
			slip_send(buf[0]);
			slip_send(buf[1]);
		}
		slip_send(SLIP_END);

		send_mac = false;
	}
	else if(set_sniffer_mode && slip_empty()){

		PRINTF("Setting sniffer mode to %d.\n", sniffer_mode);

		slip_send('!');
		slip_send('O');
		slip_send('S');

		if(sniffer_mode){
			slip_send('1');
		}
		else {
			slip_send('0');
		}
		slip_send(SLIP_END);

		set_sniffer_mode = 0;

	}
	else if(set_channel && slip_empty()){

		if(channel != 0){
			PRINTF("Setting channel %02d.\n", channel);

			slip_send('!');
			slip_send('O');
			slip_send('C');
			
			sprintf(buf,"%02d",channel);
			slip_send(buf[0]);
			slip_send(buf[1]);

			slip_send(SLIP_END);
		}

		set_channel = 0;

	}
    else if(send_prefix && br_prefix != NULL  && slip_empty()){

        struct in6_addr addr;
        int i;

        inet_pton(AF_INET6, br_prefix, &addr);
		if (timestamp) stamptime();
        fprintf(stderr,"*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
            br_prefix, 
            addr.s6_addr[0], addr.s6_addr[1],
            addr.s6_addr[2], addr.s6_addr[3],
            addr.s6_addr[4], addr.s6_addr[5],
            addr.s6_addr[6], addr.s6_addr[7]);
        slip_send('!');
        slip_send('P');
        for(i = 0; i < 8; i++) {
            /* need to call the slip_send_char for stuffing */
            slip_send_char(addr.s6_addr[i]);
        }
        slip_send(SLIP_END);

        send_prefix = false;

    }
}
Exemplo n.º 18
0
void
serial_to_wpcap(FILE *inslip)
{
	uint16_t buf_aligned[BUF_SIZE/2 + 42]; //extra for possible eth_hdr and ip_process expansion
	uint8_t *buf = (uint8_t *)buf_aligned;

    static int inbufptr = 0, issensiblestring=1;
    int ret;
	unsigned char c;

    unsigned char * inpktbuf;

    if(tun){
        inpktbuf = buf + sizeof(struct uip_eth_hdr);
    }
    else {
        inpktbuf = buf;
    }



read_more:
	if(inbufptr >= BUF_SIZE) {
		inbufptr = 0;
	}
	ret = fread(&c, 1, 1, inslip);

	if(ret == -1) {
		err(1, "serial_to_tun: read");
	}
	if(ret == 0) {
		clearerr(inslip);
		return;
		if (timestamp) stamptime();
		fprintf(stderr, "serial_to_tun: EOF\n");
		exit(1);
	}
	/*  fprintf(stderr, ".");*/
	switch(c) {
  case SLIP_END:
	  if(inbufptr > 0) {
		  if(inpktbuf[0] == '!') {
			  if (inpktbuf[1] == 'M' && inbufptr == 18) {
				  /* Read gateway MAC address and autoconfigure tap0 interface */
				  char macs64[24], macs48[18];
				  int addr_bytes[8];				  
				  int i, pos;				  
				  for(i = 0, pos = 0; i < 16; i++) {
					  macs64[pos++] = inpktbuf[2 + i];
					  if ((i & 1) == 1 && i < 14) {
						  macs64[pos++] = '-';
					  }
				  }
				  macs64[pos] = '\0';
				  if (timestamp) stamptime();
				  fprintf(stderr, "*** Gateway's MAC address: %s\n", macs64);
				  mac_received = true;
				  
				  sscanf(macs64, "%2X-%2X-%2X-%2X-%2X-%2X-%2X-%2X",
                        &addr_bytes[0],
                        &addr_bytes[1],
                        &addr_bytes[2],
                        &addr_bytes[3],
                        &addr_bytes[4],
                        &addr_bytes[5],
                        &addr_bytes[6],
                        &addr_bytes[7]);
                        
                  /* Form a fictitious MAC address for the attached device from its EUI-64 (2 middle bytes elided)  */
                  addr_bytes[0] |= 0x02;
                  for(i=0;i<3;i++){
                      dev_eth_addr.addr[i] = addr_bytes[i];
                  }
                  for(i=3;i<6;i++){
                      dev_eth_addr.addr[i] = addr_bytes[i+2];
                  }
                  sprintf(macs48,"%02X-%02X-%02X-%02X-%02X-%02X",
                            dev_eth_addr.addr[0],
                            dev_eth_addr.addr[1],
                            dev_eth_addr.addr[2],
                            dev_eth_addr.addr[3],
                            dev_eth_addr.addr[4],
                            dev_eth_addr.addr[5]);
				  if (timestamp) stamptime();
                  fprintf(stderr,"Fictitious MAC-48: %s\n", macs48);

				  if(autoconf){

                      if(IPAddrFromPrefix(autoconf_addr, ipprefix, macs64)!=0){
					      if (timestamp) stamptime();
                          fprintf(stderr, "Invalid IPv6 address.\n");
						  exit(1);
                      }
					  local_ipaddr = autoconf_addr;
					  addAddress(if_name,local_ipaddr);
					  
				  }
                  if(br_prefix != NULL){
                      /* RPL Border Router mode. Add route towards LoWPAN. */

                      if(IPAddrFromPrefix(rem_ipaddr, br_prefix, macs64)!=0){
					      if (timestamp) stamptime();
                          fprintf(stderr, "Invalid IPv6 address.\n");
						  exit(1);
                      }

                      addLoWPANRoute(if_name, br_prefix, rem_ipaddr);
                      addNeighbor(if_name, rem_ipaddr, macs48);
                  }

			  }
#define DEBUG_LINE_MARKER '\r'
		  }
		  else if(inpktbuf[0] == '?') {
			   if (inpktbuf[1] == 'M') {
				   /* Send our MAC address. */

				   send_mac = true;
				   set_sniffer_mode = true;
				   set_channel = true;
			   }
               else if (inpktbuf[1] == 'P') {
				   /* Send LoWPAN network prefix to the border router. */
				   send_prefix = true;
			   }
		  }
		  else if(inpktbuf[0] == DEBUG_LINE_MARKER) {
		    /* Dont insert timestamp on wireshark packet dumps starting with 0000 */
			  if (timestamp) {
			     if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime();
			  }
			  fwrite(inpktbuf + 1, inbufptr - 1, 1, stderr);
			  issensiblestring=1;
		  }
#if 0
		  else if(is_sensible_string(inpktbuf, inbufptr)) {
		    /* Dont insert timestamp on wireshark packet dumps starting with 0000 */
			  if (timestamp) {
			     if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime();
			  }
			  fwrite(inpktbuf, inbufptr, 1, stderr);
		  }
#else
		  else if(issensiblestring) {
		    /* Dont insert timestamp on wireshark packet dumps starting with 0000 */
			  if (timestamp) {
			     if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime();
			  }
			  fwrite(inpktbuf, inbufptr, 1, stderr);
			  
		  }
#endif
		  else {

              PRINTF("Sending to wpcap\n");

              if(tun){
                  
                  //Ethernet header to be inserted before IP packet
                  struct uip_eth_hdr * eth_hdr = (struct uip_eth_hdr *)buf;

                  memcpy(&eth_hdr->dest, &adapter_eth_addr, sizeof(struct uip_eth_addr));
                  memcpy(&eth_hdr->src, &dev_eth_addr, sizeof(struct uip_eth_addr));

                  eth_hdr->type = htons(UIP_ETHTYPE_IPV6);
                  inbufptr += sizeof(struct uip_eth_hdr);

                  // Process incoming packets to transform link layer addresses inside ICMP packets.
                  // Try to do processing if we did not succeed to add the neighbor.
                  if(clean_neighb == false){
                    inbufptr = ip_process(buf, inbufptr);
                  }
              }
              //print_packet(inpktbuf, inbufptr);

			  wpcap_send(buf, inbufptr);
			  /*      printf("After sending to wpcap\n");*/
		  }
		  inbufptr = 0;
		  issensiblestring=1;
	  }
	  break;

  case SLIP_ESC:
	  if(fread(&c, 1, 1, inslip) != 1) {
		  clearerr(inslip);
		  /* Put ESC back and give up! */
		  ungetc(SLIP_ESC, inslip);
		  return;
	  }

	  switch(c) {
  case SLIP_ESC_END:
	  c = SLIP_END;
	  break;
  case SLIP_ESC_ESC:
	  c = SLIP_ESC;
	  break;
	  }
	  /* FALLTHROUGH */
  default:
	  inpktbuf[inbufptr++] = c;
	  if (issensiblestring) {
	    if(c == '\n') {
		/* Dont insert timestamp on wireshark packet dumps starting with 0000 */
		  if (timestamp) {
			 if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime();
		  }
/* This could be a proper debug string starting with CR just a print to stdout */
/* Trap the CR which would cause overwriting of the timestamp */
//{int i;for (i=0;i<inbufptr;i++) fprintf(stderr,"%2x ",inpktbuf[i]);}
		  if(inpktbuf[0] == DEBUG_LINE_MARKER) {
		    fwrite(inpktbuf + 1, inbufptr - 1, 1, stderr);
		  } else {
	  	    fwrite(inpktbuf, inbufptr, 1, stderr);
		  }
		  inbufptr=0; 
		} else if (c == 0 || c == '\t' || c == '\r') {
	    } else if(c < ' ' || '~' < c) {
	      issensiblestring=0;
		}
	  }
	  break;
	}

	goto read_more;
}