Exemplo n.º 1
0
/* writes an 802.15.4 packet to slip-radio */
void
write_to_slip(const uint8_t * buf, int len)
{
  if(slipfd > 0) {
    write_to_serial(slipfd, buf, len);
  }
}
Exemplo n.º 2
0
/*
 * Read from tun, write to slip.
 */
void tun_to_serial(int infd, int outfd) {
	static union {
		unsigned char inbuf[2000];
		struct ip iphdr;
	} uip;
	int size;

	if ((size = read(infd, uip.inbuf, 2000)) == -1)
		err(1, "tun_to_serial: read");

	write_to_serial(outfd, uip.inbuf, size);
}
Exemplo n.º 3
0
/*
 * Read from tun, write to slip.
 */
	int
tun_to_serial(int infd, int outfd)
{
	struct {
		unsigned char inbuf[2000];
	} uip;
	int size;

	if((size = read(infd, uip.inbuf, 2000)) == -1) err(1, "tun_to_serial: read");

	write_to_serial(outfd, uip.inbuf, size);
	return size;
}
Exemplo n.º 4
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.º 5
0
void relay_dhcp_to_client(int slipfd) {
	struct dhcp_msg inm;
	struct {
		struct ip ip;
		struct dhcp_light_msg m;
	} pkt;
	int n, optlen, ip_len, udp_len;
	u_int8_t *p, *t, *end;
	u_int16_t sum;
	u_int8_t op, msg_type = 0;
	struct in_addr yiaddr;

	memset(&inm.options, 0x0, sizeof(inm.options));

	n = recv(dhsock, &inm, sizeof(inm), 0x0/*flags*/);

	if (inm.op != BOOTREPLY) {
		return;
	}

	memcpy(&yiaddr, inm.yiaddr, sizeof(inm.yiaddr));
	memcpy(&pkt.m, &inm, DHCP_BASE_LEN);
	pkt.m.hops++;
	memset(pkt.m.giaddr, 0x0, sizeof(pkt.m.giaddr));

	/*
	 * Copy options we would like to send to client.
	 */
	memcpy(pkt.m.options, inm.options, 4); /* Magic cookie */

	end = &inm.op + n;
	p = inm.options + 4; /* Magic cookie */
	t = pkt.m.options + 4; /* Magic cookie */
	while (p < end) {
		op = p[0];
		switch (op) {
		case DHCP_OPTION_END:
			goto done;

		case DHCP_OPTION_MSG_TYPE:
			msg_type = p[2];
		case DHCP_OPTION_SUBNET_MASK:
		case DHCP_OPTION_ROUTER:
		case DHCP_OPTION_LEASE_TIME:
		case DHCP_OPTION_SERVER_ID: /* Copy these options */
			memcpy(t, p, p[1] + 2);
			t += p[1] + 2;
			p += p[1] + 2;
			break;

		case DHCP_OPTION_DNS_SERVER: /* Only copy first server */
			*t++ = p[0];
			*t++ = 4;
			memcpy(t, p + 2, 4);
			t += 4;
			p += p[1] + 2;
			break;

		default: /* Ignore these options */
			/* printf("option type %d len %d\n", op, p[1]); */
			p += p[1] + 2;
			continue;
		}
	}
	done: if (op == DHCP_OPTION_END) {
		*t++ = op;
		//*p++;
	}

	optlen = t - pkt.m.options;
	ip_len = 20 + 8 + DHCP_BASE_LEN + optlen;
	udp_len = 8 + DHCP_BASE_LEN + optlen;

	pkt.ip.ip_vhl = 0x45; /* IPv4 and hdrlen=5*4 */
	pkt.ip.ip_tos = 0;
	pkt.ip.ip_len = htons(ip_len);
	pkt.ip.ip_id = htons(ip_id++);
	pkt.ip.ip_off = 0;
	pkt.ip.ip_ttl = 64;
	pkt.ip.ip_p = 17; /* proto UDP */
	pkt.ip.ip_sum = 0;
	pkt.ip.ip_src = giaddr;
	if (inm.flags & htons(BOOTP_BROADCAST)) /* check bcast bit */
		pkt.ip.ip_dst = 0xffffffff; /* 255.255.255.255 */
	else
		pkt.ip.ip_dst = yiaddr.s_addr;

	pkt.ip.uh_sport = htons(BOOTPS);
	pkt.ip.uh_dport = htons(BOOTPC);
	pkt.ip.uh_ulen = htons(udp_len);
	pkt.ip.uh_sum = 0;

	pkt.ip.ip_sum = ~htons(ip4sum(0, &pkt.ip, 20));
	sum = 17 + udp_len;
	sum = ip4sum(sum, &pkt.ip.ip_src, 8);
	sum = ip4sum(sum, &pkt.ip.uh_sport, udp_len);
	if (sum != 0xffff)
		pkt.ip.uh_sum = ~htons(sum);
	else
		pkt.ip.uh_sum = 0xffff;

	write_to_serial(slipfd, &pkt, ip_len);
	if (msg_type == DHCPACK) {
		printf("DHCPACK %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x IP %s\n",
				pkt.m.chaddr[0], pkt.m.chaddr[1], pkt.m.chaddr[2],
				pkt.m.chaddr[3], pkt.m.chaddr[4], pkt.m.chaddr[5],
				pkt.m.chaddr[6], pkt.m.chaddr[7], inet_ntoa(yiaddr));
		/* ssystem("arp -s %s auto pub only", inet_ntoa(yiaddr)); */
	}
}
Exemplo n.º 6
0
/* writes an 802.15.4 packet to slip-radio */
void
write_to_slip(const uint8_t *buf, int len)
{
  /* printf("Packet to SLIP: %d\n", len); */
  write_to_serial(slipfd, buf, len);
}