summary refs log tree commit diff
path: root/fatvpn.c
diff options
context:
space:
mode:
Diffstat (limited to 'fatvpn.c')
-rw-r--r--fatvpn.c50
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 */