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

How to read arbitrary len bytes using helper bpf_skb_load_bytes()? #254

Open
0x000001A4 opened this issue Feb 22, 2024 · 3 comments
Open

Comments

@0x000001A4
Copy link

0x000001A4 commented Feb 22, 2024

Background

I am currently trying to build an eBPF program to read the content of application data (of arbitrary length) transmitted through two processes.

I tried intercepting packets with Linux TC (like it is done in example tc.bpf.c of this repo)
Also tried intercepting packets with Socket Filters (like it is done in example sockfilter.bpf.c of this repo)

Problem

When reading from bpf_skb_load_bytes(), I need to provide an argument len (the last argument).
Given variable length messages, that can be smaller than the MAX_BUF_SIZE, for bpf_skb_load_bytes() not to return an error I need to specify the exact size of the payload that should be read.

Question

Can anyone help me understand how to read the amount of bytes that are in the packet's payload?
Passing to bpf_skb_load_bytes an arbitrary len argument, computed as the exact number of those bytes?

Attempt 1 to solve the problem

In case it is MAX_BUF_SIZE and the payload size happens to be smaller than MAX_BUF_SIZE, error -14 is returned by bpf_skb_load_bytes; and no information is read.
(I also tried this using sockfilter example on this repo and it is exactly what happens if the payload simply having an integer is intercepted).

This takes us to the necessity of computing the size of the payload to read the correct number of bytes from the payload.

Attempt 2 to solve the problem

In case I try to compute the payload_size from skb->len - total_hlen, I have problems with the verifier, which states that payload_len has a negative min value.
total_hlen is the total size in bytes used by the eth header (eth_hlen), IP header (ip_hlen) and transport header (tp_hlen).
Example in a program below:
`

__u32 eth_hlen, ip_hlen, tp_hlen, data_len, total_hlen, payload_len;
char payload[MAX_PAYLOAD_SIZE];
...
total_hlen = eth_hlen + ip_hlen + tp_hlen;

if (skb->len > total_hlen) {
    payload_len = skb->len - total_hlen;
    if (payload_len > sizeof(payload)) payload_len = sizeof(payload);

    long err = bpf_skb_load_bytes(skb, total_hlen, payload, payload_len);
    if (!err) {
        bpf_printk("New packet -> skb_len: %d, data_len: %d | Total_Hlen: %d ETH_Hlen: %d, IP_Hlen: %d, TP_Hlen: %d | payload_len: %d, payload: %s",
            skb->len, data_len, total_hlen, eth_hlen, ip_hlen, tp_hlen, payload_len, payload);
    } else bpf_printk("%d\n", err);
}`
@Shreyas220
Copy link

Shreyas220 commented Apr 28, 2024

Hey @0x000001A4 I am facing the exact same error, were you able to find a solution ?

@chenhengqi
Copy link
Contributor

What's your use-case ? Typical network BPF programs don't do that, i.e. load the full packet.

@hugbgithub
Copy link

You can invoke the bpf_skb_load_bytes with parameters 100 10 1 multi times

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

4 participants