Skip to content

Commit a9cacaa

Browse files
feat: Add support for hostname rotation
1 parent ff2021f commit a9cacaa

4 files changed

Lines changed: 60 additions & 9 deletions

File tree

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
/* -d */ int daemon;
3636
/* -f */ int skipfw;
3737
/* -g */ int nohopest;
38-
/* -h */ const char *hostname;
38+
/* -h */ const char *hostname[32];
3939
/* -i */ const char *iface[32];
4040
/* -k */ int killproc;
4141
/* -m */ uint32_t fwmark;

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
/* -d */ .daemon = 0,
3636
/* -f */ .skipfw = 0,
3737
/* -g */ .nohopest = 0,
38-
/* -h */ .hostname = NULL,
38+
/* -h */ .hostname = {NULL},
3939
/* -i */ .iface = {NULL},
4040
/* -k */ .killproc = 0,
4141
/* -m */ .fwmark = 0x8000,

src/mainfun.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ int main(int argc, char *argv[])
9191
{
9292
unsigned long long tmp;
9393
int res, opt, exitcode;
94-
size_t iface_cnt;
94+
size_t hname_cnt, iface_cnt;
9595
const char *iface_info, *direction_info, *ipproto_info;
9696

9797
if (!argc || !argv[0]) {
@@ -102,7 +102,8 @@ int main(int argc, char *argv[])
102102
return EXIT_FAILURE;
103103
}
104104

105-
iface_cnt = 0;
105+
hname_cnt = iface_cnt = 0;
106+
memset(g_ctx.hostname, 0, sizeof(g_ctx.hostname));
106107
memset(g_ctx.iface, 0, sizeof(g_ctx.iface));
107108
exitcode = EXIT_FAILURE;
108109

@@ -152,12 +153,29 @@ int main(int argc, char *argv[])
152153
break;
153154

154155
case 'h':
156+
hname_cnt++;
157+
if (hname_cnt >
158+
sizeof(g_ctx.hostname) / sizeof(*g_ctx.hostname)) {
159+
fprintf(stderr, "%s: too many hostnames specified.\n",
160+
argv[0]);
161+
print_usage(argv[0]);
162+
return EXIT_FAILURE;
163+
}
164+
165+
if (!optarg[0]) {
166+
fprintf(stderr, "%s: hostname cannot be empty.\n",
167+
argv[0]);
168+
print_usage(argv[0]);
169+
return EXIT_FAILURE;
170+
}
171+
155172
if (strlen(optarg) > _POSIX_HOST_NAME_MAX) {
156173
fprintf(stderr, "%s: hostname is too long.\n", argv[0]);
157174
print_usage(argv[0]);
158175
return EXIT_FAILURE;
159176
}
160-
g_ctx.hostname = optarg;
177+
178+
g_ctx.hostname[hname_cnt - 1] = optarg;
161179
break;
162180

163181
case 'i':
@@ -302,7 +320,7 @@ int main(int argc, char *argv[])
302320
return EXIT_FAILURE;
303321
}
304322

305-
if (!g_ctx.payloadpath && !g_ctx.hostname) {
323+
if (!g_ctx.payloadpath && !hname_cnt) {
306324
fprintf(stderr, "%s: option -h is required.\n", argv[0]);
307325
print_usage(argv[0]);
308326
return EXIT_FAILURE;

src/rawsend.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,34 @@ static void ipaddr_to_str(struct sockaddr *addr, char ipstr[INET6_ADDRSTRLEN])
7878
}
7979

8080

81-
static int setup_http_buff(void)
81+
static int setup_http_buff(int rotate)
8282
{
83+
static const size_t maxcnt = sizeof(g_ctx.hostname) /
84+
sizeof(*g_ctx.hostname);
8385
static const char *http_fmt = "GET / HTTP/1.1\r\n"
8486
"Host: %s\r\n"
8587
"Accept: */*\r\n"
8688
"\r\n";
89+
static size_t i = 0;
8790

8891
FILE *fp;
8992
int res;
9093

9194
if (!g_ctx.payloadpath) {
92-
http_len = snprintf(http_buff, HTTP_BUFSIZ, http_fmt, g_ctx.hostname);
95+
http_len = snprintf(http_buff, HTTP_BUFSIZ, http_fmt,
96+
g_ctx.hostname[i]);
9397
if (http_len < 0 || (size_t) http_len >= HTTP_BUFSIZ) {
9498
E("ERROR: snprintf(): %s", "failure");
9599
return -1;
96100
}
97101

102+
if (rotate) {
103+
i++;
104+
if (i == maxcnt || !g_ctx.hostname[i]) {
105+
i = 0;
106+
}
107+
}
108+
98109
return 0;
99110
}
100111

@@ -131,6 +142,22 @@ static int setup_http_buff(void)
131142
}
132143

133144

145+
static int rotate_hostname(void)
146+
{
147+
int res;
148+
149+
if (!g_ctx.payloadpath && g_ctx.hostname[1]) {
150+
res = setup_http_buff(1);
151+
if (res < 0) {
152+
E(T(setup_http_buff));
153+
return -1;
154+
}
155+
}
156+
157+
return 0;
158+
}
159+
160+
134161
static int send_ack(struct sockaddr_ll *sll, struct sockaddr *saddr,
135162
struct sockaddr *daddr, uint8_t ttl, uint16_t sport_be,
136163
uint16_t dport_be, uint32_t seq_be, uint32_t ackseq_be)
@@ -222,7 +249,7 @@ int fh_rawsend_setup(void)
222249
return -1;
223250
}
224251

225-
res = setup_http_buff();
252+
res = setup_http_buff(0);
226253
if (res < 0) {
227254
E(T(setup_http_buff));
228255
goto free_buff;
@@ -377,6 +404,12 @@ int fh_rawsend_handle(struct sockaddr_ll *sll, uint8_t *pkt_data, int pkt_len)
377404
E_INFO("%s:%u <===ACK(*)=== %s:%u", src_ip, ntohs(tcph->source),
378405
dst_ip, ntohs(tcph->dest));
379406

407+
res = rotate_hostname();
408+
if (res < 0) {
409+
E(T(rotate_hostname));
410+
return -1;
411+
}
412+
380413
for (i = 0; i < g_ctx.repeat; i++) {
381414
res = send_http(sll, daddr, saddr, snd_ttl, tcph->dest,
382415
tcph->source, tcph->ack_seq, ack_new);

0 commit comments

Comments
 (0)