Skip to content

Commit 47860d7

Browse files
feat: Add support for multiple interfaces
1 parent 0da2079 commit 47860d7

File tree

7 files changed

+228
-63
lines changed

7 files changed

+228
-63
lines changed

include/globvar.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct fh_context {
3535
/* -f */ int skipfw;
3636
/* -g */ int nohopest;
3737
/* -h */ const char *hostname;
38-
/* -i */ const char *iface;
38+
/* -i */ const char *iface[32];
3939
/* -k */ int killproc;
4040
/* -m */ uint32_t fwmark;
4141
/* -n */ uint32_t nfqnum;

src/globvar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct fh_context g_ctx = {.exit = 0,
3535
/* -f */ .skipfw = 0,
3636
/* -g */ .nohopest = 0,
3737
/* -h */ .hostname = NULL,
38-
/* -i */ .iface = NULL,
38+
/* -i */ .iface = {NULL},
3939
/* -k */ .killproc = 0,
4040
/* -m */ .fwmark = 0x8000,
4141
/* -n */ .nfqnum = 512,

src/ipv4ipt.c

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,43 @@
2222

2323
#include <inttypes.h>
2424
#include <stdlib.h>
25+
#include <net/if.h>
2526

2627
#include "globvar.h"
2728
#include "logging.h"
2829
#include "process.h"
2930

31+
static int ipt4_iface_setup(void)
32+
{
33+
char iface_str[IFNAMSIZ];
34+
size_t i, cnt;
35+
int res;
36+
char *ipt_iface_cmd[] = {"iptables", "-w", "-t", "mangle",
37+
"-A", "FAKEHTTP", "-i", iface_str,
38+
"-j", "FAKEHTTP_R", NULL};
39+
40+
cnt = sizeof(g_ctx.iface) / sizeof(*g_ctx.iface);
41+
42+
for (i = 0; i < cnt && g_ctx.iface[i]; i++) {
43+
res = snprintf(iface_str, sizeof(iface_str), "%s", g_ctx.iface[i]);
44+
if (res < 0 || (size_t) res >= sizeof(iface_str)) {
45+
E("ERROR: snprintf(): %s", "failure");
46+
return -1;
47+
}
48+
49+
res = fh_execute_command(ipt_iface_cmd, 0, NULL);
50+
if (res < 0) {
51+
E(T(fh_execute_command));
52+
return -1;
53+
}
54+
}
55+
return 0;
56+
}
57+
58+
3059
int fh_ipt4_setup(void)
3160
{
32-
char xmark_str[64], nfqnum_str[32], iface_str[32];
61+
char xmark_str[64], nfqnum_str[32];
3362
size_t i, ipt_cmds_cnt, ipt_opt_cmds_cnt;
3463
int res;
3564
char *ipt_cmds[][32] = {
@@ -38,65 +67,68 @@ int fh_ipt4_setup(void)
3867
{"iptables", "-w", "-t", "mangle", "-I", "PREROUTING", "-j",
3968
"FAKEHTTP", NULL},
4069

70+
{"iptables", "-w", "-t", "mangle", "-N", "FAKEHTTP_R", NULL},
71+
4172
/*
4273
exclude marked packets
4374
*/
44-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-m", "mark",
75+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-m", "mark",
4576
"--mark", xmark_str, "-j", "CONNMARK", "--set-xmark", xmark_str,
4677
NULL},
4778

48-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-m", "connmark",
49-
"--mark", xmark_str, "-j", "MARK", "--set-xmark", xmark_str, NULL},
79+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-m",
80+
"connmark", "--mark", xmark_str, "-j", "MARK", "--set-xmark",
81+
xmark_str, NULL},
5082

51-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-m", "mark",
83+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-m", "mark",
5284
"--mark", xmark_str, "-j", "RETURN", NULL},
5385

5486
/*
5587
exclude local IPs
5688
*/
57-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-s", "0.0.0.0/8",
58-
"-j", "RETURN", NULL},
89+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-s",
90+
"0.0.0.0/8", "-j", "RETURN", NULL},
5991

60-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-s",
92+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-s",
6193
"10.0.0.0/8", "-j", "RETURN", NULL},
6294

63-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-s",
95+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-s",
6496
"100.64.0.0/10", "-j", "RETURN", NULL},
6597

66-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-s",
98+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-s",
6799
"127.0.0.0/8", "-j", "RETURN", NULL},
68100

69-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-s",
101+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-s",
70102
"169.254.0.0/16", "-j", "RETURN", NULL},
71103

72-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-s",
104+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-s",
73105
"172.16.0.0/12", "-j", "RETURN", NULL},
74106

75-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-s",
107+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-s",
76108
"192.168.0.0/16", "-j", "RETURN", NULL},
77109

78-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-s",
110+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-s",
79111
"224.0.0.0/3", "-j", "RETURN", NULL},
80112

81113
/*
82114
send to nfqueue
83115
*/
84-
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP", "-i", iface_str,
85-
"-p", "tcp", "--tcp-flags", "ACK,FIN,RST", "ACK", "-j", "NFQUEUE",
116+
{"iptables", "-w", "-t", "mangle", "-A", "FAKEHTTP_R", "-p", "tcp",
117+
"--tcp-flags", "ACK,FIN,RST", "ACK", "-j", "NFQUEUE",
86118
"--queue-bypass", "--queue-num", nfqnum_str, NULL}};
87119

88120
char *ipt_opt_cmds[][32] = {
89121
/*
90122
exclude packets from connections with more than 32 packets
91123
*/
92-
{"iptables", "-w", "-t", "mangle", "-I", "FAKEHTTP", "-m", "connbytes",
93-
"!", "--connbytes", "0:32", "--connbytes-dir", "both",
124+
{"iptables", "-w", "-t", "mangle", "-I", "FAKEHTTP_R", "-m",
125+
"connbytes", "!", "--connbytes", "0:32", "--connbytes-dir", "both",
94126
"--connbytes-mode", "packets", "-j", "RETURN", NULL},
95127

96128
/*
97129
exclude big packets
98130
*/
99-
{"iptables", "-w", "-t", "mangle", "-I", "FAKEHTTP", "-m", "length",
131+
{"iptables", "-w", "-t", "mangle", "-I", "FAKEHTTP_R", "-m", "length",
100132
"!", "--length", "0:120", "-j", "RETURN", NULL}};
101133

102134
ipt_cmds_cnt = sizeof(ipt_cmds) / sizeof(*ipt_cmds);
@@ -115,12 +147,6 @@ int fh_ipt4_setup(void)
115147
return -1;
116148
}
117149

118-
res = snprintf(iface_str, sizeof(iface_str), "%s", g_ctx.iface);
119-
if (res < 0 || (size_t) res >= sizeof(iface_str)) {
120-
E("ERROR: snprintf(): %s", "failure");
121-
return -1;
122-
}
123-
124150
fh_ipt4_cleanup();
125151

126152
for (i = 0; i < ipt_cmds_cnt; i++) {
@@ -135,6 +161,12 @@ int fh_ipt4_setup(void)
135161
fh_execute_command(ipt_opt_cmds[i], 1, NULL);
136162
}
137163

164+
res = ipt4_iface_setup();
165+
if (res < 0) {
166+
E(T(ipt4_iface_setup));
167+
return -1;
168+
}
169+
138170
return 0;
139171
}
140172

@@ -143,6 +175,8 @@ void fh_ipt4_cleanup(void)
143175
{
144176
size_t i, cnt;
145177
char *ipt_cmds[][32] = {
178+
{"iptables", "-w", "-t", "mangle", "-F", "FAKEHTTP_R", NULL},
179+
146180
{"iptables", "-w", "-t", "mangle", "-F", "FAKEHTTP", NULL},
147181

148182
{"iptables", "-w", "-t", "mangle", "-D", "PREROUTING", "-j",
@@ -160,6 +194,8 @@ void fh_ipt4_cleanup(void)
160194
{"iptables", "-w", "-t", "mangle", "-D", "POSTROUTING", "-j",
161195
"FAKEHTTP", NULL},
162196

197+
{"iptables", "-w", "-t", "mangle", "-X", "FAKEHTTP_R", NULL},
198+
163199
{"iptables", "-w", "-t", "mangle", "-X", "FAKEHTTP", NULL}};
164200

165201
cnt = sizeof(ipt_cmds) / sizeof(*ipt_cmds);

src/ipv4nft.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,35 @@
2727
#include "logging.h"
2828
#include "process.h"
2929

30+
static int nft4_iface_setup(void)
31+
{
32+
char nftstr[120];
33+
size_t i, cnt;
34+
int res;
35+
char *nft_iface_cmd[] = {"nft", nftstr, NULL};
36+
37+
cnt = sizeof(g_ctx.iface) / sizeof(*g_ctx.iface);
38+
39+
for (i = 0; i < cnt && g_ctx.iface[i]; i++) {
40+
res = snprintf(
41+
nftstr, sizeof(nftstr),
42+
"add rule ip fakehttp fh_prerouting iifname \"%s\" jump fh_rules",
43+
g_ctx.iface[i]);
44+
if (res < 0 || (size_t) res >= sizeof(nftstr)) {
45+
E("ERROR: snprintf(): %s", "failure");
46+
return -1;
47+
}
48+
49+
res = fh_execute_command(nft_iface_cmd, 0, NULL);
50+
if (res < 0) {
51+
E(T(fh_execute_command));
52+
return -1;
53+
}
54+
}
55+
return 0;
56+
}
57+
58+
3059
int fh_nft4_setup(void)
3160
{
3261
size_t i, nft_opt_cmds_cnt;
@@ -38,7 +67,6 @@ int fh_nft4_setup(void)
3867
" chain fh_prerouting {\n"
3968
" type filter hook prerouting priority mangle - 5;\n"
4069
" policy accept;\n"
41-
" jump fh_rules;\n"
4270
" }\n"
4371
"\n"
4472
" chain fh_rules {\n"
@@ -69,8 +97,8 @@ int fh_nft4_setup(void)
6997
/*
7098
send to nfqueue
7199
*/
72-
" iifname \"%s\" tcp flags & (fin | rst | ack) == ack queue "
73-
"num %" PRIu32 " bypass;\n"
100+
" tcp flags & (fin | rst | ack) == ack queue num %" PRIu32
101+
" bypass;\n"
74102

75103
" }\n"
76104
"}\n";
@@ -93,7 +121,7 @@ int fh_nft4_setup(void)
93121
res = snprintf(nft_conf_buff, sizeof(nft_conf_buff), nft_conf_fmt,
94122
g_ctx.fwmask, g_ctx.fwmark, ~g_ctx.fwmask, g_ctx.fwmark,
95123
g_ctx.fwmask, g_ctx.fwmark, ~g_ctx.fwmask, g_ctx.fwmark,
96-
g_ctx.fwmask, g_ctx.fwmark, g_ctx.iface, g_ctx.nfqnum);
124+
g_ctx.fwmask, g_ctx.fwmark, g_ctx.nfqnum);
97125
if (res < 0 || (size_t) res >= sizeof(nft_conf_buff)) {
98126
E("ERROR: snprintf(): %s", "failure");
99127
return -1;
@@ -111,6 +139,12 @@ int fh_nft4_setup(void)
111139
fh_execute_command(nft_opt_cmds[i], 1, NULL);
112140
}
113141

142+
res = nft4_iface_setup();
143+
if (res < 0) {
144+
E(T(nft4_iface_setup));
145+
return -1;
146+
}
147+
114148
return 0;
115149
}
116150

0 commit comments

Comments
 (0)