mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2024-12-22 06:15:31 +00:00
Module for kernel works now on local machine.
SEG2_DELAY is not implemented yet.
This commit is contained in:
parent
62a5627c50
commit
8bb2bb28d2
2
Kbuild
2
Kbuild
@ -1,3 +1,3 @@
|
|||||||
obj-m := ipt_YTUNBLOCK.o
|
obj-m := ipt_YTUNBLOCK.o
|
||||||
ipt_YTUNBLOCK-objs := iptk_YTUNBLOCK.o mangle.o
|
ipt_YTUNBLOCK-objs := iptk_YTUNBLOCK.o mangle.o
|
||||||
ccflags-y := -std=gnu11 -Wno-unused-variable -DKERNEL_SPACE
|
ccflags-y := -std=gnu11 -Wno-unused-variable -DKERNEL_SPACE -DDEBUG
|
||||||
|
4
config.h
4
config.h
@ -23,6 +23,7 @@
|
|||||||
#elif FRAGMENTATION_STRATEGY == FRAG_STRAT_IP
|
#elif FRAGMENTATION_STRATEGY == FRAG_STRAT_IP
|
||||||
#define USE_IP_FRAGMENTATION
|
#define USE_IP_FRAGMENTATION
|
||||||
#elif FRAGMENTATION_STRATEGY == FRAG_STRAT_NONE
|
#elif FRAGMENTATION_STRATEGY == FRAG_STRAT_NONE
|
||||||
|
#define USE_NO_FRAGMENTATION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RAWSOCKET_MARK (1 << 15)
|
#define RAWSOCKET_MARK (1 << 15)
|
||||||
@ -35,6 +36,7 @@
|
|||||||
#define FAKE_SNI
|
#define FAKE_SNI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SILENT
|
#if !defined(SILENT) && !defined(KERNEL_SPACE)
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
186
iptk_YTUNBLOCK.c
186
iptk_YTUNBLOCK.c
@ -1,4 +1,3 @@
|
|||||||
//
|
|
||||||
// Kernel module for youtubeUnblock.
|
// Kernel module for youtubeUnblock.
|
||||||
// Make with make kmake && sudo iptables -t mangle -D OUTPUT 1 && sudo make kreload && sudo iptables -t mangle -I OUTPUT -p tcp -j YTUNBLOCK
|
// Make with make kmake && sudo iptables -t mangle -D OUTPUT 1 && sudo make kreload && sudo iptables -t mangle -I OUTPUT -p tcp -j YTUNBLOCK
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@ -9,15 +8,16 @@
|
|||||||
#include <linux/net.h>
|
#include <linux/net.h>
|
||||||
#include <linux/netfilter/x_tables.h>
|
#include <linux/netfilter/x_tables.h>
|
||||||
#include "ipt_YTUNBLOCK.h"
|
#include "ipt_YTUNBLOCK.h"
|
||||||
|
|
||||||
#include "mangle.h"
|
#include "mangle.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "raw_replacements.h"
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION("0.1");
|
MODULE_VERSION("0.1");
|
||||||
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");
|
||||||
|
|
||||||
#define USE_TCP_SEGMENTATION
|
|
||||||
|
|
||||||
static int rsfd;
|
static int rsfd;
|
||||||
static struct socket *rawsocket;
|
static struct socket *rawsocket;
|
||||||
DEFINE_MUTEX(rslock);
|
DEFINE_MUTEX(rslock);
|
||||||
@ -63,16 +63,13 @@ static void close_raw_socket(void) {
|
|||||||
static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
||||||
|
|
||||||
if (pktlen > AVAILABLE_MTU) {
|
if (pktlen > AVAILABLE_MTU) {
|
||||||
pr_alert("The packet is too big!");
|
pr_warn("The packet is too big and may cause issues!");
|
||||||
#ifdef DEBUG
|
|
||||||
printf("Split packet!\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
__u32 buff1_size = pktlen;
|
__u32 buff1_size = pktlen;
|
||||||
__u32 buff2_size = pktlen;
|
__u32 buff2_size = pktlen;
|
||||||
__u8 *buff1 = kmalloc(pktlen, GFP_KERNEL);
|
__u8 *buff1 = kmalloc(pktlen, GFP_ATOMIC);
|
||||||
if (buff1 == NULL) return -1;
|
if (buff1 == NULL) return -1;
|
||||||
__u8 *buff2 = kmalloc(pktlen, GFP_KERNEL);
|
__u8 *buff2 = kmalloc(pktlen, GFP_ATOMIC);
|
||||||
if (buff2 == NULL) {
|
if (buff2 == NULL) {
|
||||||
kfree(buff1);
|
kfree(buff1);
|
||||||
return -1;
|
return -1;
|
||||||
@ -80,15 +77,19 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
|||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
#ifdef USE_TCP_SEGMENTATION
|
#if defined(USE_TCP_SEGMENTATION) || defined(RAWSOCK_TCP_FSTRAT)
|
||||||
if ((ret = tcp4_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
if ((ret = tcp4_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
||||||
buff1, &buff1_size, buff2, &buff2_size)) < 0)
|
buff1, &buff1_size, buff2, &buff2_size)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
#else
|
#elif defined(USE_IP_FRAGMENTATION) || defined(RAWSOCK_IP_FSTRAT)
|
||||||
if ((ret = ip4_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
if ((ret = ip4_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
||||||
buff1, &buff1_size, buff2, &buff2_size)) < 0)
|
buff1, &buff1_size, buff2, &buff2_size)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
#else
|
||||||
|
pr_warn("send_raw_socket: Packet is too big but fragmentation is disabled! "
|
||||||
|
"Pass -DRAWSOCK_TCP_FSTRAT or -DRAWSOCK_IP_FSTRAT as CFLAGS "
|
||||||
|
"To enable it only for raw socket\n");
|
||||||
|
return -EINVAL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
@ -147,100 +148,147 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
|||||||
ret = kernel_sendmsg(rawsocket, &msg, &iov, 1, pktlen);
|
ret = kernel_sendmsg(rawsocket, &msg, &iov, 1, pktlen);
|
||||||
mutex_unlock(&rslock);
|
mutex_unlock(&rslock);
|
||||||
|
|
||||||
pr_info("%d\n", ret);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
static unsigned int ykb_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
static unsigned int ykb_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
|
if ((skb->mark & RAWSOCKET_MARK) == RAWSOCKET_MARK)
|
||||||
|
return XT_CONTINUE;
|
||||||
|
|
||||||
if (skb->head == NULL) return XT_CONTINUE;
|
if (skb->head == NULL) return XT_CONTINUE;
|
||||||
struct iphdr *iph = ip_hdr(skb);
|
|
||||||
if (iph == NULL) {
|
// TODO: Mallocs are bad!
|
||||||
pr_alert("iph is NULL!\n");
|
uint32_t buflen = skb->len;
|
||||||
goto accept;
|
__u8 *buf = kmalloc(skb->len, GFP_ATOMIC);
|
||||||
}
|
|
||||||
__u32 iph_len = iph->ihl * 4;
|
|
||||||
|
|
||||||
struct tcphdr *tcph = tcp_hdr(skb);
|
|
||||||
if (tcph == NULL) {
|
|
||||||
pr_alert("tcph is NULL!\n");
|
|
||||||
goto accept;
|
|
||||||
}
|
|
||||||
__u32 tcph_len = tcp_hdrlen(skb);
|
|
||||||
|
|
||||||
// Mallocs are bad!
|
|
||||||
__u8 *buf = kmalloc(skb->len, GFP_KERNEL);
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
pr_alert("Cannot alloc enough buffer");
|
pr_err("Cannot alloc enough buffer space");
|
||||||
goto accept;
|
goto accept;
|
||||||
}
|
}
|
||||||
if (skb_copy_bits(skb, 0, buf, skb->len) < 0) {
|
if (skb_copy_bits(skb, 0, buf, skb->len) < 0) {
|
||||||
pr_alert("Unable copy bits\n");
|
pr_err("Unable copy bits\n");
|
||||||
goto ac_fkb;
|
goto ac_fkb;
|
||||||
}
|
}
|
||||||
|
struct iphdr *iph;
|
||||||
|
uint32_t iph_len;
|
||||||
|
struct tcphdr *tcph;
|
||||||
|
uint32_t tcph_len;
|
||||||
|
__u8 *payload;
|
||||||
|
uint32_t plen;
|
||||||
|
|
||||||
const __u8 *payload = buf + iph_len + tcph_len;
|
int ret = tcp4_payload_split(buf, buflen, &iph, &iph_len,
|
||||||
__u32 plen = skb->len - iph_len - tcph_len;
|
&tcph, &tcph_len, &payload, &plen);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
goto ac_fkb;
|
||||||
|
|
||||||
struct verdict vrd = analyze_tls_data(payload, plen);
|
struct verdict vrd = analyze_tls_data(payload, plen);
|
||||||
|
|
||||||
if (vrd.gvideo_hello) {
|
if (vrd.gvideo_hello) {
|
||||||
pr_alert("Googlevideo detected!\n");
|
int ret;
|
||||||
|
pr_info("Googlevideo detected\n");
|
||||||
|
|
||||||
|
ip4_set_checksum(iph);
|
||||||
|
tcp4_set_checksum(tcph, iph);
|
||||||
|
|
||||||
uint32_t f1len = skb->len;
|
uint32_t f1len = skb->len;
|
||||||
uint32_t f2len = skb->len;
|
uint32_t f2len = skb->len;
|
||||||
__u8 *frag1 = kmalloc(f1len, GFP_KERNEL);
|
__u8 *frag1 = kmalloc(f1len, GFP_ATOMIC);
|
||||||
__u8 *frag2 = kmalloc(f2len, GFP_KERNEL);
|
if (!frag1) {
|
||||||
|
pr_err("Cannot alloc enough gv frag1 buffer space");
|
||||||
|
goto ac_fkb;
|
||||||
|
}
|
||||||
|
__u8 *frag2 = kmalloc(f2len, GFP_ATOMIC);
|
||||||
|
if (!frag2) {
|
||||||
|
pr_err("Cannot alloc enough gv frag1 buffer space");
|
||||||
|
kfree(frag1);
|
||||||
|
goto ac_fkb;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_TCP_SEGMENTATION
|
|
||||||
|
#ifdef FAKE_SNI
|
||||||
|
uint32_t fksn_len = FAKE_SNI_MAXLEN;
|
||||||
|
__u8 *fksn_buf = kmalloc(fksn_len, GFP_ATOMIC);
|
||||||
|
if (!fksn_buf) {
|
||||||
|
pr_err("Cannot alloc enough gksn buffer space");
|
||||||
|
goto fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gen_fake_sni(iph, tcph, fksn_buf, &fksn_len);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("Cannot alloc enough gksn buffer space");
|
||||||
|
goto fksn_fb;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_TCP_SEGMENTATION)
|
||||||
size_t ipd_offset = vrd.sni_offset;
|
size_t ipd_offset = vrd.sni_offset;
|
||||||
size_t mid_offset = ipd_offset + vrd.sni_len / 2;
|
size_t mid_offset = ipd_offset + vrd.sni_len / 2;
|
||||||
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
if ((ret = tcp4_frag(buf, skb->len,
|
if ((ret = tcp4_frag(buf, skb->len,
|
||||||
mid_offset, frag1, &f1len, frag2, &f2len)) < 0) {
|
mid_offset, frag1, &f1len, frag2, &f2len)) < 0) {
|
||||||
pr_err("tcp4_frag");
|
pr_err("tcp4_frag: %d", ret);
|
||||||
|
goto fksn_fb;
|
||||||
}
|
}
|
||||||
|
#elif defined(USE_IP_FRAGMENTATION)
|
||||||
if ((ret = send_raw_socket(frag2, f2len) < 0) ||
|
size_t ipd_offset = tcph_len + vrd.sni_offset;
|
||||||
(ret = send_raw_socket(frag1, f1len) < 0)) {
|
|
||||||
pr_err("raw frags send");
|
|
||||||
goto fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
// TODO: Implement ip fragmentation
|
|
||||||
/*
|
|
||||||
// TODO: Implement compute of tcp checksum
|
|
||||||
// GSO may turn kernel to not compute the tcp checksum.
|
|
||||||
// Also it will never be meaningless to ensure the
|
|
||||||
// checksum is right.
|
|
||||||
// nfq_tcp_compute_checksum_ipv4(tcph, ip_header);
|
|
||||||
|
|
||||||
size_t ipd_offset = ((char *)data - (char *)tcph) + vrd.sni_offset;
|
|
||||||
size_t mid_offset = ipd_offset + vrd.sni_len / 2;
|
size_t mid_offset = ipd_offset + vrd.sni_len / 2;
|
||||||
mid_offset += 8 - mid_offset % 8;
|
mid_offset += 8 - mid_offset % 8;
|
||||||
|
|
||||||
if ((errno = ip4_frag(raw_payload, raw_payload_len,
|
if ((ret = ip4_frag(buf, skb->len,
|
||||||
mid_offset, frag1, &f1len, frag2, &f2len)) < 0) {
|
mid_offset, frag1, &f1len, frag2, &f2len)) < 0) {
|
||||||
errno *= -1;
|
pr_err("ip4_frag: %d", ret);
|
||||||
perror("ip4_frag");
|
goto fksn_fb;
|
||||||
goto fallback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((send_raw_socket(frag2, f2len) < 0) ||
|
|
||||||
(send_raw_socket(frag1, f1len) < 0)) {
|
|
||||||
perror("raw frags send");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FAKE_SNI
|
||||||
|
ret = send_raw_socket(fksn_buf, fksn_len);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("fksn_send: %d", ret);
|
||||||
|
goto fksn_fb;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_NO_FRAGMENTATION)
|
||||||
|
#ifdef SEG2_DELAY
|
||||||
|
#error "SEG2_DELAY is incompatible with NO FRAGMENTATION"
|
||||||
|
#endif
|
||||||
|
ret = send_raw_socket(buf, buflen);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("nofrag_send: %d", ret);
|
||||||
|
}
|
||||||
|
goto fksn_fb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = send_raw_socket(frag2, f2len);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("raw frag2 send: %d", ret);
|
||||||
|
goto fksn_fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SEG2_DELAY
|
||||||
|
#error "Seg2 delay is unsupported yet for kmod"
|
||||||
|
#else
|
||||||
|
ret = send_raw_socket(frag1, f1len);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("raw frag1 send: %d", ret);
|
||||||
|
goto fksn_fb;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fksn_fb:
|
||||||
|
#ifdef FAKE_SNI
|
||||||
|
kfree(fksn_buf);
|
||||||
|
#endif
|
||||||
fallback:
|
fallback:
|
||||||
|
#ifndef SEG2_DELAY
|
||||||
kfree(frag1);
|
kfree(frag1);
|
||||||
|
#endif
|
||||||
kfree(frag2);
|
kfree(frag2);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
return XT_CONTINUE;
|
kfree_skb(skb);
|
||||||
// return NF_DROP;
|
return NF_STOLEN;
|
||||||
}
|
}
|
||||||
ac_fkb:
|
ac_fkb:
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
94
mangle.c
94
mangle.c
@ -1,61 +1,10 @@
|
|||||||
#include "mangle.h"
|
#include "mangle.h"
|
||||||
#include "raw_replacements.h"
|
#include "raw_replacements.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef KERNEL_SPACE
|
#ifdef KERNEL_SPACE
|
||||||
#include <linux/printk.h>
|
#include <linux/printk.h>
|
||||||
|
#include <linux/ip.h>
|
||||||
static __u16 nfq_checksum(__u32 sum, __u16 *buf, int size)
|
|
||||||
{
|
|
||||||
while (size > 1) {
|
|
||||||
sum += *buf++;
|
|
||||||
size -= sizeof(__u16);
|
|
||||||
}
|
|
||||||
if (size) {
|
|
||||||
#ifdef __LITTLE_ENDIAN
|
|
||||||
sum += (uint16_t)*(uint8_t *)buf << 8;
|
|
||||||
#else
|
|
||||||
sum += (__u16)*(__u8 *)buf;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
sum = (sum >> 16) + (sum & 0xffff);
|
|
||||||
sum += (sum >> 16);
|
|
||||||
|
|
||||||
return (__u16)(~sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __u16 nfq_checksum_tcpudp_ipv4(struct iphdr *iph, __u16 protonum)
|
|
||||||
{
|
|
||||||
__u32 sum = 0;
|
|
||||||
__u32 iph_len = iph->ihl*4;
|
|
||||||
__u32 len = ntohs(iph->tot_len) - iph_len;
|
|
||||||
__u8 *payload = (__u8 *)iph + iph_len;
|
|
||||||
|
|
||||||
sum += (iph->saddr >> 16) & 0xFFFF;
|
|
||||||
sum += (iph->saddr) & 0xFFFF;
|
|
||||||
sum += (iph->daddr >> 16) & 0xFFFF;
|
|
||||||
sum += (iph->daddr) & 0xFFFF;
|
|
||||||
sum += htons(protonum);
|
|
||||||
sum += htons(len);
|
|
||||||
|
|
||||||
return nfq_checksum(sum, (__u16 *)payload, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nfq_ip_set_checksum(struct iphdr *iph)
|
|
||||||
{
|
|
||||||
__u32 iph_len = iph->ihl * 4;
|
|
||||||
|
|
||||||
iph->check = 0;
|
|
||||||
iph->check = nfq_checksum(0, (__u16 *)iph, iph_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nfq_tcp_compute_checksum_ipv4(struct tcphdr *tcph, struct iphdr *iph)
|
|
||||||
{
|
|
||||||
/* checksum field in header needs to be zero for calculation. */
|
|
||||||
tcph->check = 0;
|
|
||||||
tcph->check = nfq_checksum_tcpudp_ipv4(iph, IPPROTO_TCP);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define printf pr_info
|
#define printf pr_info
|
||||||
#define perror pr_err
|
#define perror pr_err
|
||||||
@ -69,9 +18,33 @@ typedef uint8_t __u8;
|
|||||||
typedef uint32_t __u32;
|
typedef uint32_t __u32;
|
||||||
typedef uint16_t __u16;
|
typedef uint16_t __u16;
|
||||||
|
|
||||||
#define lgerror(msg, ret) ({errno = -ret; perror(msg);})
|
#define lgerror(msg, ret) __extension__ ({errno = -ret; perror(msg);})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void tcp4_set_checksum(struct tcphdr *tcph, struct iphdr *iph)
|
||||||
|
{
|
||||||
|
#ifdef KERNEL_SPACE
|
||||||
|
uint32_t tcp_packet_len = ntohs(iph->tot_len) - (iph->ihl << 2);
|
||||||
|
tcph->check = 0;
|
||||||
|
tcph->check = csum_tcpudp_magic(
|
||||||
|
iph->saddr, iph->daddr, tcp_packet_len,
|
||||||
|
IPPROTO_TCP,
|
||||||
|
csum_partial(tcph, tcp_packet_len, 0));
|
||||||
|
#else
|
||||||
|
nfq_tcp_compute_checksum_ipv4(tcph, iph);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ip4_set_checksum(struct iphdr *iph)
|
||||||
|
{
|
||||||
|
#ifdef KERNEL_SPACE
|
||||||
|
iph->check = 0;
|
||||||
|
iph->check = ip_fast_csum(iph, iph->ihl);
|
||||||
|
#else
|
||||||
|
nfq_ip_set_checksum(iph);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int ip4_payload_split(__u8 *pkt, __u32 buflen,
|
int ip4_payload_split(__u8 *pkt, __u32 buflen,
|
||||||
struct iphdr **iph, __u32 *iph_len,
|
struct iphdr **iph, __u32 *iph_len,
|
||||||
@ -219,8 +192,8 @@ int ip4_frag(const __u8 *pkt, __u32 buflen, __u32 payload_offset,
|
|||||||
printf("Packet split in portion %u %u\n", f1_plen, f2_plen);
|
printf("Packet split in portion %u %u\n", f1_plen, f2_plen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nfq_ip_set_checksum(f1_hdr);
|
ip4_set_checksum(f1_hdr);
|
||||||
nfq_ip_set_checksum(f2_hdr);
|
ip4_set_checksum(f2_hdr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -297,8 +270,9 @@ int tcp4_frag(const __u8 *pkt, __u32 buflen, __u32 payload_offset,
|
|||||||
printf("Packet split in portion %u %u\n", s1_plen, s2_plen);
|
printf("Packet split in portion %u %u\n", s1_plen, s2_plen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nfq_tcp_compute_checksum_ipv4(s1_tcph, s1_hdr);
|
tcp4_set_checksum(s1_tcph, s1_hdr);
|
||||||
nfq_tcp_compute_checksum_ipv4(s2_tcph, s2_hdr);
|
tcp4_set_checksum(s2_tcph, s2_hdr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,8 +455,8 @@ int gen_fake_sni(const struct iphdr *iph, const struct tcphdr *tcph,
|
|||||||
ntcph->th_sport = tcph->th_sport;
|
ntcph->th_sport = tcph->th_sport;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nfq_ip_set_checksum(niph);
|
ip4_set_checksum(niph);
|
||||||
nfq_tcp_compute_checksum_ipv4(ntcph, niph);
|
tcp4_set_checksum(ntcph, niph);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
3
mangle.h
3
mangle.h
@ -59,6 +59,9 @@ int tcp4_payload_split(uint8_t *pkt, uint32_t buflen,
|
|||||||
struct tcphdr **tcph, uint32_t *tcph_len,
|
struct tcphdr **tcph, uint32_t *tcph_len,
|
||||||
uint8_t **payload, uint32_t *plen);
|
uint8_t **payload, uint32_t *plen);
|
||||||
|
|
||||||
|
void tcp4_set_checksum(struct tcphdr *tcph, struct iphdr *iph);
|
||||||
|
void ip4_set_checksum(struct iphdr *iph);
|
||||||
|
|
||||||
int gen_fake_sni(const struct iphdr *iph, const struct tcphdr *tcph,
|
int gen_fake_sni(const struct iphdr *iph, const struct tcphdr *tcph,
|
||||||
uint8_t *buf, uint32_t *buflen);
|
uint8_t *buf, uint32_t *buflen);
|
||||||
#endif /* YU_MANGLE_H */
|
#endif /* YU_MANGLE_H */
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef RAW_REPLACEMENTS_H
|
#ifndef RAW_REPLACEMENTS_H
|
||||||
#define RAW_REPLACEMENTS_H
|
#define RAW_REPLACEMENTS_H
|
||||||
|
|
||||||
const char fake_sni[] = "\276(\001\273\366\234|\335\213\222\023\330\200\030\001\366\350e\000\000\001\001\b\n}\355\267Hm/\217\347\026\003\001\004\316\001\000\004\312\003\003K+\272\314\340\306\374>dw%\f\223\346\225\270\270~\335\027\f\264\341H\267\357\303\216T\322[\371 \245\320\212V6\374\3706\232\0216B\325\273P\b\300>\0332>\362\323\033\322\301\204\022f8\223\214\000\"\023\001\023\003\023\002\300+\300/\314\251\314\250\300,\3000\300\n\300\t\300\023\300\024\000\234\000\235\000/\0005\001\000\004_\000\000\000\023\000\021\000\000\016www.google.com\000\027\000\000\377\001\000\001\000\000\n\000\016\000\f\000\035\000\027\000\030\000\031\001\000\001\001\000\v\000\002\001\000\000\020\000\v\000\t\bhttp/1.1\000\005\000\005\001\000\000\000\000\000\"\000\n\000\b\004\003\005\003\006\003\002\003\0003\000k\000i\000\035\000 \333C\212\234-\t\237#\202\\\231\311\022]\333\341t(\t\276U\373u\234\316J~,^|*Z\000\027\000A\004k\n\255\254\376X\226t\001;n~\033\034.\245\027\024\3762_\352$\374\346^f\fF,\201\275\263\336O\231\001\032\200\357dI\266y\031\323\311vR\232\004\r\366FT\004\335\326\356\256\230B\t\313\000*\000\000\000+\000\005\004\003\004\003\003\000\r\000\030\000\026\004\003\005\003\006\003\b\004\b\005\b\006\004\001\005\001\006\001\002\003\002\001\000-\000\002\001\001\000\034\000\002@\001\376\r\0029\000\000\001\000\003\344\000 \337\306\243\332Y\033\a\252\352\025\365Z\035\223\226\304\255\363\215G\356g\344%}7\217\033n\211^\201\002\017g\267\334\326OD}\336\341ZC\230\226'\225\313\357\211\\\242\273\030k\216\377U\315\206\2410\200\203\332Z\223\005\370\b\304\370f\017\200\023\241\223~?\270{\037b\312\001\270\227\366\356\352\002\314\351\006\237\241q\226\300\314\321o\247{\201\317\230}B\005T\3660\335\320\332r?S\217\tq\036\031\326I|\237]\311 c\f\024r\031\310W\373\257\314q)q\030\237\261\227\217Kd?\257'G\320\020\340\256ND\247\005\341\324\024OP>\370\350\270b\311wAj\t\311\213\365i\203\230x\207\354\245<\274\202\230c\v0Y\263\364\022\303a\200\022\031\314\271rl=\327\336\001\327\264\267\342\353\352=\354[u\224\260\257\034\004\232\023\226}\227\030e\221\"\350\207\027dId\324\305\362N:\035\307`\204\337\201;\221\320\266b\362hrH\345e\206\246%\006\020a4\3430\036\225\215\274\275\360Q&\271\237)\222uK\362\017o\220\226W\357\267#\357\v\023\354\213\2629\331\ad\005/~6k\000[\247\301\270\310qJ\004\303|m5\363\376Y\002\243}6\251x\024\331)GH\335\205rI\032\f\210\a\212\347]\271\030\347.\021\213\365\026\030\340/Ny\r\332\3577\3203\026iX}>\2507\327&XRXU!\017\270I\313\352\350^?\352Uss\017\266pF\222NI\245\307_\305#\361\352\243+-\266\317Q\036s\243\277\355{S&\023>\275\360\215\032V\237XOY\345u>\002\305\252T\354\035\327v{P\352M\233\366\221\270\377\251\261f+rF\201wL2W\266X\252\242X\2536I\337c\205uZ\254Fe\305h\t\371\376\216r\336Y\327h\347*\331\257-ZQ{(\336\226\206\017\037\036\021\341\027z\033\254\235\252\227\224\004?p\243\351\\\263\352\205\327#W\345\255\256\375\267bP\3047\363!*K\003t\212(\306\214P\215\3506j\025\375\213e\254s\000)\001\034\000\367\000\361\002\276W%\232?\326\223\277\211v\017\a\361\347\312N\226\024L\260v\210\271j\324[|\270\344\3773\321-\313b>~\310\253XIR\324)&;\033{g;)\344\255\226\370\347I\\y\020\324\360\211vC\310\226s\267|\273$\341\332\2045qh\245w\2255\214\316\030\255\301\326C\343\304=\245\231h`yd\000#s\002\370\374Z\0336\245\361\226\222\306\032k\2457\016h\314(R;\326T~EHH\352\307\023^\247\363\321`V\340\253Z\233\357\227I\373\337z\177\nv\261\252\371\017\226\223\345\005\315y4\b\236N0\2630\017\215c\305&L\260\346J\237\203Q(\335W\027|>\3553\275j\307?W5\3463kc\350\262C\361 \037w!\371}\214\"I\377|\331@a;\342\3566\312\272Z\327u7\204'\215YBLL\235\236\242\345\215\245T\211a\312\263\342\000! \221\202X$\302\317\203\246\207c{\231\330\264\324\\k\271\272\336\356\002|\261O\207\030+\367P\317\356";
|
#define FAKE_SNI_MAXLEN 1500
|
||||||
|
|
||||||
|
#define fake_sni "\276(\001\273\366\234|\335\213\222\023\330\200\030\001\366\350e\000\000\001\001\b\n}\355\267Hm/\217\347\026\003\001\004\316\001\000\004\312\003\003K+\272\314\340\306\374>dw%\f\223\346\225\270\270~\335\027\f\264\341H\267\357\303\216T\322[\371 \245\320\212V6\374\3706\232\0216B\325\273P\b\300>\0332>\362\323\033\322\301\204\022f8\223\214\000\"\023\001\023\003\023\002\300+\300/\314\251\314\250\300,\3000\300\n\300\t\300\023\300\024\000\234\000\235\000/\0005\001\000\004_\000\000\000\023\000\021\000\000\016www.google.com\000\027\000\000\377\001\000\001\000\000\n\000\016\000\f\000\035\000\027\000\030\000\031\001\000\001\001\000\v\000\002\001\000\000\020\000\v\000\t\bhttp/1.1\000\005\000\005\001\000\000\000\000\000\"\000\n\000\b\004\003\005\003\006\003\002\003\0003\000k\000i\000\035\000 \333C\212\234-\t\237#\202\\\231\311\022]\333\341t(\t\276U\373u\234\316J~,^|*Z\000\027\000A\004k\n\255\254\376X\226t\001;n~\033\034.\245\027\024\3762_\352$\374\346^f\fF,\201\275\263\336O\231\001\032\200\357dI\266y\031\323\311vR\232\004\r\366FT\004\335\326\356\256\230B\t\313\000*\000\000\000+\000\005\004\003\004\003\003\000\r\000\030\000\026\004\003\005\003\006\003\b\004\b\005\b\006\004\001\005\001\006\001\002\003\002\001\000-\000\002\001\001\000\034\000\002@\001\376\r\0029\000\000\001\000\003\344\000 \337\306\243\332Y\033\a\252\352\025\365Z\035\223\226\304\255\363\215G\356g\344%}7\217\033n\211^\201\002\017g\267\334\326OD}\336\341ZC\230\226'\225\313\357\211\\\242\273\030k\216\377U\315\206\2410\200\203\332Z\223\005\370\b\304\370f\017\200\023\241\223~?\270{\037b\312\001\270\227\366\356\352\002\314\351\006\237\241q\226\300\314\321o\247{\201\317\230}B\005T\3660\335\320\332r?S\217\tq\036\031\326I|\237]\311 c\f\024r\031\310W\373\257\314q)q\030\237\261\227\217Kd?\257'G\320\020\340\256ND\247\005\341\324\024OP>\370\350\270b\311wAj\t\311\213\365i\203\230x\207\354\245<\274\202\230c\v0Y\263\364\022\303a\200\022\031\314\271rl=\327\336\001\327\264\267\342\353\352=\354[u\224\260\257\034\004\232\023\226}\227\030e\221\"\350\207\027dId\324\305\362N:\035\307`\204\337\201;\221\320\266b\362hrH\345e\206\246%\006\020a4\3430\036\225\215\274\275\360Q&\271\237)\222uK\362\017o\220\226W\357\267#\357\v\023\354\213\2629\331\ad\005/~6k\000[\247\301\270\310qJ\004\303|m5\363\376Y\002\243}6\251x\024\331)GH\335\205rI\032\f\210\a\212\347]\271\030\347.\021\213\365\026\030\340/Ny\r\332\3577\3203\026iX}>\2507\327&XRXU!\017\270I\313\352\350^?\352Uss\017\266pF\222NI\245\307_\305#\361\352\243+-\266\317Q\036s\243\277\355{S&\023>\275\360\215\032V\237XOY\345u>\002\305\252T\354\035\327v{P\352M\233\366\221\270\377\251\261f+rF\201wL2W\266X\252\242X\2536I\337c\205uZ\254Fe\305h\t\371\376\216r\336Y\327h\347*\331\257-ZQ{(\336\226\206\017\037\036\021\341\027z\033\254\235\252\227\224\004?p\243\351\\\263\352\205\327#W\345\255\256\375\267bP\3047\363!*K\003t\212(\306\214P\215\3506j\025\375\213e\254s\000)\001\034\000\367\000\361\002\276W%\232?\326\223\277\211v\017\a\361\347\312N\226\024L\260v\210\271j\324[|\270\344\3773\321-\313b>~\310\253XIR\324)&;\033{g;)\344\255\226\370\347I\\y\020\324\360\211vC\310\226s\267|\273$\341\332\2045qh\245w\2255\214\316\030\255\301\326C\343\304=\245\231h`yd\000#s\002\370\374Z\0336\245\361\226\222\306\032k\2457\016h\314(R;\326T~EHH\352\307\023^\247\363\321`V\340\253Z\233\357\227I\373\337z\177\nv\261\252\371\017\226\223\345\005\315y4\b\236N0\2630\017\215c\305&L\260\346J\237\203Q(\335W\027|>\3553\275j\307?W5\3463kc\350\262C\361 \037w!\371}\214\"I\377|\331@a;\342\3566\312\272Z\327u7\204'\215YBLL\235\236\242\345\215\245T\211a\312\263\342\000! \221\202X$\302\317\203\246\207c{\231\330\264\324\\k\271\272\336\356\002|\261O\207\030+\367P\317\356"
|
||||||
|
|
||||||
#endif /*RAW_REPLACEMENTS_H*/
|
#endif /*RAW_REPLACEMENTS_H*/
|
||||||
|
@ -110,13 +110,13 @@ static int open_raw_socket(void) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int one = 1;
|
// int one = 1;
|
||||||
const int *val = &one;
|
// const int *val = &one;
|
||||||
if (setsockopt(config.rawsocket, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)
|
// if (setsockopt(config.rawsocket, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)
|
||||||
{
|
// {
|
||||||
fprintf(stderr, "setsockopt(IP_HDRINCL, 1) failed\n");
|
// fprintf(stderr, "setsockopt(IP_HDRINCL, 1) failed\n");
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
int mark = RAWSOCKET_MARK;
|
int mark = RAWSOCKET_MARK;
|
||||||
if (setsockopt(config.rawsocket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
|
if (setsockopt(config.rawsocket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user