diff options
| author | Nakidai <nakidai@disroot.org> | 2025-11-23 12:10:39 +0300 |
|---|---|---|
| committer | Nakidai <nakidai@disroot.org> | 2025-11-23 12:40:44 +0300 |
| commit | b1ec6ae205a00142971672a505585f3da87d4a9f (patch) | |
| tree | e39dbc76b05b48886a65983b81a655802ac62cb4 | |
| parent | 1271e6efcb473dba79ba7249569d8e6fb296e96f (diff) | |
| download | fatvpn-b1ec6ae205a00142971672a505585f3da87d4a9f.tar.gz fatvpn-b1ec6ae205a00142971672a505585f3da87d4a9f.zip | |
Make ipv4 and ipv6 separated
Using ipv4 inside of ipv6 was less portable
| -rw-r--r-- | fatvpn.c | 50 | ||||
| -rw-r--r-- | fatvpnd.c | 53 |
2 files changed, 61 insertions, 42 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 */ diff --git a/fatvpnd.c b/fatvpnd.c index 767f305..f3f891b 100644 --- a/fatvpnd.c +++ b/fatvpnd.c @@ -9,7 +9,7 @@ #define TIMEOUT_D 180 /* timeout (no packets) in seconds for disconnect */ struct { - struct sockaddr_in6 a; + struct sockaddr_storage a; u32 lptime; /* time of last packet */ u8 mac[6]; /* internal mac */ } peer[MAX_PEERS]; @@ -19,10 +19,10 @@ u32 ccnt; int main(int argc, char *argv[]){ u8 *pkt; s32 res, tap, fdmax, skt, i, psz; - struct sockaddr_in6 c; - struct timespec t; - struct termios attr; - struct ifreq ifr; + struct sockaddr_storage c; + struct timespec t; + struct termios attr; + struct ifreq ifr; fd_set rset; /* arguments */ @@ -36,19 +36,20 @@ int main(int argc, char *argv[]){ } memset(&c, 0, sizeof(c)); - c.sin6_family = AF_INET6; - c.sin6_port = htons((u16)atoi(argv[argc-1])); + c.ss_family = AF_INET; + (*(struct sockaddr_in*)&c).sin_port = htons((u16)atoi(argv[argc-1])); if (argc == 4){ - res = inet_pton(AF_INET6, argv[2], c.sin6_addr.s6_addr); + res = inet_pton(AF_INET6, argv[2], + ((struct sockaddr_in6*)&c)->sin6_addr.s6_addr); if (res != 1){ res = inet_pton(AF_INET, argv[2], &psz); if (res != 1){ fprintf(stderr, "wrong addr: %s\n",argv[2]); exit(1); } - c.sin6_addr.s6_addr[10] = 0xFF; - c.sin6_addr.s6_addr[11] = 0xFF; - memcpy(&c.sin6_addr.s6_addr[12], &psz, 4); + memcpy(&((struct sockaddr_in*)&c)->sin_addr.s_addr, &psz, 4); + } else { + c.ss_family = AF_INET6; } } @@ -129,7 +130,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(c.ss_family, SOCK_DGRAM, 0); ERRDIE(skt, "socket"); res = 1; res = setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, &res, sizeof(res)); ERRDIE(res, "SO_REUSEADDR"); @@ -176,8 +177,7 @@ inf_loop: for (i=0; i < ccnt; i++){ if (0 == memcmp(peer[i].mac, pkt, 6)){ - send_pkt(skt, pkt, psz, - (struct sockaddr_storage*) &peer[i].a); + send_pkt(skt, pkt, psz, &peer[i].a); break; } } @@ -186,12 +186,25 @@ inf_loop: /* recv packet from client */ if (0 == FD_ISSET(skt, &rset)) goto inf_loop; - psz = recv_pkt(skt, pkt, MAX_PKT_SZ, (struct sockaddr_storage*) &c); - - for (i=0; i < ccnt; i++) - if (c.sin6_port == peer[i].a.sin6_port && - 0 == memcmp(c.sin6_addr.s6_addr, - peer[i].a.sin6_addr.s6_addr, 16)) break; + psz = recv_pkt(skt, pkt, MAX_PKT_SZ, &c); + + switch (c.ss_family) + { + case AF_INET: + for (i=0; i < ccnt; i++) + if (((struct sockaddr_in*)&c)->sin_port == + ((struct sockaddr_in*)&peer[i].a)->sin_port && + ((struct sockaddr_in*)&c)->sin_addr.s_addr == + ((struct sockaddr_in*)&peer[i].a)->sin_addr.s_addr) break; + break; + case AF_INET6: + for (i=0; i < ccnt; i++) + if (((struct sockaddr_in6*)&c)->sin6_port == + ((struct sockaddr_in6*)&peer[i].a)->sin6_port && + 0 == memcmp(((struct sockaddr_in6*)&c)->sin6_addr.s6_addr, + ((struct sockaddr_in6*)&peer[i].a)->sin6_addr.s6_addr, 16)) break; + break; + } if (i == ccnt){ /* client not connected */ |