-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vlan: add vlan.id keyword - v3 #12273
Conversation
and filter network packets based on Virtual Local Area Network IDs. By default, | ||
it matches all VLAN IDs. However, if a specific layer is defined, it will only match that layer. | ||
|
||
vlan.id uses :ref:`unsigned 32-bit integer <rules-integer-keywords>`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why 32 bit? Iirc we can have a 12bit number max, so should we use u16?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah I see the code uses u16
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed, doc should state u16 as used in the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also mention here the max value, and the specification that defines that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the work Alice
CI : red, could you investigate ?
Code : looking into it now
Commits segmentation : ok
Commit messages : title could be detect: add vlan.id keyword
Git ID set : looks fine for me
CLA : you already contributed
Doc update : good, some remark inline
Redmine ticket : ok
Rustfmt : looks ok for vlan_id.rs
Tests : nice, thanks, added a remark there
Dependencies added: none
|
||
Suricata has a ``vlan.id`` keyword that can be used in signatures to identify | ||
and filter network packets based on Virtual Local Area Network IDs. By default, | ||
it matches all VLAN IDs. However, if a specific layer is defined, it will only match that layer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you mean all layers if a packet has multiple vlan layers
@@ -29,6 +29,8 @@ pub enum RuleParseError<I> { | |||
InvalidTransformBase64(String), | |||
InvalidByteExtract(String), | |||
|
|||
InvalidGeneric(String), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be removed
const PrefilterPacketHeaderCtx *ctx = pectx; | ||
|
||
for (int i = 0; i < p->vlan_idx; i++) { | ||
if (p->vlan_id[i] == ctx->v1.u16[0] && (ctx->v1.u8[0] == 0 || ctx->v1.u8[0] - 1 == i)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function should use some more similar logic as DetectVlanIdMatch
with DetectU16Match
...
static void DetectVlanIdFree(DetectEngineCtx *de_ctx, void *ptr) | ||
{ | ||
DetectVlanIdData *data = ptr; | ||
SCFree(data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am afraid that we have to do the free in the rust side, so we need to call a rust function here
} | ||
|
||
const DetectVlanIdData *vdata = (const DetectVlanIdData *)ctx; | ||
if (vdata->layer == INT8_MIN) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should name this constant INT8_MIN
with some name containing vlan
} | ||
} else { | ||
if (vdata->layer < 0) { | ||
if (((int16_t)p->vlan_idx) + vdata->layer < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add some comment here
if du16.is_err() { | ||
return None; | ||
} | ||
let du16 = du16.unwrap().1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jasonish do you have proposals for better rust style here ?
|
||
alert ip any any -> any any (msg:"Vlan ID is equal to 400"; vlan.id:400,-1; sid:1;) | ||
|
||
In this example, we use the negative value -1 to represent the last layer of the VLAN IDs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jufajardini what do you think about the doc ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bi nitty here, I'd suggest:
In this example, we use the negative value -1 to represent the last layer of the VLAN IDs. | |
In the last example, we use the negative value -1 to represent the last layer of the VLAN IDs. |
It's probably also a good idea to mention this in the description, not just here when explaining the example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jufajardini what do you think about the doc ?
It's looking good :) I've made some suggestions, but we're going on the right direction /o/
Should we add if vlan.id
supports prefiltering or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shared some comments to help with the docs, mostly. ^^
We're missing adding the new file to doc/userguide/rules/index.rst
, too, otherwise it won't be added, and the docs won't be generated, throwing an error.
@@ -0,0 +1,32 @@ | |||
Vlan.id Keyword |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considering what was brought up in the call we had:
Thinking about the structure we have for other keywords, I do think we should prepare the doc for the possibility of other vlan
keywords being added. I'll point out in the files the changes needed for that.
That said, My suggestion is that we name the file vlan-keywords
- and then the first title in this file would be VLAN Keywords -, and then have a section vlan.id
for this description of the keyword itself.
|
||
vlan.id: [op]id[,layer]; | ||
|
||
The id can be matched exactly, or compared using the _op_ setting:: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: for bold, you can use **
, for italic, *
, and ``
for inline code
The id can be matched exactly, or compared using the _op_ setting:: | |
The id can be matched exactly, or compared using the ``op`` setting:: |
|
||
alert ip any any -> any any (msg:"Vlan ID is equal to 300"; vlan.id:300; sid:1;) | ||
|
||
:: | ||
|
||
alert ip any any -> any any (msg:"Vlan ID is equal to 300"; vlan.id:300,1; sid:1;) | ||
|
||
:: | ||
|
||
alert ip any any -> any any (msg:"Vlan ID is equal to 400"; vlan.id:400,-1; sid:1;) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a few directives that help with formatting rule examples. You can add them in the first lines of your document, and then benefit from some neat options.
More on this: https://docs.suricata.io/en/latest/devguide/contributing/contribution-process.html#rule-examples (and then you can take advantage of that to highlight your keyword on the examples, for instance ) usage example in our docs: https://raw.githubusercontent.com/OISF/suricata/refs/heads/master/doc/userguide/rules/http-keywords.rst
and filter network packets based on Virtual Local Area Network IDs. By default, | ||
it matches all VLAN IDs. However, if a specific layer is defined, it will only match that layer. | ||
|
||
vlan.id uses :ref:`unsigned 32-bit integer <rules-integer-keywords>`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also mention here the max value, and the specification that defines that?
|
||
alert ip any any -> any any (msg:"Vlan ID is equal to 400"; vlan.id:400,-1; sid:1;) | ||
|
||
In this example, we use the negative value -1 to represent the last layer of the VLAN IDs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bi nitty here, I'd suggest:
In this example, we use the negative value -1 to represent the last layer of the VLAN IDs. | |
In the last example, we use the negative value -1 to represent the last layer of the VLAN IDs. |
It's probably also a good idea to mention this in the description, not just here when explaining the example.
|
||
alert ip any any -> any any (msg:"Vlan ID is equal to 400"; vlan.id:400,-1; sid:1;) | ||
|
||
In this example, we use the negative value -1 to represent the last layer of the VLAN IDs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jufajardini what do you think about the doc ?
It's looking good :) I've made some suggestions, but we're going on the right direction /o/
Should we add if vlan.id
supports prefiltering or not?
{ | ||
sigmatch_table[DETECT_VLAN_ID].name = "vlan.id"; | ||
sigmatch_table[DETECT_VLAN_ID].desc = "match vlan id"; | ||
sigmatch_table[DETECT_VLAN_ID].url = "/rules/vlan-id.html"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we agree to having a file more generic for vlan keywords, then this one becomes:
sigmatch_table[DETECT_VLAN_ID].url = "/rules/vlan-id.html"; | |
sigmatch_table[DETECT_VLAN_ID].url = "/rules/vlan-keywords.html#vlan-id"; |
return None; | ||
} | ||
let layer = if parts.len() == 2 { | ||
i8::from_str(parts[1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion for even more expressivity : add support vlan.id: >100,all
which matches only if all vlan layers match
Ticket: #1065
Make sure these boxes are checked accordingly before submitting your Pull Request -- thank you.
Contribution style:
https://docs.suricata.io/en/latest/devguide/contributing/contribution-process.html
Our Contribution agreements:
https://suricata.io/about/contribution-agreement/ (note: this is only required once)
Changes (if applicable):
(including schema descriptions)
https://redmine.openinfosecfoundation.org/projects/suricata/issues
Link to ticket: https://redmine.openinfosecfoundation.org/issues/1065
Describe changes:
Provide values to any of the below to override the defaults.
link to the pull request in the respective
_BRANCH
variable.SV_BRANCH= OISF/suricata-verify#2183
Previous PR= #12103