diff options
Diffstat (limited to 'fatvpn.c')
| -rw-r--r-- | fatvpn.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/fatvpn.c b/fatvpn.c index 3a03067..51f48e5 100644 --- a/fatvpn.c +++ b/fatvpn.c @@ -13,13 +13,12 @@ int main(int argc, char *argv[]){ u8 *pkt; s32 tmp, res, tap, fdmax, skt; u32 lptime; - struct sockaddr_in *s4; - struct sockaddr_in6 srv, sender; - struct addrinfo *srvi; - struct timespec t; - struct timeval slp; - struct termios attr; - struct ifreq ifr; + struct sockaddr_storage srv, sender; + struct addrinfo *srvi; + struct timespec t; + struct timeval slp; + struct termios attr; + struct ifreq ifr; fd_set rset; /* arguments */ @@ -50,16 +49,10 @@ int main(int argc, char *argv[]){ /* server address */ switch (srvi->ai_family){ case AF_INET: - s4 = (struct sockaddr_in*) srvi->ai_addr; - srv.sin6_family = AF_INET6; - srv.sin6_port = s4->sin_port; - memset(&srv.sin6_addr.s6_addr, 0, 16); - srv.sin6_addr.s6_addr[10] = 0xFF; - srv.sin6_addr.s6_addr[11] = 0xFF; - memcpy(&srv.sin6_addr.s6_addr[12], &s4->sin_addr.s_addr, 4); + memcpy(&srv, srvi->ai_addr, sizeof(struct sockaddr_in)); break; case AF_INET6: - memcpy(&srv, srvi->ai_addr, sizeof(srv)); + memcpy(&srv, srvi->ai_addr, sizeof(struct sockaddr_in6)); break; default: fprintf(stderr, "unsupported addrfamily: %s\n", argv[2]); @@ -142,7 +135,7 @@ int main(int argc, char *argv[]){ if (pkt == NULL) fputs("pkt = malloc() failed\n",stderr), exit(1); /* socket, setsockopt */ - skt = socket(PF_INET6, SOCK_DGRAM, 0); ERRDIE(skt, "socket"); + skt = socket(srv.ss_family, SOCK_DGRAM, 0); ERRDIE(skt, "socket"); res = 1; res = setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, &res, sizeof(res)); ERRDIE(res, "SO_REUSEADDR"); @@ -172,7 +165,7 @@ inf_loop: clock_gettime(CLOCK_MONOTONIC, &t); if (TIMEOUT_P <= (u32)t.tv_sec - lptime){ /* ping for NAT keepalive */ - send_pkt(skt, pkt, 14, (struct sockaddr_storage*)&srv); + send_pkt(skt, pkt, 14, &srv); lptime = t.tv_sec; } @@ -182,19 +175,32 @@ inf_loop: ERRDIE(res, "read(tap)"); /* TODO: check res+N > MAX_PKT_SZ */ - send_pkt(skt, pkt, res, (struct sockaddr_storage*)&srv); + send_pkt(skt, pkt, res, &srv); } /* recv packet from server */ if (0 == FD_ISSET(skt, &rset)) goto inf_loop; - res = recv_pkt(skt, pkt, MAX_PKT_SZ, - (struct sockaddr_storage*)&sender); + res = recv_pkt(skt, pkt, MAX_PKT_SZ, &sender); if (res < 14) goto inf_loop; /* ignore too small packets */ /* compare port and ip */ - if (srv.sin6_port != sender.sin6_port) goto inf_loop; - tmp = memcmp(srv.sin6_addr.s6_addr, sender.sin6_addr.s6_addr, 16); + switch (srvi->ai_family){ + case AF_INET: + if (((struct sockaddr_in*)&srv)->sin_port != + ((struct sockaddr_in*)&sender)->sin_port) goto inf_loop; + tmp = memcmp(&((struct sockaddr_in*)&srv)->sin_addr.s_addr, + &((struct sockaddr_in*)&sender)->sin_addr.s_addr, + 4); + break; + case AF_INET6: + if (((struct sockaddr_in6*)&srv)->sin6_port != + ((struct sockaddr_in6*)&sender)->sin6_port) goto inf_loop; + tmp = memcmp(((struct sockaddr_in6*)&srv)->sin6_addr.s6_addr, + ((struct sockaddr_in6*)&sender)->sin6_addr.s6_addr, + 16); + break; + } if (tmp != 0) goto inf_loop; /* packet recv time for entropy and last packet time */ |