why I can't parse h_proto == 0x0806 that arp protocol from Linux ebpf tc egress code?

188 Views Asked by At

I want to get IP address from arp broadcast that net dev send.So I use tc egress to get this IP by ebpf.I can use this code parse struct xdp_buff but is not work on struct __sk_buff. I print eth->h_porto get error hex.So what should I do can soulve this probleme?

There is some stuct

#define ETH_P_IP 0x0800
#define ETH_P_ARP 0x0806
#define ETH_ALEN    6

struct ethhdr {
unsigned char   h_dest[ETH_ALEN];   /* destination eth addr */
unsigned char   h_source[ETH_ALEN]; /* source ether addr    */
__be16      h_proto;        /* packet type ID field */
}__attribute__((packed));

struct arphdr {
__be16      ar_hrd;     /* format of hardware address   */
__be16      ar_pro;     /* format of protocol address   */
unsigned char   ar_hln;     /* length of hardware address   */
unsigned char   ar_pln;     /* length of protocol address   */
__be16      ar_op;      /* ARP opcode (command)     */

#if 0
/*
*    Ethernet looks like this : This bit is variable sized however...
*/
unsigned char       ar_sha[ETH_ALEN];   /* sender hardware address  */
unsigned char       ar_sip[4];      /* sender IP address        */
unsigned char       ar_tha[ETH_ALEN];   /* target hardware address  */
unsigned char       ar_tip[4];      /* target IP address        */
#endif
};

struct arp_eth {
unsigned char       ar_sha[ETH_ALEN];
__be32                  ar_sip;
unsigned char       ar_tha[ETH_ALEN];
__be32                  ar_tip;
}__packed;

This is parse code

#define ETH_HLEN 14
static __always_inline int parse_ip_src_addr(struct __sk_buff *ctx, __u32 *ip_src_addr,struct pair *mac_info) {
    void *data_end = (void *) (long) ctx->data_end;
    void *data = (void *) (long) ctx->data;
    struct arphdr *arp = data + ETH_HLEN;
    struct ethhdr *eth = data;
    struct arp_eth *arp_eth;

    if (data + ETH_HLEN + sizeof(*arp) + sizeof(*arp_eth) > data_end){
        return 1;
    }
     char h_proto[] = "h_proto:%x";

     bpf_trace_printk(h_proto,sizeof(h_proto),bpf_ntohs(eth->h_proto));

    if (eth->h_proto == bpf_htons(ETH_P_ARP)){
    }
}

There is my attach golang code

    objs := bpfObjects{}
    if err := loadBpfObjects(&objs, nil); err != nil {
        log.Fatalf("loading objects: %v", err)
    }
    defer objs.Close()

    // Get the first-mounted cgroupv2 path.
    cgroupPath, err := detectCgroupPath()
    if err != nil {
        log.Fatal(err)
    }

    // Link the count_egress_packets program to the cgroup.
    l, err := link.AttachCgroup(link.CgroupOptions{
        Path:    cgroupPath,
        Attach:  ebpf.AttachCGroupInetEgress,
        Program: objs.ArpEgressPackets,
    })
    if err != nil {
        log.Fatal(err)
    }
    defer l.Close()

tcpdump hex info bpf_trace_printk info

0

There are 0 best solutions below