mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2026-01-31 14:40:36 +03:00
Use mallocs instead of NETBUF_ALLOC
malloc won't hurt when youtubeUnblock is processing the packet. But it is better for kmod and a way cleaner than NETBUF_ALLOC defines.
This commit is contained in:
@@ -195,21 +195,21 @@ static int send_raw_socket(const uint8_t *pkt, size_t pktlen) {
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (pktlen > AVAILABLE_MTU) {
|
if (pktlen > AVAILABLE_MTU) {
|
||||||
lgdebug("The packet is too big and may cause issues!");
|
lgtrace("Split packet!");
|
||||||
|
|
||||||
NETBUF_ALLOC(buff1, MAX_PACKET_SIZE);
|
size_t buff1_size = pktlen;
|
||||||
if (!NETBUF_CHECK(buff1)) {
|
uint8_t *buff1 = malloc(buff1_size);
|
||||||
|
if (buff1 == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
NETBUF_ALLOC(buff2, MAX_PACKET_SIZE);
|
size_t buff2_size = pktlen;
|
||||||
if (!NETBUF_CHECK(buff2)) {
|
uint8_t *buff2 = malloc(buff2_size);
|
||||||
|
if (buff2 == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
NETBUF_FREE(buff2);
|
free(buff1);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
size_t buff1_size = MAX_PACKET_SIZE;
|
|
||||||
size_t buff2_size = MAX_PACKET_SIZE;
|
|
||||||
|
|
||||||
if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
||||||
buff1, &buff1_size, buff2, &buff2_size)) < 0) {
|
buff1, &buff1_size, buff2, &buff2_size)) < 0) {
|
||||||
@@ -231,12 +231,12 @@ static int send_raw_socket(const uint8_t *pkt, size_t pktlen) {
|
|||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETBUF_FREE(buff1);
|
free(buff1);
|
||||||
NETBUF_FREE(buff2);
|
free(buff2);
|
||||||
return sent;
|
return sent;
|
||||||
erret_lc:
|
erret_lc:
|
||||||
NETBUF_FREE(buff1);
|
free(buff1);
|
||||||
NETBUF_FREE(buff2);
|
free(buff2);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
216
src/mangle.c
216
src/mangle.c
@@ -211,33 +211,33 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
|
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto accept;
|
return PKT_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As defined by TLS standard.
|
// As defined by TLS standard.
|
||||||
if (section->dport_filter && ntohs(tcph->dest) != 443) {
|
if (section->dport_filter && ntohs(tcph->dest) != 443) {
|
||||||
goto accept;
|
return PKT_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcph->syn && section->synfake) {
|
if (tcph->syn && section->synfake) {
|
||||||
lgtrace_addp("TCP syn alter");
|
lgtrace_addp("TCP syn alter");
|
||||||
|
|
||||||
NETBUF_ALLOC(payload, MAX_PACKET_SIZE);
|
size_t fake_len = section->fake_sni_pkt_sz;
|
||||||
if (!NETBUF_CHECK(payload)) {
|
if (section->synfake_len)
|
||||||
|
fake_len = min(section->synfake_len, fake_len);
|
||||||
|
|
||||||
|
|
||||||
|
size_t payload_len = iph_len + tcph_len + fake_len;
|
||||||
|
uint8_t *payload = malloc(payload_len);
|
||||||
|
if (payload == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
goto accept;
|
return PKT_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(payload, ipxh, iph_len);
|
memcpy(payload, ipxh, iph_len);
|
||||||
memcpy(payload + iph_len, tcph, tcph_len);
|
memcpy(payload + iph_len, tcph, tcph_len);
|
||||||
size_t fake_len = section->fake_sni_pkt_sz;
|
|
||||||
|
|
||||||
if (section->synfake_len)
|
|
||||||
fake_len = min(section->synfake_len, fake_len);
|
|
||||||
|
|
||||||
memcpy(payload + iph_len + tcph_len, section->fake_sni_pkt, fake_len);
|
memcpy(payload + iph_len + tcph_len, section->fake_sni_pkt, fake_len);
|
||||||
|
|
||||||
|
|
||||||
struct tcphdr *tcph = (struct tcphdr *)(payload + iph_len);
|
struct tcphdr *tcph = (struct tcphdr *)(payload + iph_len);
|
||||||
if (ipxv == IP4VERSION) {
|
if (ipxv == IP4VERSION) {
|
||||||
struct iphdr *iph = (struct iphdr *)payload;
|
struct iphdr *iph = (struct iphdr *)payload;
|
||||||
@@ -252,22 +252,23 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ret = instance_config.send_raw_packet(payload, iph_len + tcph_len + fake_len);
|
ret = instance_config.send_raw_packet(payload, payload_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
lgerror(ret, "send_syn_altered");
|
lgerror(ret, "send_syn_altered");
|
||||||
|
|
||||||
NETBUF_FREE(payload);
|
free(payload);
|
||||||
goto accept;
|
return PKT_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETBUF_FREE(payload);
|
free(payload);
|
||||||
goto drop;
|
return PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcph->syn) goto continue_flow;
|
if (tcph->syn)
|
||||||
|
return PKT_CONTINUE;
|
||||||
|
|
||||||
if (!section->tls_enabled)
|
if (!section->tls_enabled)
|
||||||
goto continue_flow;
|
return PKT_CONTINUE;
|
||||||
|
|
||||||
struct tls_verdict vrd = analyze_tls_data(section, data, dlen);
|
struct tls_verdict vrd = analyze_tls_data(section, data, dlen);
|
||||||
lgtrace_addp("TLS analyzed");
|
lgtrace_addp("TLS analyzed");
|
||||||
@@ -282,12 +283,11 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
size_t target_sni_offset = vrd.target_sni_ptr - data;
|
size_t target_sni_offset = vrd.target_sni_ptr - data;
|
||||||
|
|
||||||
size_t payload_len = raw_payload_len;
|
size_t payload_len = raw_payload_len;
|
||||||
NETBUF_ALLOC(payload, MAX_PACKET_SIZE);
|
uint8_t *payload = malloc(raw_payload_len);
|
||||||
if (!NETBUF_CHECK(payload)) {
|
if (payload == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
goto accept;
|
return PKT_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(payload, raw_payload, raw_payload_len);
|
memcpy(payload, raw_payload, raw_payload_len);
|
||||||
|
|
||||||
void *iph;
|
void *iph;
|
||||||
@@ -311,6 +311,7 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
set_tcp_checksum(tcph, iph, iph_len);
|
set_tcp_checksum(tcph, iph, iph_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (0) {
|
if (0) {
|
||||||
int delta = 2;
|
int delta = 2;
|
||||||
ret = seqovl_packet(payload, &payload_len, delta);
|
ret = seqovl_packet(payload, &payload_len, delta);
|
||||||
@@ -321,9 +322,9 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
lgerror(ret, "seqovl_packet delta %d", delta);
|
lgerror(ret, "seqovl_packet delta %d", delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dlen > AVAILABLE_MTU) {
|
||||||
if (dlen > 1480 && config.verbose) {
|
|
||||||
lgdebug("WARNING! Client Hello packet is too big and may cause issues!");
|
lgdebug("WARNING! Client Hello packet is too big and may cause issues!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +336,8 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
size_t mid_offset;
|
size_t mid_offset;
|
||||||
|
|
||||||
switch (section->fragmentation_strategy) {
|
switch (section->fragmentation_strategy) {
|
||||||
case FRAG_STRAT_TCP: {
|
case FRAG_STRAT_TCP:
|
||||||
|
{
|
||||||
ipd_offset = target_sni_offset;
|
ipd_offset = target_sni_offset;
|
||||||
mid_offset = ipd_offset + vrd.target_sni_len / 2;
|
mid_offset = ipd_offset + vrd.target_sni_len / 2;
|
||||||
|
|
||||||
@@ -401,7 +403,9 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
lginfo("WARNING: IP fragmentation is supported only for IPv4");
|
lginfo("WARNING: IP fragmentation is supported only for IPv4");
|
||||||
goto default_send;
|
goto default_send;
|
||||||
}
|
}
|
||||||
default:
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default_send:
|
default_send:
|
||||||
ret = instance_config.send_raw_packet(payload, payload_len);
|
ret = instance_config.send_raw_packet(payload, payload_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -409,28 +413,17 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
goto accept_lc;
|
goto accept_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto drop_lc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
goto drop_lc;
|
goto drop_lc;
|
||||||
|
|
||||||
accept_lc:
|
accept_lc:
|
||||||
NETBUF_FREE(payload);
|
free(payload);
|
||||||
goto accept;
|
return PKT_ACCEPT;
|
||||||
drop_lc:
|
drop_lc:
|
||||||
NETBUF_FREE(payload);
|
free(payload);
|
||||||
goto drop;
|
return PKT_DROP;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
continue_flow:
|
|
||||||
return PKT_CONTINUE;
|
return PKT_CONTINUE;
|
||||||
accept:
|
|
||||||
return PKT_ACCEPT;
|
|
||||||
drop:
|
|
||||||
return PKT_DROP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int process_udp_packet(const struct section_config_t *section, const uint8_t *pkt, size_t pktlen) {
|
int process_udp_packet(const struct section_config_t *section, const uint8_t *pkt, size_t pktlen) {
|
||||||
@@ -458,12 +451,8 @@ int process_udp_packet(const struct section_config_t *section, const uint8_t *pk
|
|||||||
goto drop;
|
goto drop;
|
||||||
else if (section->udp_mode == UDP_MODE_FAKE) {
|
else if (section->udp_mode == UDP_MODE_FAKE) {
|
||||||
for (int i = 0; i < section->udp_fake_seq_len; i++) {
|
for (int i = 0; i < section->udp_fake_seq_len; i++) {
|
||||||
NETBUF_ALLOC(fake_udp, MAX_PACKET_SIZE);
|
uint8_t *fake_udp;
|
||||||
if (!NETBUF_CHECK(fake_udp)) {
|
size_t fake_udp_len;
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
size_t fsn_len = MAX_PACKET_SIZE;
|
|
||||||
|
|
||||||
struct udp_fake_type fake_type = {
|
struct udp_fake_type fake_type = {
|
||||||
.fake_len = section->udp_fake_len,
|
.fake_len = section->udp_fake_len,
|
||||||
@@ -472,24 +461,25 @@ int process_udp_packet(const struct section_config_t *section, const uint8_t *pk
|
|||||||
.faking_ttl = section->faking_ttl,
|
.faking_ttl = section->faking_ttl,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ret = gen_fake_udp(fake_type, iph, iph_len, udph, fake_udp, &fsn_len);
|
ret = gen_fake_udp(fake_type, iph, iph_len, udph, &fake_udp, &fake_udp_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
lgerror(ret, "gen_fake_udp");
|
lgerror(ret, "gen_fake_udp");
|
||||||
goto erret_lc;
|
goto erret;
|
||||||
}
|
}
|
||||||
|
|
||||||
lgtrace_addp("post fake udp #%d", i + 1);
|
lgtrace_addp("post fake udp #%d", i + 1);
|
||||||
|
|
||||||
ret = instance_config.send_raw_packet(fake_udp, fsn_len);
|
ret = instance_config.send_raw_packet(fake_udp, fake_udp_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
lgerror(ret, "send fake udp");
|
lgerror(ret, "send fake udp");
|
||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETBUF_FREE(fake_udp);
|
free(fake_udp);
|
||||||
continue;
|
continue;
|
||||||
erret_lc:
|
erret_lc:
|
||||||
NETBUF_FREE(fake_udp);
|
free(fake_udp);
|
||||||
|
erret:
|
||||||
goto accept;
|
goto accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,33 +514,21 @@ int send_ip4_frags(const struct section_config_t *section, const uint8_t *packet
|
|||||||
packet, pktlen);
|
packet, pktlen);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NETBUF_ALLOC(frag1, MAX_PACKET_SIZE);
|
size_t f1len = pktlen;
|
||||||
if (!NETBUF_CHECK(frag1)) {
|
uint8_t *frag1 = malloc(f1len);
|
||||||
|
if (frag1 == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETBUF_ALLOC(frag2, MAX_PACKET_SIZE);
|
size_t f2len = pktlen;
|
||||||
if (!NETBUF_CHECK(frag2)) {
|
uint8_t *frag2 = malloc(f2len);
|
||||||
|
if (frag2 == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
NETBUF_FREE(frag1);
|
free(frag1);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
NETBUF_ALLOC(fake_pad, MAX_PACKET_SIZE);
|
|
||||||
if (!NETBUF_CHECK(fake_pad)) {
|
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
|
||||||
NETBUF_FREE(frag1);
|
|
||||||
NETBUF_FREE(frag2);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
size_t f1len = MAX_PACKET_SIZE;
|
|
||||||
size_t f2len = MAX_PACKET_SIZE;
|
|
||||||
// size_t fake_pad_len = MAX_PACKET_SIZE;
|
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (dvs > poses[0]) {
|
if (dvs > poses[0]) {
|
||||||
@@ -570,8 +548,6 @@ int send_ip4_frags(const struct section_config_t *section, const uint8_t *packet
|
|||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
dvs += frag_pos;
|
|
||||||
|
|
||||||
if (section->frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto send_frag2;
|
goto send_frag2;
|
||||||
send_frag1:
|
send_frag1:
|
||||||
@@ -583,54 +559,22 @@ send_frag1:
|
|||||||
if (section->frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto out_lc;
|
goto out_lc;
|
||||||
|
|
||||||
send_fake:
|
send_frag2:
|
||||||
/*
|
ret = send_ip4_frags(section, frag2, f2len, poses + 1, poses_sz - 1, poses[0]);
|
||||||
if (section->frag_sni_faked) {
|
|
||||||
ITER_FAKE_STRAT(section->faking_strategy, strategy) {
|
|
||||||
size_t iphfl;
|
|
||||||
fake_pad_len = f2len;
|
|
||||||
ret = ip4_payload_split(frag2, f2len, NULL, &iphfl, NULL, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
lgerror("Invalid frag2", ret);
|
|
||||||
goto erret_lc;
|
|
||||||
}
|
|
||||||
memcpy(fake_pad, frag2, iphfl + sizeof(struct udphdr));
|
|
||||||
memset(fake_pad + iphfl + sizeof(struct udphdr), 0, f2len - iphfl - sizeof(struct udphdr));
|
|
||||||
((struct iphdr *)fake_pad)->tot_len = htons(fake_pad_len);
|
|
||||||
((struct iphdr *)fake_pad)->id = 1;
|
|
||||||
((struct iphdr *)fake_pad)->ttl = 8;
|
|
||||||
((struct iphdr *)fake_pad)->frag_off = 0;
|
|
||||||
ip4_set_checksum((struct iphdr*)fake_pad);
|
|
||||||
// *(struct udphdr *)(fake_pad + iphfl) = *(struct udphdr *)(frag2 + iphfl);
|
|
||||||
ret = send_ip4_frags(fake_pad, fake_pad_len, NULL, 0, 0);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (section->frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto send_frag1;
|
goto send_frag1;
|
||||||
|
|
||||||
send_frag2:
|
|
||||||
ret = send_ip4_frags(section, frag2, f2len, poses + 1, poses_sz - 1, dvs);
|
|
||||||
if (ret < 0) {
|
|
||||||
goto erret_lc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (section->frag_sni_reverse)
|
|
||||||
goto send_fake;
|
|
||||||
|
|
||||||
out_lc:
|
out_lc:
|
||||||
NETBUF_FREE(frag1);
|
free(frag1);
|
||||||
NETBUF_FREE(frag2);
|
free(frag2);
|
||||||
// NETBUF_FREE(fake_pad);
|
|
||||||
goto out;
|
goto out;
|
||||||
erret_lc:
|
erret_lc:
|
||||||
NETBUF_FREE(frag1);
|
free(frag1);
|
||||||
NETBUF_FREE(frag2);
|
free(frag2);
|
||||||
// NETBUF_FREE(fake_pad);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,22 +600,21 @@ int send_tcp_frags(const struct section_config_t *section, const uint8_t *packet
|
|||||||
packet, pktlen);
|
packet, pktlen);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NETBUF_ALLOC(frag1, MAX_PACKET_SIZE);
|
size_t f1len = pktlen;
|
||||||
if (!NETBUF_CHECK(frag1)) {
|
uint8_t *frag1 = malloc(f1len);
|
||||||
|
if (frag1 == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETBUF_ALLOC(frag2, MAX_PACKET_SIZE);
|
size_t f2len = pktlen;
|
||||||
if (!NETBUF_CHECK(frag2)) {
|
uint8_t *frag2 = malloc(f2len);
|
||||||
|
if (frag2 == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
NETBUF_FREE(frag1);
|
free(frag1);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t f1len = MAX_PACKET_SIZE;
|
|
||||||
size_t f2len = MAX_PACKET_SIZE;
|
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (dvs > poses[0]) {
|
if (dvs > poses[0]) {
|
||||||
@@ -680,7 +623,6 @@ int send_tcp_frags(const struct section_config_t *section, const uint8_t *packet
|
|||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ret = tcp_frag(packet, pktlen, poses[0] - dvs,
|
ret = tcp_frag(packet, pktlen, poses[0] - dvs,
|
||||||
frag1, &f1len, frag2, &f2len);
|
frag1, &f1len, frag2, &f2len);
|
||||||
|
|
||||||
@@ -697,7 +639,6 @@ int send_tcp_frags(const struct section_config_t *section, const uint8_t *packet
|
|||||||
goto send_frag2;
|
goto send_frag2;
|
||||||
|
|
||||||
send_frag1:
|
send_frag1:
|
||||||
{
|
|
||||||
ret = send_tcp_frags(section, frag1, f1len, NULL, 0, 0);
|
ret = send_tcp_frags(section, frag1, f1len, NULL, 0, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
@@ -705,7 +646,6 @@ send_frag1:
|
|||||||
|
|
||||||
if (section->frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto out_lc;
|
goto out_lc;
|
||||||
}
|
|
||||||
|
|
||||||
send_fake:
|
send_fake:
|
||||||
if (section->frag_sni_faked) {
|
if (section->frag_sni_faked) {
|
||||||
@@ -729,7 +669,6 @@ send_fake:
|
|||||||
goto send_frag1;
|
goto send_frag1;
|
||||||
|
|
||||||
send_frag2:
|
send_frag2:
|
||||||
{
|
|
||||||
ret = send_tcp_frags(section, frag2, f2len, poses + 1, poses_sz - 1, poses[0]);
|
ret = send_tcp_frags(section, frag2, f2len, poses + 1, poses_sz - 1, poses[0]);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
@@ -737,14 +676,13 @@ send_frag2:
|
|||||||
|
|
||||||
if (section->frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto send_fake;
|
goto send_fake;
|
||||||
}
|
|
||||||
out_lc:
|
out_lc:
|
||||||
NETBUF_FREE(frag1);
|
free(frag1);
|
||||||
NETBUF_FREE(frag2);
|
free(frag2);
|
||||||
goto out;
|
goto out;
|
||||||
erret_lc:
|
erret_lc:
|
||||||
NETBUF_FREE(frag1);
|
free(frag1);
|
||||||
NETBUF_FREE(frag2);
|
free(frag2);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
@@ -773,28 +711,24 @@ int post_fake_sni(struct fake_type f_type,
|
|||||||
|
|
||||||
// one goes for default fake
|
// one goes for default fake
|
||||||
for (int i = 0; i < fake_seq_type.sequence_len; i++) {
|
for (int i = 0; i < fake_seq_type.sequence_len; i++) {
|
||||||
NETBUF_ALLOC(fake_sni, MAX_PACKET_SIZE);
|
uint8_t *fake_sni;
|
||||||
if (!NETBUF_CHECK(fake_sni)) {
|
size_t fake_sni_len;
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
size_t fsn_len = MAX_PACKET_SIZE;
|
|
||||||
|
|
||||||
ret = gen_fake_sni(
|
ret = gen_fake_sni(
|
||||||
fake_seq_type,
|
fake_seq_type,
|
||||||
fsiph, iph_len, fstcph, tcph_len,
|
fsiph, iph_len, fstcph, tcph_len,
|
||||||
fake_sni, &fsn_len);
|
&fake_sni, &fake_sni_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
lgerror(ret, "gen_fake_sni");
|
lgerror(ret, "gen_fake_sni");
|
||||||
goto erret_lc;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
lgtrace_addp("post fake sni #%d", i + 1);
|
lgtrace_addp("post fake sni #%d", i + 1);
|
||||||
|
|
||||||
if (f_type.seg2delay) {
|
if (f_type.seg2delay) {
|
||||||
ret = instance_config.send_delayed_packet(fake_sni, fsn_len, f_type.seg2delay);
|
ret = instance_config.send_delayed_packet(fake_sni, fake_sni_len, f_type.seg2delay);
|
||||||
} else {
|
} else {
|
||||||
ret = instance_config.send_raw_packet(fake_sni, fsn_len);
|
ret = instance_config.send_raw_packet(fake_sni, fake_sni_len);
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
lgerror(ret, "send fake sni");
|
lgerror(ret, "send fake sni");
|
||||||
@@ -804,7 +738,7 @@ int post_fake_sni(struct fake_type f_type,
|
|||||||
size_t tcph_len;
|
size_t tcph_len;
|
||||||
size_t plen;
|
size_t plen;
|
||||||
ret = tcp_payload_split(
|
ret = tcp_payload_split(
|
||||||
fake_sni, fsn_len,
|
fake_sni, fake_sni_len,
|
||||||
&fsiph, &iph_len,
|
&fsiph, &iph_len,
|
||||||
&fstcph, &tcph_len,
|
&fstcph, &tcph_len,
|
||||||
NULL, &plen);
|
NULL, &plen);
|
||||||
@@ -830,10 +764,10 @@ int post_fake_sni(struct fake_type f_type,
|
|||||||
fsiph = (void *)rfsiph;
|
fsiph = (void *)rfsiph;
|
||||||
fstcph = (void *)rfstcph;
|
fstcph = (void *)rfstcph;
|
||||||
|
|
||||||
NETBUF_FREE(fake_sni);
|
free(fake_sni);
|
||||||
continue;
|
continue;
|
||||||
erret_lc:
|
erret_lc:
|
||||||
NETBUF_FREE(fake_sni);
|
free(fake_sni);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
src/quic.c
37
src/quic.c
@@ -285,14 +285,26 @@ int udp_fail_packet(struct udp_failing_strategy strategy, uint8_t *payload, size
|
|||||||
int gen_fake_udp(struct udp_fake_type type,
|
int gen_fake_udp(struct udp_fake_type type,
|
||||||
const void *ipxh, size_t iph_len,
|
const void *ipxh, size_t iph_len,
|
||||||
const struct udphdr *udph,
|
const struct udphdr *udph,
|
||||||
uint8_t *buf, size_t *buflen) {
|
uint8_t **ubuf, size_t *ubuflen) {
|
||||||
size_t data_len = type.fake_len;
|
size_t data_len = type.fake_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!ipxh || !udph || !buf || !buflen)
|
if (!ipxh || !udph || !ubuf || !ubuflen)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
int ipxv = netproto_version(ipxh, iph_len);
|
int ipxv = netproto_version(ipxh, iph_len);
|
||||||
|
|
||||||
|
if (ipxv == IP6VERSION) {
|
||||||
|
iph_len = sizeof(struct ip6_hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t dlen = iph_len + sizeof(struct udphdr) + data_len;
|
||||||
|
size_t buffer_len = dlen + 50;
|
||||||
|
uint8_t *buf = malloc(buffer_len);
|
||||||
|
if (buf == NULL) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
if (ipxv == IP4VERSION) {
|
if (ipxv == IP4VERSION) {
|
||||||
const struct iphdr *iph = ipxh;
|
const struct iphdr *iph = ipxh;
|
||||||
|
|
||||||
@@ -303,20 +315,15 @@ int gen_fake_udp(struct udp_fake_type type,
|
|||||||
} else if (ipxv == IP6VERSION) {
|
} else if (ipxv == IP6VERSION) {
|
||||||
const struct ip6_hdr *iph = ipxh;
|
const struct ip6_hdr *iph = ipxh;
|
||||||
|
|
||||||
iph_len = sizeof(struct ip6_hdr);
|
|
||||||
memcpy(buf, iph, iph_len);
|
memcpy(buf, iph, iph_len);
|
||||||
struct ip6_hdr *niph = (struct ip6_hdr *)buf;
|
struct ip6_hdr *niph = (struct ip6_hdr *)buf;
|
||||||
|
|
||||||
niph->ip6_nxt = IPPROTO_UDP;
|
niph->ip6_nxt = IPPROTO_UDP;
|
||||||
} else {
|
} else {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t dlen = iph_len + sizeof(struct udphdr) + data_len;
|
|
||||||
|
|
||||||
if (*buflen < dlen)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memcpy(buf + iph_len, udph, sizeof(struct udphdr));
|
memcpy(buf + iph_len, udph, sizeof(struct udphdr));
|
||||||
uint8_t *bfdptr = buf + iph_len + sizeof(struct udphdr);
|
uint8_t *bfdptr = buf + iph_len + sizeof(struct udphdr);
|
||||||
|
|
||||||
@@ -336,11 +343,19 @@ int gen_fake_udp(struct udp_fake_type type,
|
|||||||
|
|
||||||
set_udp_checksum(nudph, buf, iph_len);
|
set_udp_checksum(nudph, buf, iph_len);
|
||||||
|
|
||||||
udp_fail_packet(type.strategy, buf, &dlen, *buflen);
|
ret = udp_fail_packet(type.strategy, buf, &dlen, buffer_len);
|
||||||
|
if (ret < 0) {
|
||||||
|
lgerror(ret, "udp_fail_packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
*buflen = dlen;
|
*ubuflen = dlen;
|
||||||
|
*ubuf = buf;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
error:
|
||||||
|
free(buf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_quic_decrypted(
|
int parse_quic_decrypted(
|
||||||
|
|||||||
@@ -234,11 +234,11 @@ int parse_quic_decrypted(
|
|||||||
// Like fail_packet for TCP
|
// Like fail_packet for TCP
|
||||||
int udp_fail_packet(struct udp_failing_strategy strategy, uint8_t *payload, size_t *plen, size_t avail_buflen);
|
int udp_fail_packet(struct udp_failing_strategy strategy, uint8_t *payload, size_t *plen, size_t avail_buflen);
|
||||||
|
|
||||||
// Like gen_fake_sni for TCP
|
// Like gen_fake_sni for TCP, Allocates and generates udp fake
|
||||||
int gen_fake_udp(struct udp_fake_type type,
|
int gen_fake_udp(struct udp_fake_type type,
|
||||||
const void *ipxh, size_t iph_len,
|
const void *ipxh, size_t iph_len,
|
||||||
const struct udphdr *udph,
|
const struct udphdr *udph,
|
||||||
uint8_t *buf, size_t *buflen);
|
uint8_t **buf, size_t *buflen);
|
||||||
|
|
||||||
int detect_udp_filtered(const struct section_config_t *section,
|
int detect_udp_filtered(const struct section_config_t *section,
|
||||||
const uint8_t *payload, size_t plen);
|
const uint8_t *payload, size_t plen);
|
||||||
|
|||||||
90
src/tls.c
90
src/tls.c
@@ -41,27 +41,28 @@ int bruteforce_analyze_sni_str(
|
|||||||
vrd->sni_ptr = data + dlen / 2;
|
vrd->sni_ptr = data + dlen / 2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int max_domain_len = 0;
|
||||||
|
|
||||||
|
for (struct domains_list *sne = section->sni_domains; sne != NULL;
|
||||||
|
sne = sne->next) {
|
||||||
|
max_domain_len = max(sne->domain_len, max_domain_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t buf_size = max_domain_len + dlen + 1;
|
||||||
|
uint8_t *buf = malloc(buf_size);
|
||||||
|
if (buf == NULL) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
int *nzbuf = malloc(buf_size * sizeof(int));
|
||||||
|
if (nzbuf == NULL) {
|
||||||
|
free(buf);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
for (struct domains_list *sne = section->sni_domains; sne != NULL; sne = sne->next) {
|
for (struct domains_list *sne = section->sni_domains; sne != NULL; sne = sne->next) {
|
||||||
const char *domain_startp = sne->domain_name;
|
const char *domain_startp = sne->domain_name;
|
||||||
int domain_len = sne->domain_len;
|
int domain_len = sne->domain_len;
|
||||||
|
|
||||||
if (sne->domain_len + dlen + 1 > MAX_PACKET_SIZE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
NETBUF_ALLOC(buf, MAX_PACKET_SIZE);
|
|
||||||
if (!NETBUF_CHECK(buf)) {
|
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
NETBUF_ALLOC(nzbuf, MAX_PACKET_SIZE * sizeof(int));
|
|
||||||
if (!NETBUF_CHECK(nzbuf)) {
|
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
|
||||||
NETBUF_FREE(buf);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
int *zbuf = (void *)nzbuf;
|
int *zbuf = (void *)nzbuf;
|
||||||
|
|
||||||
memcpy(buf, domain_startp, domain_len);
|
memcpy(buf, domain_startp, domain_len);
|
||||||
@@ -77,17 +78,13 @@ int bruteforce_analyze_sni_str(
|
|||||||
vrd->sni_ptr = data + (k - domain_len - 1);
|
vrd->sni_ptr = data + (k - domain_len - 1);
|
||||||
vrd->target_sni_ptr = vrd->sni_ptr;
|
vrd->target_sni_ptr = vrd->sni_ptr;
|
||||||
vrd->target_sni_len = vrd->sni_len;
|
vrd->target_sni_len = vrd->sni_len;
|
||||||
NETBUF_FREE(buf);
|
goto return_vrd;
|
||||||
NETBUF_FREE(nzbuf);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NETBUF_FREE(buf);
|
|
||||||
NETBUF_FREE(nzbuf);
|
|
||||||
}
|
}
|
||||||
|
return_vrd:
|
||||||
|
free(buf);
|
||||||
|
free(nzbuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int analyze_sni_str(
|
static int analyze_sni_str(
|
||||||
@@ -319,18 +316,31 @@ out:
|
|||||||
int gen_fake_sni(struct fake_type type,
|
int gen_fake_sni(struct fake_type type,
|
||||||
const void *ipxh, size_t iph_len,
|
const void *ipxh, size_t iph_len,
|
||||||
const struct tcphdr *tcph, size_t tcph_len,
|
const struct tcphdr *tcph, size_t tcph_len,
|
||||||
uint8_t *buf, size_t *buflen) {
|
uint8_t **ubuf, size_t *ubuflen) {
|
||||||
size_t data_len = type.fake_len;
|
size_t data_len = type.fake_len;
|
||||||
|
uint8_t *buf = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (type.type == FAKE_PAYLOAD_RANDOM && data_len == 0) {
|
if (type.type == FAKE_PAYLOAD_RANDOM && data_len == 0) {
|
||||||
data_len = (size_t)randint() % 1200;
|
data_len = (size_t)randint() % 1200;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ipxh || !tcph || !buf || !buflen)
|
if (!ipxh || !tcph || !ubuf || !ubuflen)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
int ipxv = netproto_version(ipxh, iph_len);
|
int ipxv = netproto_version(ipxh, iph_len);
|
||||||
|
|
||||||
|
if (ipxv == IP6VERSION) {
|
||||||
|
iph_len = sizeof(struct ip6_hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t dlen = iph_len + tcph_len + data_len;
|
||||||
|
size_t buffer_len = dlen + 50;
|
||||||
|
buf = malloc(buffer_len);
|
||||||
|
if (buf == NULL) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
if (ipxv == IP4VERSION) {
|
if (ipxv == IP4VERSION) {
|
||||||
const struct iphdr *iph = ipxh;
|
const struct iphdr *iph = ipxh;
|
||||||
|
|
||||||
@@ -341,20 +351,15 @@ int gen_fake_sni(struct fake_type type,
|
|||||||
} else if (ipxv == IP6VERSION) {
|
} else if (ipxv == IP6VERSION) {
|
||||||
const struct ip6_hdr *iph = ipxh;
|
const struct ip6_hdr *iph = ipxh;
|
||||||
|
|
||||||
iph_len = sizeof(struct ip6_hdr);
|
|
||||||
memcpy(buf, iph, iph_len);
|
memcpy(buf, iph, iph_len);
|
||||||
struct ip6_hdr *niph = (struct ip6_hdr *)buf;
|
struct ip6_hdr *niph = (struct ip6_hdr *)buf;
|
||||||
|
|
||||||
niph->ip6_nxt = IPPROTO_TCP;
|
niph->ip6_nxt = IPPROTO_TCP;
|
||||||
} else {
|
} else {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t dlen = iph_len + tcph_len + data_len;
|
|
||||||
|
|
||||||
if (*buflen < dlen)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memcpy(buf + iph_len, tcph, tcph_len);
|
memcpy(buf + iph_len, tcph, tcph_len);
|
||||||
uint8_t *bfdptr = buf + iph_len + tcph_len;
|
uint8_t *bfdptr = buf + iph_len + tcph_len;
|
||||||
|
|
||||||
@@ -391,10 +396,19 @@ int gen_fake_sni(struct fake_type type,
|
|||||||
niph->ip6_plen = htons(dlen - iph_len);
|
niph->ip6_plen = htons(dlen - iph_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
fail_packet(type.strategy, buf, &dlen, *buflen);
|
ret = fail_packet(type.strategy, buf, &dlen, buffer_len);
|
||||||
|
if (ret < 0) {
|
||||||
*buflen = dlen;
|
lgerror(ret, "fail_packet");
|
||||||
|
goto error;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
*ubuflen = dlen;
|
||||||
|
*ubuf = buf;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
free(buf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,11 +75,11 @@ struct tls_verdict analyze_tls_data(const struct section_config_t *section, cons
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the fake client hello message
|
* Allocates and generates the fake client hello message
|
||||||
*/
|
*/
|
||||||
int gen_fake_sni(struct fake_type type,
|
int gen_fake_sni(struct fake_type type,
|
||||||
const void *iph, size_t iph_len,
|
const void *iph, size_t iph_len,
|
||||||
const struct tcphdr *tcph, size_t tcph_len,
|
const struct tcphdr *tcph, size_t tcph_len,
|
||||||
uint8_t *buf, size_t *buflen);
|
uint8_t **ubuf, size_t *ubuflen);
|
||||||
|
|
||||||
#endif /* TLS_H */
|
#endif /* TLS_H */
|
||||||
|
|||||||
25
src/types.h
25
src/types.h
@@ -126,31 +126,6 @@ free((item)); \
|
|||||||
|
|
||||||
#endif /* not a KERNEL_SPACE */
|
#endif /* not a KERNEL_SPACE */
|
||||||
|
|
||||||
/* An alternative memory allocation strategy for userspace app */
|
|
||||||
// #define ALLOC_MALLOC
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use NETBUF_ALLOC and NETBUF_FREE as an abstraction of memory allocation.
|
|
||||||
* Do not use it within expressions, consider these defines as separate statements.
|
|
||||||
*
|
|
||||||
* Use NETBUF_CHECK to check that buffer was properly allocated.
|
|
||||||
*/
|
|
||||||
#ifdef KERNEL_SPACE
|
|
||||||
#include <linux/gfp.h>
|
|
||||||
#define NETBUF_ALLOC(buf, buf_len) __u8* buf = kmalloc(buf_len, GFP_KERNEL);
|
|
||||||
#define NETBUF_CHECK(buf) ((buf) != NULL)
|
|
||||||
#define NETBUF_FREE(buf) kfree(buf);
|
|
||||||
#elif defined(ALLOC_MALLOC)
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define NETBUF_ALLOC(buf, buf_len) __u8* buf = malloc(buf_len);
|
|
||||||
#define NETBUF_CHECK(buf) ((buf) != NULL)
|
|
||||||
#define NETBUF_FREE(buf) free(buf);
|
|
||||||
#else
|
|
||||||
#define NETBUF_ALLOC(buf, buf_len) __u8 buf[buf_len];
|
|
||||||
#define NETBUF_CHECK(buf) (1)
|
|
||||||
#define NETBUF_FREE(buf) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int randint(void) {
|
static inline int randint(void) {
|
||||||
int rnd;
|
int rnd;
|
||||||
|
|
||||||
|
|||||||
@@ -501,50 +501,46 @@ static int send_raw_socket(const uint8_t *pkt, size_t pktlen) {
|
|||||||
if (pktlen > AVAILABLE_MTU) {
|
if (pktlen > AVAILABLE_MTU) {
|
||||||
lgtrace("Split packet!");
|
lgtrace("Split packet!");
|
||||||
|
|
||||||
NETBUF_ALLOC(buff1, MNL_SOCKET_BUFFER_SIZE);
|
size_t buff1_size = pktlen;
|
||||||
if (!NETBUF_CHECK(buff1)) {
|
uint8_t *buff1 = malloc(buff1_size);
|
||||||
|
if (buff1 == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
size_t buff2_size = pktlen;
|
||||||
NETBUF_ALLOC(buff2, MNL_SOCKET_BUFFER_SIZE);
|
uint8_t *buff2 = malloc(buff2_size);
|
||||||
if (!NETBUF_CHECK(buff2)) {
|
if (buff2 == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
NETBUF_FREE(buff1);
|
free(buff1);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t buff1_size = MNL_SOCKET_BUFFER_SIZE;
|
|
||||||
size_t buff2_size = MNL_SOCKET_BUFFER_SIZE;
|
|
||||||
|
|
||||||
if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
||||||
buff1, &buff1_size, buff2, &buff2_size)) < 0) {
|
buff1, &buff1_size, buff2, &buff2_size)) < 0) {
|
||||||
|
|
||||||
errno = -ret;
|
goto erret_lc;
|
||||||
goto free_buffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
int status = send_raw_socket(buff1, buff1_size);
|
ret = send_raw_socket(buff1, buff1_size);
|
||||||
|
|
||||||
if (status >= 0) sent += status;
|
if (ret >= 0) sent += ret;
|
||||||
else {
|
else {
|
||||||
ret = status;
|
goto erret_lc;
|
||||||
goto free_buffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status = send_raw_socket(buff2, buff2_size);
|
ret = send_raw_socket(buff2, buff2_size);
|
||||||
if (status >= 0) sent += status;
|
if (ret >= 0) sent += ret;
|
||||||
else {
|
else {
|
||||||
ret = status;
|
goto erret_lc;
|
||||||
goto free_buffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sent;
|
free(buff1);
|
||||||
|
free(buff2);
|
||||||
free_buffs:
|
return sent;
|
||||||
NETBUF_FREE(buff1)
|
erret_lc:
|
||||||
NETBUF_FREE(buff2)
|
free(buff1);
|
||||||
|
free(buff2);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,7 +551,7 @@ free_buffs:
|
|||||||
} else if (ipvx == IP6VERSION) {
|
} else if (ipvx == IP6VERSION) {
|
||||||
ret = send_raw_ipv6(pkt, pktlen);
|
ret = send_raw_ipv6(pkt, pktlen);
|
||||||
} else {
|
} else {
|
||||||
lginfo("proto version %d is unsupported", ipvx);
|
printf("proto version %d is unsupported\n", ipvx);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,6 +559,7 @@ free_buffs:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Per-queue data. Passed to queue_cb.
|
// Per-queue data. Passed to queue_cb.
|
||||||
struct queue_data {
|
struct queue_data {
|
||||||
struct mnl_socket **_nl;
|
struct mnl_socket **_nl;
|
||||||
@@ -725,12 +722,11 @@ int init_queue(int queue_num) {
|
|||||||
uint32_t portid = mnl_socket_get_portid(nl);
|
uint32_t portid = mnl_socket_get_portid(nl);
|
||||||
|
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
NETBUF_ALLOC(bbuf, BUF_SIZE);
|
char *buf = malloc(BUF_SIZE);
|
||||||
if (!NETBUF_CHECK(bbuf)) {
|
if (buf == NULL) {
|
||||||
lgerror(-ENOMEM, "Allocation error");
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
goto die_alloc;
|
goto die_alloc;
|
||||||
}
|
}
|
||||||
char *buf = (char *)bbuf;
|
|
||||||
|
|
||||||
/* Support for kernels versions < 3.8 */
|
/* Support for kernels versions < 3.8 */
|
||||||
// Obsolete and ignored in kernel version 3.8
|
// Obsolete and ignored in kernel version 3.8
|
||||||
@@ -837,12 +833,12 @@ int init_queue(int queue_num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NETBUF_FREE(bbuf)
|
free(buf);
|
||||||
close_socket(&nl);
|
close_socket(&nl);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
die:
|
die:
|
||||||
NETBUF_FREE(bbuf)
|
free(buf);
|
||||||
die_alloc:
|
die_alloc:
|
||||||
close_socket(&nl);
|
close_socket(&nl);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user