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; } }
/* * 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 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 while (1) { if (inbufptr >= sizeof(uip.inbuf)) { if (timestamp) { stamptime(); } fprintf(stderr, "*** dropping large %d byte packet\n", inbufptr); inbufptr = 0; } 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]; unsigned int pos = 0; for (unsigned int i = 0; i < 16; i++) { macs[pos++] = uip.inbuf[2 + i]; if ((i & 1) == 1 && i < 14) { macs[pos++] = ':'; } } if (timestamp) { stamptime(); } macs[pos] = '\0'; 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[0] == '?') { if (uip.inbuf[1] == 'P') { /* Prefix info requested */ struct in6_addr addr; 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 (unsigned int i = 0; i < 8; i++) { /* need to call the slip_send_char for stuffing */ slip_send_char(slipfd, addr.s6_addr[i]); } slip_send(slipfd, SLIP_END); } #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) { #if WIRESHARK_IMPORT_FORMAT printf("0000"); for (unsigned int i = 0; i < inbufptr; i++) { printf(" %02x", uip.inbuf[i]); } #else printf(" "); for (unsigned int i = 0; i < inbufptr; i++) { printf("%02x", uip.inbuf[i]); if ((i & 3) == 3) { printf(" "); } if ((i & 15) == 15) { printf("\n "); } } #endif 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; } } }