summary refs log tree commit diff
path: root/fatvpnd.c
diff options
context:
space:
mode:
Diffstat (limited to 'fatvpnd.c')
-rw-r--r--fatvpnd.c53
1 files changed, 33 insertions, 20 deletions
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 */