further IPv6 commits

This commit is contained in:
Chris Hellberg 2021-12-30 05:09:16 +00:00
parent 16e1b731f6
commit ab2bbd987f
4 changed files with 106 additions and 11 deletions

View file

@ -649,13 +649,30 @@ static int tunnel_tun(int tun_fd, struct dnsfd *dns_fds)
char in[64*1024];
int userid;
int read;
int ip_version;
int c;
struct in6_addr v6Addr;
char v6AddrP[16];
if ((read = read_tun(tun_fd, in, sizeof(in))) <= 0)
return 0;
/* find target ip in packet, in is padded with 4 bytes TUN header */
header = (struct ip*) (in + 4);
userid = find_user_by_ip(header->ip_dst.s_addr);
ip_version = in[4] & 0xf0;
if (ip_version == 64) { /* IPv4 */
header = (struct ip*) (in + 4);
userid = find_user_by_ip(header->ip_dst.s_addr);
} else { /* IPv6 */
for (c = 0; c < 16; c++) {
v6Addr.s6_addr[c] = in[c + 28];
printf("adding byte: %i to v6 address\n", in[c+28]);
}
inet_ntop(AF_INET6, &v6Addr, v6AddrP, INET6_ADDRSTRLEN);
printf("read v6Addr from tunnel: %s\n", v6AddrP);
userid = find_user_by_ip6(&v6Addr);
printf("userid: %d\n", userid);
}
if (userid < 0)
return 0;
@ -2437,7 +2454,7 @@ main(int argc, char **argv)
srand(time(NULL));
fw_query_init();
while ((choice = getopt(argc, argv, "46vcsfhDuS:t:d:m:l:L:p:n:b:P:z:F:i:")) != -1) {
while ((choice = getopt(argc, argv, "46vcsSfhDu:t:d:m:l:L:p:n:b:P:z:F:i:")) != -1) {
switch(choice) {
case '4':
addrfamily = AF_INET;

View file

@ -549,19 +549,39 @@ write_tun(int tun_fd, char *data, size_t len)
len -= 4;
} else {
#ifdef LINUX
int i = data[4] & 0xf0;
if (i == 64) {
fprintf(stderr, "IPv4 packet\n");
// Look at the fifth bype
// Linux prefixes with 32 bits ethertype
// 0x0800 for IPv4, 0x86DD for IPv6
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x08;
data[3] = 0x00;
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x08;
data[3] = 0x00;
} else { /* 96 for IPV6 */
fprintf(stderr, "IPv6 packet\n");
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x86;
data[3] = 0xDD;
}
#else /* OPENBSD and DARWIN(utun) */
// BSDs prefix with 32 bits address family
// AF_INET for IPv4, AF_INET6 for IPv6
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x00;
data[3] = 0x02;
if (i == 64) {
fprintf(stderr, "IPv4 packet\n");
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x00;
data[3] = 0x02;
} else { /* 96 for IPV6 */
fprintf(stderr, "IPv6 packet\n");
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x00;
data[3] = 0x0A;
#endif
}

View file

@ -42,12 +42,20 @@ int init_users(in_addr_t my_ip, int netbits)
int i;
int skip = 0;
char newip[16];
char ip6Tmp[16];
char ip6Tmp2[18];
char ipv4Tmp[16];
int maxusers;
in_addr_t netmask = 0;
struct in_addr net;
struct in_addr ipstart;
/* For IPv6, we take the IPv4 address and simply prepend ::
* and use a 64-bit mask. Reduces the need to parse
* netmasks.
*/
for (i = 0; i < netbits; i++) {
netmask = (netmask << 1) | 1;
@ -70,6 +78,19 @@ int init_users(in_addr_t my_ip, int netbits)
skip++;
snprintf(newip, sizeof(newip), "0.0.0.%d", i + skip + 1);
ip = ipstart.s_addr + inet_addr(newip);
inet_ntop(AF_INET, &ip, ip6Tmp, INET_ADDRSTRLEN);
snprintf(ip6Tmp2, sizeof(ip6Tmp2), "::%s", ip6Tmp);
inet_pton(AF_INET6, ip6Tmp2, &users[i].tun_ip6);
memset(ip6Tmp2,0,strlen(ip6Tmp2));
inet_ntop(AF_INET6, &users[i].tun_ip6, ip6Tmp2, INET6_ADDRSTRLEN);
inet_ntop(AF_INET, &ip, ipv4Tmp, INET_ADDRSTRLEN);
printf("storing IPv4 address: %s\n", ipv4Tmp);
printf("storing IPv6 address: %s\n", ip6Tmp2);
memset(ip6Tmp2,0,strlen(ip6Tmp2));
}
users[i].tun_ip = ip;
net.s_addr = ip;
@ -91,6 +112,40 @@ const char *users_get_first_ip(void)
return strdup(inet_ntoa(ip));
}
int find_user_by_ip6(struct in6_addr *v6Addr)
{
int i;
char v6AddrOut[32];
inet_ntop(AF_INET6, v6Addr, v6AddrOut, INET6_ADDRSTRLEN);
printf("Going to check address: %s in user list\n", v6AddrOut);
for (i = 0; i < usercount; i++) {
if (users[i].active &&
users[i].authenticated &&
!users[i].disabled &&
users[i].last_pkt + 60 > time(NULL) &&
(areV6AddressesEqual(v6Addr, &users[i].tun_ip6) == 0) ) {
return i;
}
}
return -1;
}
int areV6AddressesEqual(struct in6_addr *v6Struct1, struct in6_addr *v6Struct2)
{
int i;
for (i = 0; i < 16; i++) {
printf("byte1 %d: %d byte2 %d: %d\n", i, v6Struct1->s6_addr[i], i, v6Struct2->s6_addr[i]);
if (v6Struct1->s6_addr[i] != v6Struct2->s6_addr[i]) {
return -1;
}
}
return 0;
}
int find_user_by_ip(uint32_t ip)
{
int ret;

View file

@ -45,6 +45,7 @@ struct tun_user {
int seed;
in_addr_t tun_ip;
struct sockaddr_storage host;
struct in6_addr tun_ip6;
socklen_t hostlen;
struct query q;
struct query q_sendrealsoon;
@ -83,9 +84,11 @@ extern struct tun_user *users;
int init_users(in_addr_t, int);
const char* users_get_first_ip(void);
int find_user_by_ip(uint32_t);
int find_user_by_ip6(struct in6_addr *v6Addr);
int all_users_waiting_to_send(void);
int find_available_user(void);
void user_switch_codec(int userid, const struct encoder *enc);
void user_set_conn_type(int userid, enum connection c);
int areV6AddressesEqual(struct in6_addr *, struct in6_addr *);
#endif