mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2024-12-22 06:15:31 +00:00
IPv6 for kernel module
This commit is contained in:
parent
27629ba0cc
commit
9c839a5094
110
iptk_YTUNBLOCK.c
110
iptk_YTUNBLOCK.c
@ -66,10 +66,12 @@ MODULE_VERSION("0.3.2");
|
|||||||
MODULE_AUTHOR("Vadim Vetrov <vetrovvd@gmail.com>");
|
MODULE_AUTHOR("Vadim Vetrov <vetrovvd@gmail.com>");
|
||||||
MODULE_DESCRIPTION("Linux kernel module for youtube unblock");
|
MODULE_DESCRIPTION("Linux kernel module for youtube unblock");
|
||||||
|
|
||||||
static int rsfd;
|
|
||||||
static struct socket *rawsocket;
|
static struct socket *rawsocket;
|
||||||
DEFINE_MUTEX(rslock);
|
DEFINE_MUTEX(rslock);
|
||||||
|
|
||||||
|
static struct socket *raw6socket;
|
||||||
|
DEFINE_MUTEX(rs6lock);
|
||||||
|
|
||||||
static int open_raw_socket(void) {
|
static int open_raw_socket(void) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
ret = sock_create(AF_INET, SOCK_RAW, IPPROTO_RAW, &rawsocket);
|
ret = sock_create(AF_INET, SOCK_RAW, IPPROTO_RAW, &rawsocket);
|
||||||
@ -144,6 +146,79 @@ static int send_raw_ipv4(const uint8_t *pkt, uint32_t pktlen) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int open_raw6_socket(void) {
|
||||||
|
int ret = 0;
|
||||||
|
ret = sock_create(AF_INET6, SOCK_RAW, IPPROTO_RAW, &raw6socket);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_alert("Unable to create raw socket\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockptr_t optval = {
|
||||||
|
.kernel = NULL,
|
||||||
|
.is_kernel = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
int mark = config.mark;
|
||||||
|
optval.kernel = &mark;
|
||||||
|
ret = sock_setsockopt(raw6socket, SOL_SOCKET, SO_MARK, optval, sizeof(mark));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
pr_alert("setsockopt(SO_MARK, %d) failed\n", mark);
|
||||||
|
goto sr_err;
|
||||||
|
}
|
||||||
|
int one = 1;
|
||||||
|
optval.kernel = &one;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
sr_err:
|
||||||
|
sock_release(raw6socket);
|
||||||
|
err:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_raw6_socket(void) {
|
||||||
|
sock_release(raw6socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_raw_ipv6(const uint8_t *pkt, uint32_t pktlen) {
|
||||||
|
int ret = 0;
|
||||||
|
if (pktlen > AVAILABLE_MTU) return -ENOMEM;
|
||||||
|
|
||||||
|
struct ip6_hdr *iph;
|
||||||
|
|
||||||
|
if ((ret = ip6_payload_split(
|
||||||
|
(uint8_t *)pkt, pktlen, &iph, NULL, NULL, NULL)) < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in6 daddr = {
|
||||||
|
.sin6_family = AF_INET6,
|
||||||
|
/* Always 0 for raw socket */
|
||||||
|
.sin6_port = 0,
|
||||||
|
.sin6_addr = iph->ip6_dst
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msghdr msg;
|
||||||
|
struct kvec iov;
|
||||||
|
iov.iov_base = (__u8 *)pkt;
|
||||||
|
iov.iov_len = pktlen;
|
||||||
|
iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, 1);
|
||||||
|
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
msg.msg_name = &daddr;
|
||||||
|
msg.msg_namelen = sizeof(struct sockaddr_in6);
|
||||||
|
msg.msg_control = NULL;
|
||||||
|
msg.msg_controllen = 0;
|
||||||
|
|
||||||
|
mutex_lock(&rs6lock);
|
||||||
|
ret = kernel_sendmsg(raw6socket, &msg, &iov, 1, pktlen);
|
||||||
|
mutex_unlock(&rs6lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -213,8 +288,8 @@ erret_lc:
|
|||||||
if (ipvx == IP4VERSION)
|
if (ipvx == IP4VERSION)
|
||||||
return send_raw_ipv4(pkt, pktlen);
|
return send_raw_ipv4(pkt, pktlen);
|
||||||
|
|
||||||
// else if (ipvx == IP6VERSION)
|
else if (ipvx == IP6VERSION)
|
||||||
// return send_raw_ipv6(pkt, pktlen);
|
return send_raw_ipv6(pkt, pktlen);
|
||||||
|
|
||||||
printf("proto version %d is unsupported\n", ipvx);
|
printf("proto version %d is unsupported\n", ipvx);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -286,17 +361,42 @@ static struct xt_target ykb_tg_reg __read_mostly = {
|
|||||||
.me = THIS_MODULE,
|
.me = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct xt_target ykb6_tg_reg __read_mostly = {
|
||||||
|
.name = "YTUNBLOCK",
|
||||||
|
.target = ykb_tg,
|
||||||
|
.table = "mangle",
|
||||||
|
.hooks = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD),
|
||||||
|
.targetsize = sizeof(struct xt_ytunblock_tginfo),
|
||||||
|
.proto = IPPROTO_TCP,
|
||||||
|
.family = NFPROTO_IPV6,
|
||||||
|
.checkentry = ykb_chk,
|
||||||
|
.me = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
static int __init ykb_init(void) {
|
static int __init ykb_init(void) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ret = open_raw_socket();
|
ret = open_raw_socket();
|
||||||
if (ret < 0) goto err;
|
if (ret < 0) goto err;
|
||||||
|
|
||||||
|
if (config.use_ipv6) {
|
||||||
|
ret = open_raw6_socket();
|
||||||
|
if (ret < 0) goto close_rawsocket;
|
||||||
|
|
||||||
|
ret = xt_register_target(&ykb6_tg_reg);
|
||||||
|
if (ret < 0) goto close_raw6socket;
|
||||||
|
}
|
||||||
|
|
||||||
ret = xt_register_target(&ykb_tg_reg);
|
ret = xt_register_target(&ykb_tg_reg);
|
||||||
if (ret < 0) goto close_rawsocket;
|
if (ret < 0) goto close_xt6_target;
|
||||||
|
|
||||||
pr_info("youtubeUnblock kernel module started.\n");
|
pr_info("youtubeUnblock kernel module started.\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
close_xt6_target:
|
||||||
|
if (config.use_ipv6) xt_unregister_target(&ykb6_tg_reg);
|
||||||
|
close_raw6socket:
|
||||||
|
if (config.use_ipv6) close_raw6_socket();
|
||||||
close_rawsocket:
|
close_rawsocket:
|
||||||
close_raw_socket();
|
close_raw_socket();
|
||||||
err:
|
err:
|
||||||
@ -305,6 +405,8 @@ err:
|
|||||||
|
|
||||||
static void __exit ykb_destroy(void) {
|
static void __exit ykb_destroy(void) {
|
||||||
xt_unregister_target(&ykb_tg_reg);
|
xt_unregister_target(&ykb_tg_reg);
|
||||||
|
if (config.use_ipv6) xt_unregister_target(&ykb6_tg_reg);
|
||||||
|
if (config.use_ipv6) close_raw6_socket();
|
||||||
close_raw_socket();
|
close_raw_socket();
|
||||||
pr_info("youtubeUnblock kernel module destroyed.\n");
|
pr_info("youtubeUnblock kernel module destroyed.\n");
|
||||||
}
|
}
|
||||||
|
10
kmake.mk
10
kmake.mk
@ -15,7 +15,7 @@ kmake: kmod xmod
|
|||||||
kmod:
|
kmod:
|
||||||
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
||||||
|
|
||||||
xmod: libipt_YTUNBLOCK.so
|
xmod: libipt_YTUNBLOCK.so libip6t_YTUNBLOCK.so
|
||||||
|
|
||||||
libipt_YTUNBLOCK.so: libipt_YTUNBLOCK.o
|
libipt_YTUNBLOCK.so: libipt_YTUNBLOCK.o
|
||||||
$(CCLD) -shared -fPIC ${IPT_CFLAGS} -o $@ $^;
|
$(CCLD) -shared -fPIC ${IPT_CFLAGS} -o $@ $^;
|
||||||
@ -23,13 +23,21 @@ libipt_YTUNBLOCK.so: libipt_YTUNBLOCK.o
|
|||||||
libipt_YTUNBLOCK.o: libipt_YTUNBLOCK.c
|
libipt_YTUNBLOCK.o: libipt_YTUNBLOCK.c
|
||||||
$(CC) ${IPT_CFLAGS} -D_INIT=lib$*_init -fPIC -c -o $@ $<;
|
$(CC) ${IPT_CFLAGS} -D_INIT=lib$*_init -fPIC -c -o $@ $<;
|
||||||
|
|
||||||
|
libip6t_YTUNBLOCK.so: libip6t_YTUNBLOCK.o
|
||||||
|
$(CCLD) -shared -fPIC ${IPT_CFLAGS} -o $@ $^;
|
||||||
|
|
||||||
|
libip6t_YTUNBLOCK.o: libip6t_YTUNBLOCK.c
|
||||||
|
$(CC) ${IPT_CFLAGS} -D_INIT=lib$*_init -fPIC -c -o $@ $<;
|
||||||
|
|
||||||
kload:
|
kload:
|
||||||
insmod ipt_YTUNBLOCK.ko
|
insmod ipt_YTUNBLOCK.ko
|
||||||
cp ./libipt_YTUNBLOCK.so /usr/lib/xtables/
|
cp ./libipt_YTUNBLOCK.so /usr/lib/xtables/
|
||||||
|
cp ./libip6t_YTUNBLOCK.so /usr/lib/xtables/
|
||||||
|
|
||||||
kunload:
|
kunload:
|
||||||
-rmmod ipt_YTUNBLOCK
|
-rmmod ipt_YTUNBLOCK
|
||||||
-/bin/rm /usr/lib/xtables/libipt_YTUNBLOCK.so
|
-/bin/rm /usr/lib/xtables/libipt_YTUNBLOCK.so
|
||||||
|
-/bin/rm /usr/lib/xtables/libip6t_YTUNBLOCK.so
|
||||||
|
|
||||||
kreload: kunload kload
|
kreload: kunload kload
|
||||||
|
|
||||||
|
26
libip6t_YTUNBLOCK.c
Normal file
26
libip6t_YTUNBLOCK.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Used to register target in iptables
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <xtables.h>
|
||||||
|
|
||||||
|
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||||
|
#include "ipt_YTUNBLOCK.h"
|
||||||
|
|
||||||
|
#define _init __attribute__((constructor)) _INIT
|
||||||
|
#define __maybe_unused __attribute__((__unused__))
|
||||||
|
|
||||||
|
static void YTKB_help(void) {
|
||||||
|
printf("Youtube Unblock - bypass youtube slowdown DPI in Russia\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xtables_target ykb6_tg_reg = {
|
||||||
|
.name = "YTUNBLOCK",
|
||||||
|
.version = XTABLES_VERSION,
|
||||||
|
.family = NFPROTO_IPV6,
|
||||||
|
.size = XT_ALIGN(sizeof(struct xt_ytunblock_tginfo)),
|
||||||
|
.userspacesize = XT_ALIGN(sizeof(struct xt_ytunblock_tginfo)),
|
||||||
|
.help = YTKB_help,
|
||||||
|
};
|
||||||
|
|
||||||
|
void _init(void) {
|
||||||
|
xtables_register_target(&ykb6_tg_reg);
|
||||||
|
}
|
9
utils.c
9
utils.c
@ -37,7 +37,14 @@ void ip4_set_checksum(struct iphdr *iph)
|
|||||||
void tcp6_set_checksum(struct tcphdr *tcph, struct ip6_hdr *iph) {
|
void tcp6_set_checksum(struct tcphdr *tcph, struct ip6_hdr *iph) {
|
||||||
uint16_t old_check = ntohs(tcph->check);
|
uint16_t old_check = ntohs(tcph->check);
|
||||||
|
|
||||||
// nfq_tcp_compute_checksum_ipv6(tcph, iph);
|
#ifdef KERNEL_SPACE
|
||||||
|
tcph->check = 0;
|
||||||
|
tcph->check = csum_ipv6_magic(&iph->saddr, &iph->daddr,
|
||||||
|
ntohs(iph->ip6_plen), IPPROTO_TCP,
|
||||||
|
csum_partial(tcph, ntohs(iph->ip6_plen), 0));
|
||||||
|
#else
|
||||||
|
nfq_tcp_compute_checksum_ipv6(tcph, iph);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int set_ip_checksum(void *iph, uint32_t iphb_len) {
|
int set_ip_checksum(void *iph, uint32_t iphb_len) {
|
||||||
|
Loading…
Reference in New Issue
Block a user