Skip to content
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

Section "methodfour" (FAIL) #1

Open
doup123 opened this issue Nov 28, 2020 · 3 comments
Open

Section "methodfour" (FAIL) #1

doup123 opened this issue Nov 28, 2020 · 3 comments

Comments

@doup123
Copy link

doup123 commented Nov 28, 2020

I have faced a similar issue in the past, attempting to match the payload in a DNS packet.
The problem there is that the qname (domain name) is of variable-length. To that end, I have used a BPF Map that matches the first 12 bytes of the name. I assume that the error that you see is related to the size of uint8_t hashkey[10];
I do not know exactly why but if you choose an array size that can be divided by 4, this may work e.g. uint8_t hashkey[12].
Have you tried different sizes of hashkey?

@gamemann
Copy link
Owner

gamemann commented Dec 7, 2020

Hey and thank you for this report! I'm going to try this out next week at some point and I'll let you know how it goes.

@doup123
Copy link
Author

doup123 commented Dec 9, 2020

For example:
I could compile a program that includes the following structure:
Code
struct key {
u32 test0[125];
};
BPF_HASH(test_key,struct key,u64,1000);

@gamemann
Copy link
Owner

gamemann commented Feb 27, 2021

Hey @doup123, I apologize for the delay on this! The last few months I've been extremely busy. I've been working on this project again today and I believe I finally got it to work. I'd recommend checking out the code here. This allows me to perform partial payload matching from the beginning of the payload. There isn't any support for exact payload matching at the moment since the map's key size would need to match the exact payload length.

I'm a little iffy on using the for loop in this situation due to performance, but I don't think there's any better way to do it.

uint8_t *pcktdata = data + sizeof(struct ethhdr) + (iph->ihl * 4) + l4len;

uint8_t hashkey[MAX_PAYLOAD_LENGTH] = {0};

for (int i = 0; i < MAX_PAYLOAD_LENGTH; i++)
{
    if (pcktdata + (i + 1) > (uint8_t *)data_end)
    {
        break;
    }

    //hashkey[i] = *(pcktdata + i)
    memcpy(hashkey + i, pcktdata + i, 1);
}

uint8_t *match = bpf_map_lookup_elem(&payload_map, &hashkey);

if (match)
{
    printk("Dropping matched packet.\n");
}

The MAX_PAYLOAD_LENGTH constant in the above example is 15 for a maximum of 15 bytes, but I'd imagine you can go a bit higher until you hit the max jump sequence limitation within BPF.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants