diff options
Diffstat (limited to 'gre.c')
-rw-r--r-- | gre.c | 44 |
1 files changed, 29 insertions, 15 deletions
@@ -46,7 +46,7 @@ static size_t remote_len; static short type = IFF_TUN; static uint8_t mac[6]; -uint8_t buf[4096]; +uint8_t buf[65536]; static void gre_cb(void); static int gre_ipv4(uint8_t **buf, int *n); @@ -187,7 +187,7 @@ static void gre_cb(void) int n; struct sockaddr_storage src; socklen_t src_len = sizeof(src); - uint8_t offset = type == IFF_TAP ? 6 + 6 + 2 : 0; + uint8_t offset = 0; //type == IFF_TAP ? 6 + 6 + 2 : 0; memset(&src, 0, src_len); n = recvfrom(sock, buf + offset, sizeof(buf)-offset, 0, (struct sockaddr*)&src, &src_len); @@ -202,13 +202,16 @@ static void gre_cb(void) switch (remote.ss_family) { case AF_INET: res = gre_ipv4(&frame, &n); break; case AF_INET6: res = gre_ipv6(&frame, &n, (const struct sockaddr_in6*)&src); break; - default: return; + default: printf("Unknown family\n"); return; } if (res < 0) + { + printf("Failed GRE decode"); return; + } - if ( type == IFF_TAP ) + if ( 0 ) //type == IFF_TAP ) { /* Set tuntap header */ memset(frame - offset, 0, 2); @@ -241,6 +244,7 @@ static int gre_ipv4(uint8_t **bufp, int *np) const struct sockaddr_in *remote_in = (const struct sockaddr_in *)&remote; if (*(uint32_t *)(buf + 12) != remote_in->sin_addr.s_addr) { + printf("Wrong IPv4 source\n"); return -1; } @@ -273,22 +277,33 @@ static int gre_ipv6(uint8_t **bufp, int *np, const struct sockaddr_in6 *src) static int gre_any(const uint8_t *buf, int n) { + //uint8_t offset = type == IFF_TAP ? 6 + 6 + 2 : 0; + uint8_t offset = 0; + // parse GRE header - if (*(uint16_t *)(buf) != 0) + uint16_t *hdr = (uint16_t *)(buf+offset); + if (hdr[0] != 0) { + printf("Bad GRE header: %04x %04x\n", ntohs(hdr[0]), ntohs(hdr[1])); return -1; } uint16_t protocol = ntohs(*(uint16_t *)(buf + 2)); - switch (protocol) { - case ETHERTYPE_IP: - case ETHERTYPE_IPV6: - break; - case ETHERTYPE_ARP: - if (type == IFF_TAP) + if (type == IFF_TUN) + { + switch (protocol) { + case ETHERTYPE_IP: + case ETHERTYPE_IPV6: break; - return -1; - default: - return -1; + default: + printf("Wrong proto: %04x\n", protocol); + return -1; + } + } else { + if (protocol != ETH_P_TEB) + { + printf("Wrong proto: %04x\n", protocol); + return -1; + } } return write(tun, buf, n); } @@ -312,7 +327,6 @@ static int tun_cb(void) if (type == IFF_TAP) { - size_t ethsize = 6 + 6 + 2; frame = buf; *(uint16_t*)(frame + 2) = htons(ETH_P_TEB); } else { |