int main(int argc, char* argv[]) { struct tuntap_dev tuntap; int i; int mtu = 1400; printf("Welcome to n2n\n"); initWin32(); open_wintap(&tuntap, "1.2.3.20", "255.255.255.0", mtu); for(i=0; i<10; i++) { u_char buf[MTU]; int rc; rc = tun_read(&tuntap, buf, sizeof(buf)); buf[0]=2; buf[1]=3; buf[2]=4; printf("tun_read returned %d\n", rc); rc = tun_write(&tuntap, buf, rc); printf("tun_write returned %d\n", rc); } // rc = tun_open (device->device_name, IF_MODE_TUN); WSACleanup (); return(0); }
void tcplib_send_out(struct split_ip_msg *msg, struct tcp_hdr *tcph) { uint8_t buf[8192]; struct timespec tv; if (sock <= 0) return; // printf("sending message\n"); memcpy(msg->hdr.ip6_src.s6_addr, iface_addr, 16); msg->hdr.ip6_src.s6_addr[15] = 2; msg->hdr.hlim = 64; memset(msg->hdr.vlfc, 0, 4); msg->hdr.vlfc[0] = 6 << 4; tcph->chksum = htons(msg_cksum(msg, IANA_TCP)); tv.tv_sec = 0; // sleep for a ms to give up the cpu... tv.tv_nsec = 1000000; nanosleep(&tv); // print_split_msg(msg); if (rand() % LOSS_RATE_TRANS == 0) { printf("dropping packet on write\n"); } else { printf("tun_write\n"); tun_write(sock, msg); } }
void netdev_transmit(struct netdev *dev, struct eth_hdr *hdr, uint16_t ethertype, int len, uint8_t *dst) { uint8_t dst_mac[6]; memcpy(dst_mac, dst, 6); hdr->ethertype = htons(ethertype); memcpy(hdr->smac, dev->hwaddr, 6); memcpy(hdr->dmac, dst_mac, 6); len += sizeof(struct eth_hdr); tun_write((char *)hdr, len); }
void deliver_to_kernel(struct lowpan_reconstruct *recon) { struct ip6_packet pkt; struct ip_iovec v; struct ip6_hdr *iph = (struct ip6_hdr *)recon->r_buf; iph->ip6_plen = htons(recon->r_bytes_rcvd - sizeof(struct ip6_hdr)); { struct ip6_ext *cur = (struct ip6_ext *)(recon->r_buf + sizeof(struct ip6_hdr)); uint8_t nxt = iph->ip6_nxt; while (nxt == IPV6_HOP || nxt == IPV6_ROUTING || nxt == IPV6_FRAG || nxt == IPV6_DEST || nxt == IPV6_MOBILITY || nxt == IPV6_IPV6) { nxt = cur->ip6e_nxt; cur = cur + cur->ip6e_len; if (cur->ip6e_len == 0) { break; } } if (nxt == IANA_UDP) { struct udp_hdr *udp = (struct udp_hdr *)cur; udp->len = htons(recon->r_bytes_rcvd - ((uint8_t *)cur - recon->r_buf)); } } /* set up the IPv6 packet structure */ memcpy(&pkt.ip6_hdr, iph, sizeof(struct ip6_hdr)); pkt.ip6_data = &v; v.iov_base = recon->r_buf + sizeof(struct ip6_hdr); v.iov_len = ntohs(iph->ip6_plen); v.iov_next = NULL; tun_write(tun_fd, &pkt); free(recon->r_buf); memset(recon, 0, sizeof(struct lowpan_reconstruct)); recon->r_timeout = T_UNUSED; recon->r_buf = NULL; }
/** * Function to run the tunnel */ void run_tunnel(char *dest, int server) { struct icmp_packet packet; int tun_fd, sock_fd; fd_set fs; tun_fd = tun_alloc("tun0", IFF_TUN | IFF_NO_PI); printf("[DEBUG] Starting tunnel - Dest: %s, Server: %d\n", dest, server); printf("[DEBUG] Opening ICMP socket\n"); sock_fd = open_icmp_socket(); if (server) { printf("[DEBUG] Binding ICMP socket\n"); bind_icmp_socket(sock_fd); } configure_network(server); while (1) { FD_ZERO(&fs); FD_SET(tun_fd, &fs); FD_SET(sock_fd, &fs); select(tun_fd>sock_fd?tun_fd+1:sock_fd+1, &fs, NULL, NULL, NULL); if (FD_ISSET(tun_fd, &fs)) { printf("[DEBUG] Data needs to be readed from tun device\n"); // Reading data from tun device and sending ICMP packet printf("[DEBUG] Preparing ICMP packet to be sent\n"); // Preparing ICMP packet to be sent memset(&packet, 0, sizeof(struct icmp_packet)); printf("[DEBUG] Destination address: %s\n", dest); strcpy(packet.src_addr, "0.0.0.0"); strcpy(packet.dest_addr, dest); if(server) { set_reply_type(&packet); } else { set_echo_type(&packet); } packet.payload = malloc(MTU); packet.payload_size = tun_read(tun_fd, packet.payload, MTU); if(packet.payload_size == -1) { perror("Error while reading from tun device\n"); exit(EXIT_FAILURE); } printf("[DEBUG] Sending ICMP packet with payload_size: %d, payload: %s\n", packet.payload_size, packet.payload); // Sending ICMP packet send_icmp_packet(sock_fd, &packet); free(packet.payload); } if (FD_ISSET(sock_fd, &fs)) { printf("[DEBUG] Received ICMP packet\n"); // Reading data from remote socket and sending to tun device // Getting ICMP packet memset(&packet, 0, sizeof(struct icmp_packet)); receive_icmp_packet(sock_fd, &packet); printf("[DEBUG] Read ICMP packet with src: %s, dest: %s, payload_size: %d, payload: %s\n", packet.src_addr, packet.dest_addr, packet.payload_size, packet.payload); // Writing out to tun device tun_write(tun_fd, packet.payload, packet.payload_size); printf("[DEBUG] Src address being copied: %s\n", packet.src_addr); strcpy(dest, packet.src_addr); } } }
static void read_data(struct rcontext* rcontext, const struct proto* proto) { tun_write(rcontext->config->master_fd, proto->data.value, proto->data.length); }
int icmp_tunnel(int sock, int proxy, struct sockaddr_in *target, int tun_fd, int packetsize, u_int16_t id) { char* packet; struct icmp *icmp, *icmpr; int len; int result; fd_set fs; struct sockaddr_in from; int fromlen; int num; len = sizeof (struct icmp); packet = malloc (len+packetsize); memset (packet, 0, len+packetsize); icmp = (struct icmp*)(packet); icmpr = (struct icmp*)(packet+sizeof(struct ip)); while (1) { FD_ZERO (&fs); FD_SET (tun_fd, &fs); FD_SET (sock, &fs); select (tun_fd>sock?tun_fd+1:sock+1, &fs, NULL, NULL, NULL); /* data available on tunnel device */ if (FD_ISSET (tun_fd, &fs)) { result = tun_read (tun_fd, packet+len, packetsize); if (!result) { return 0; } else if (result==-1) { perror ("read"); return -1; } icmp->type = proxy ? 0 : 8; icmp->code = 0; icmp->id = id; icmp->seq = 0; icmp->cksum = 0; icmp->cksum = in_cksum((u_short*)packet, len+result); result = sendto (sock, (char*)packet, len+result, 0, (struct sockaddr*)target, sizeof (struct sockaddr_in)); if (result==-1) { perror ("sendto"); return -1; } } /* data available on socket */ if (FD_ISSET (sock, &fs)) { fromlen = sizeof (struct sockaddr_in); num = recvfrom (sock, packet, len+packetsize, 0, (struct sockaddr*)&from, (socklen_t*) &fromlen); /* the data packet */ if (icmpr->id == id) { tun_write (tun_fd, packet+sizeof(struct ip)+sizeof(struct icmp), num-sizeof(struct ip)-sizeof(struct icmp)); /* one IPv4 client */ memcpy(&(target->sin_addr.s_addr), &(from.sin_addr.s_addr), 4*sizeof(char)); } } /* end of data available */ } /* end of while(1) */ return 0; }