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()