40 #define XFF_CHAIN_MINLEN 7
42 #define XFF_CHAIN_MAXLEN 256
44 #define XFF_DEFAULT "X-Forwarded-For"
53 static int ParseXFFString(
char *input,
char *output,
int output_size)
55 size_t len = strlen(input);
59 if (input[0] ==
'[') {
60 char *end = strchr(input,
']');
64 if (end != input+(
len - 1)) {
86 if (d == 3 && c == 1) {
88 char *x = strchr(input,
':');
101 if (inet_pton(AF_INET, input, ip) == 1 ||
102 inet_pton(AF_INET6, input, ip) == 1)
104 strlcpy(output, input, output_size);
110 static int HttpXFFGetIPFromTxAux(
111 const Flow *f, htp_tx_t *tx,
HttpXFFCfg *xff_cfg,
char *dstbuf,
int dstbuflen)
114 uint8_t *p_xff = NULL;
116 const htp_header_t *h_xff = htp_tx_request_header(tx, xff_cfg->
header);
121 memcpy(xff_chain, htp_header_value_ptr(h_xff), htp_header_value_len(h_xff));
122 xff_chain[htp_header_value_len(h_xff)] = 0;
126 p_xff =
memrchr(xff_chain,
' ', htp_header_value_len(h_xff));
135 p_xff = memchr(xff_chain,
',', htp_header_value_len(h_xff));
141 return ParseXFFString((
char *)p_xff, dstbuf, dstbuflen);
153 const Flow *f, uint64_t tx_id,
HttpXFFCfg *xff_cfg,
char *dstbuf,
int dstbuflen)
156 uint64_t total_txs = 0;
159 htp_state = (
HtpState *)FlowGetAppState(f);
161 if (htp_state == NULL) {
162 SCLogDebug(
"no http state, XFF IP cannot be retrieved");
167 if (tx_id >= total_txs)
172 SCLogDebug(
"tx is NULL, XFF cannot be retrieved");
175 return HttpXFFGetIPFromTxAux(f, tx, xff_cfg, dstbuf, dstbuflen);
187 uint64_t total_txs = 0;
189 htp_state = (
HtpState *)FlowGetAppState(f);
190 if (htp_state == NULL) {
191 SCLogDebug(
"no http state, XFF IP cannot be retrieved");
198 memset(&state, 0,
sizeof(state));
203 if (ires.tx_ptr == NULL)
206 if (HttpXFFGetIPFromTxAux(f, ires.tx_ptr, xff_cfg, dstbuf, dstbuflen) == 1)
209 tx_id = ires.tx_id + 1;
231 if (xff_mode != NULL && strcasecmp(xff_mode,
"overwrite") == 0) {
234 if (xff_mode == NULL) {
235 SCLogWarning(
"The XFF mode hasn't been defined, falling back to extra-data mode");
237 else if (strcasecmp(xff_mode,
"extra-data") != 0) {
239 "The XFF mode %s is invalid, falling back to extra-data mode", xff_mode);
246 if (xff_deployment != NULL && strcasecmp(xff_deployment,
"forward") == 0) {
249 if (xff_deployment == NULL) {
250 SCLogWarning(
"The XFF deployment hasn't been defined, falling back to reverse "
253 else if (strcasecmp(xff_deployment,
"reverse") != 0) {
254 SCLogWarning(
"The XFF mode %s is invalid, falling back to reverse proxy deployment",
262 if (xff_header != NULL) {
263 result->
header = (
char *) xff_header;
275 static int XFFTest01(
void) {
276 char input[] =
"1.2.3.4:5678";
278 int r = ParseXFFString(input, output,
sizeof(output));
279 FAIL_IF_NOT(r == 1 && strcmp(output,
"1.2.3.4") == 0);
283 static int XFFTest02(
void) {
284 char input[] =
"[12::34]:1234";
286 int r = ParseXFFString(input, output,
sizeof(output));
287 FAIL_IF_NOT(r == 1 && strcmp(output,
"12::34") == 0);
291 static int XFFTest03(
void) {
292 char input[] =
"[2a03:2880:1010:3f02:face:b00c:0:2]:80";
294 int r = ParseXFFString(input, output,
sizeof(output));
295 FAIL_IF_NOT(r == 1 && strcmp(output,
"2a03:2880:1010:3f02:face:b00c:0:2") == 0);
299 static int XFFTest04(
void) {
300 char input[] =
"[2a03:2880:1010:3f02:face:b00c:0:2]";
302 int r = ParseXFFString(input, output,
sizeof(output));
303 FAIL_IF_NOT(r == 1 && strcmp(output,
"2a03:2880:1010:3f02:face:b00c:0:2") == 0);
307 static int XFFTest05(
void) {
308 char input[] =
"[::ffff:1.2.3.4]:1234";
310 int r = ParseXFFString(input, output,
sizeof(output));
311 FAIL_IF_NOT(r == 1 && strcmp(output,
"::ffff:1.2.3.4") == 0);
315 static int XFFTest06(
void) {
316 char input[] =
"12::34";
318 int r = ParseXFFString(input, output,
sizeof(output));
319 FAIL_IF_NOT(r == 1 && strcmp(output,
"12::34") == 0);
323 static int XFFTest07(
void) {
324 char input[] =
"1.2.3.4";
326 int r = ParseXFFString(input, output,
sizeof(output));
327 FAIL_IF_NOT(r == 1 && strcmp(output,
"1.2.3.4") == 0);
331 static int XFFTest08(
void) {
332 char input[] =
"[1.2.3.4:1234";
334 int r = ParseXFFString(input, output,
sizeof(output));
339 static int XFFTest09(
void) {
340 char input[] =
"999.999.999.999:1234";
342 int r = ParseXFFString(input, output,
sizeof(output));