Flowspec: split net_format_flowspec into several functions
This commit is contained in:
parent
2af807a83f
commit
93a3661c15
1 changed files with 147 additions and 121 deletions
266
lib/flowspec.c
266
lib/flowspec.c
|
@ -929,21 +929,6 @@ get_value(const byte *val, u8 len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
is_bitmask(enum flow_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FLOW_TYPE_TCP_FLAGS:
|
||||
case FLOW_TYPE_FRAGMENT:
|
||||
case FLOW_TYPE_LABEL:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
fragment_val_str(u8 val)
|
||||
{
|
||||
|
@ -957,6 +942,147 @@ fragment_val_str(u8 val)
|
|||
return "???";
|
||||
}
|
||||
|
||||
static void
|
||||
net_format_flow_ip(buffer *b, const byte *part, int ipv6)
|
||||
{
|
||||
uint pxlen = *(part+1);
|
||||
if (ipv6)
|
||||
{
|
||||
uint pxoffset = *(part+2);
|
||||
if (pxoffset)
|
||||
buffer_print(b, "%I6/%u offset %u; ", flow_read_ip6(part+3,pxlen,pxoffset), pxlen, pxoffset);
|
||||
else
|
||||
buffer_print(b, "%I6/%u; ", flow_read_ip6(part+3,pxlen,0), pxlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_print(b, "%I4/%u; ", flow_read_ip4(part+2,pxlen), pxlen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
net_format_flow_num(buffer *b, const byte *part)
|
||||
{
|
||||
const byte *last_op = NULL;
|
||||
const byte *op = part+1;
|
||||
u64 val;
|
||||
uint len;
|
||||
uint first = 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
/* XXX: I don't like this so complicated if-tree */
|
||||
if (!isset_and(op) &&
|
||||
((num_op( op) == FLOW_EQ) || (num_op( op) == FLOW_GTE)) &&
|
||||
((num_op(last_op) == FLOW_EQ) || (num_op(last_op) == FLOW_LTE)))
|
||||
{
|
||||
b->pos--; /* Remove last char (it is a space) */
|
||||
buffer_puts(b, ",");
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_puts(b, isset_and(op) ? "&& " : "|| ");
|
||||
}
|
||||
}
|
||||
first = 0;
|
||||
|
||||
len = get_value_length(op);
|
||||
val = get_value(op+1, len);
|
||||
|
||||
if (!isset_end(op) && !isset_and(op) && isset_and(op+1+len) &&
|
||||
(num_op(op) == FLOW_GTE) && (num_op(op+1+len) == FLOW_LTE))
|
||||
{
|
||||
/* Display interval */
|
||||
buffer_print(b, "%u..", val);
|
||||
op += 1 + len;
|
||||
len = get_value_length(op);
|
||||
val = get_value(op+1, len);
|
||||
buffer_print(b, "%u", val);
|
||||
}
|
||||
else if (num_op(op) == FLOW_EQ)
|
||||
{
|
||||
buffer_print(b, "%u", val);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_print(b, "%s %u", num_op_str(op), val);
|
||||
}
|
||||
|
||||
if (isset_end(op))
|
||||
{
|
||||
buffer_puts(b, "; ");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_puts(b, " ");
|
||||
}
|
||||
|
||||
last_op = op;
|
||||
op += 1 + len;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
net_format_flow_bitmask(buffer *b, const byte *part)
|
||||
{
|
||||
const byte *op = part+1;
|
||||
u64 val;
|
||||
uint len;
|
||||
uint first = 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
if (isset_and(op))
|
||||
{
|
||||
b->pos--; /* Remove last char (it is a space) */
|
||||
buffer_puts(b, ",");
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_puts(b, "|| ");
|
||||
}
|
||||
}
|
||||
first = 0;
|
||||
|
||||
len = get_value_length(op);
|
||||
val = get_value(op+1, len);
|
||||
|
||||
/*
|
||||
* Not Match Show
|
||||
* ------------------
|
||||
* 0 0 !0/B
|
||||
* 0 1 B/B
|
||||
* 1 0 0/B
|
||||
* 1 1 !B/B
|
||||
*/
|
||||
|
||||
if ((*op & 0x3) == 0x3 || (*op & 0x3) == 0)
|
||||
buffer_puts(b, "!");
|
||||
|
||||
if (*part == FLOW_TYPE_FRAGMENT && (val == 1 || val == 2 || val == 4 || val == 8))
|
||||
buffer_print(b, "%s%s", ((*op & 0x1) ? "" : "!"), fragment_val_str(val));
|
||||
else
|
||||
buffer_print(b, "0x%x/0x%x", ((*op & 0x1) ? val : 0), val);
|
||||
|
||||
if (isset_end(op))
|
||||
{
|
||||
buffer_puts(b, "; ");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_puts(b, " ");
|
||||
}
|
||||
|
||||
op += 1 + len;
|
||||
}
|
||||
}
|
||||
|
||||
static uint
|
||||
net_format_flow(char *buf, uint blen, const byte *data, uint dlen, int ipv6)
|
||||
{
|
||||
|
@ -982,124 +1108,24 @@ net_format_flow(char *buf, uint blen, const byte *data, uint dlen, int ipv6)
|
|||
{
|
||||
case FLOW_TYPE_DST_PREFIX:
|
||||
case FLOW_TYPE_SRC_PREFIX:
|
||||
{
|
||||
uint pxlen = *(part+1);
|
||||
if (ipv6)
|
||||
{
|
||||
uint pxoffset = *(part+2);
|
||||
if (pxoffset)
|
||||
buffer_print(&b, "%I6/%u offset %u; ", flow_read_ip6(part+3,pxlen,pxoffset), pxlen, pxoffset);
|
||||
else
|
||||
buffer_print(&b, "%I6/%u; ", flow_read_ip6(part+3,pxlen,0), pxlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_print(&b, "%I4/%u; ", flow_read_ip4(part+2,pxlen), pxlen);
|
||||
}
|
||||
net_format_flow_ip(&b, part, ipv6);
|
||||
break;
|
||||
}
|
||||
|
||||
case FLOW_TYPE_IP_PROTOCOL: /* == FLOW_TYPE_NEXT_HEADER */
|
||||
case FLOW_TYPE_PORT:
|
||||
case FLOW_TYPE_DST_PORT:
|
||||
case FLOW_TYPE_SRC_PORT:
|
||||
case FLOW_TYPE_ICMP_TYPE:
|
||||
case FLOW_TYPE_ICMP_CODE:
|
||||
case FLOW_TYPE_TCP_FLAGS:
|
||||
case FLOW_TYPE_PACKET_LENGTH:
|
||||
case FLOW_TYPE_DSCP:
|
||||
net_format_flow_num(&b, part);
|
||||
break;
|
||||
case FLOW_TYPE_TCP_FLAGS:
|
||||
case FLOW_TYPE_FRAGMENT:
|
||||
case FLOW_TYPE_LABEL:
|
||||
{
|
||||
const byte *last_op = NULL;
|
||||
const byte *op = part+1;
|
||||
u64 val;
|
||||
uint len;
|
||||
uint first = 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
/* XXX: I don't like this so complicated if-tree */
|
||||
if (!isset_and(op) && !is_bitmask(*part) &&
|
||||
((num_op( op) == FLOW_EQ) || (num_op( op) == FLOW_GTE)) &&
|
||||
((num_op(last_op) == FLOW_EQ) || (num_op(last_op) == FLOW_LTE)))
|
||||
{
|
||||
b.pos--; /* Remove last char (it is a space) */
|
||||
buffer_puts(&b, ",");
|
||||
}
|
||||
else if (isset_and(op) && is_bitmask(*part))
|
||||
{
|
||||
b.pos--; /* Remove last char (it is a space) */
|
||||
buffer_puts(&b, ",");
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_puts(&b, isset_and(op) ? "&& " : "|| ");
|
||||
}
|
||||
}
|
||||
first = 0;
|
||||
|
||||
len = get_value_length(op);
|
||||
val = get_value(op+1, len);
|
||||
|
||||
if (is_bitmask(*part))
|
||||
{
|
||||
/*
|
||||
* Not Match Show
|
||||
* ------------------
|
||||
* 0 0 !0/B
|
||||
* 0 1 B/B
|
||||
* 1 0 0/B
|
||||
* 1 1 !B/B
|
||||
*/
|
||||
|
||||
if ((*op & 0x3) == 0x3 || (*op & 0x3) == 0)
|
||||
buffer_puts(&b, "!");
|
||||
|
||||
if (*part == FLOW_TYPE_FRAGMENT && (val == 1 || val == 2 || val == 4 || val == 8))
|
||||
buffer_print(&b, "%s%s", ((*op & 0x1) ? "" : "!"), fragment_val_str(val));
|
||||
else
|
||||
buffer_print(&b, "0x%x/0x%x", ((*op & 0x1) ? val : 0), val);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset_end(op) && !isset_and(op) && isset_and(op+1+len) &&
|
||||
(num_op(op) == FLOW_GTE) && (num_op(op+1+len) == FLOW_LTE))
|
||||
{
|
||||
/* Display interval */
|
||||
buffer_print(&b, "%u..", val);
|
||||
op += 1 + len;
|
||||
len = get_value_length(op);
|
||||
val = get_value(op+1, len);
|
||||
buffer_print(&b, "%u", val);
|
||||
}
|
||||
else if (num_op(op) == FLOW_EQ)
|
||||
{
|
||||
buffer_print(&b, "%u", val);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_print(&b, "%s %u", num_op_str(op), val);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset_end(op))
|
||||
{
|
||||
buffer_puts(&b, "; ");
|
||||
net_format_flow_bitmask(&b, part);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_puts(&b, " ");
|
||||
}
|
||||
|
||||
last_op = op;
|
||||
op += 1 + len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
part = flow_next_part(part, data+dlen, ipv6);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue