Reputation: 29
Below are the sample codes
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));
xdp_kernel.c
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/in.h>
SEC("xdp")
int xdp_test(struct xdp_md *ctx)
{
bpf_printk("PACKET RECIEVED");
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
void *pos = data;
struct ethhdr *eth = (struct ethhdr *)(pos);
if ((eth + 1) <= data_end)
{
bpf_printk("ETH %ld 0x%X",data_end-data,bpf_ntohs(eth->h_proto));
if (bpf_ntohs(eth->h_proto) == ETH_P_IP)
{
//bpf_printk("IP");
pos += sizeof(struct ethhdr);
struct iphdr *iph = (struct iphdr *)(pos);
if ((iph + 1) <= data_end)
{
if (iph->protocol == IPPROTO_UDP)
{
bpf_printk("UDP");
const __u16 iph_sz_in_bytes = iph->ihl * 4;
if (((void *)iph + iph_sz_in_bytes) <= data_end)
{
pos += iph_sz_in_bytes;
struct udphdr *udh = (struct udphdr *)(pos);
if ((udh + 1) <= data_end)
{
}
}
}
}
}
}
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
sender.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
const int delay_secs = 1;
const char *message2 = "Hello, World!";
unsigned long counter = 0;
char message[8192] = {0};
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
perror("socket");
return 1;
}
struct ip_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.imr_interface.s_addr = inet_addr("192.168.2.6"); // local wifi interface address
if (
setsockopt(
fd, IPPROTO_IP, IP_MULTICAST_IF, (char *)&mreq, sizeof(mreq)) < 0)
{
perror("setsockopt");
return 1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("239.0.0.0");
addr.sin_port = htons(1234);
while (1)
{
char ch = 0;
snprintf(message, 8192, "%s-%lu", message2, ++counter);
int nbytes = sendto(
fd,
message,
strlen(message),
0,
(struct sockaddr *)&addr,
sizeof(addr));
if (nbytes < 0)
{
perror("sendto");
return 1;
}
sleep(delay_secs);
}
return 0;
}
listner.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define MSGBUFSIZE 8192
int main()
{
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
perror("socket");
return 1;
}
u_int yes = 1;
if (
setsockopt(
fd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0)
{
perror("Reusing ADDR failed");
return 1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("239.0.0.0");
addr.sin_port = htons(1234);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("bind");
return 1;
}
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr("239.0.0.0");
mreq.imr_interface.s_addr = inet_addr("192.168.2.6"); //local wifi address
if (
setsockopt(
fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)
{
perror("setsockopt");
return 1;
}
while (1)
{
char msgbuf[MSGBUFSIZE];
int addrlen = sizeof(addr);
int nbytes = recvfrom(
fd,
msgbuf,
MSGBUFSIZE,
0,
(struct sockaddr *)&addr,
&addrlen);
if (nbytes < 0)
{
perror("recvfrom");
return 1;
}
msgbuf[nbytes] = '\0';
puts(msgbuf);
}
return 0;
}
sender is sending multicast successfully and even listener is receiving
Issue here in in XDP kernel code am not able to capture this packet since i am only interested in IP4 protocol,but trace in XDP prints the below protocol ID
sender-28811 [002] ..s21 11044.326101: bpf_trace_printk: PACKET RECIEVED
sender-28811 [002] ..s21 11044.326122: bpf_trace_printk: ETH 45 0xC0A8
Where as for other IP4 it prints
irq/168-iwlwifi-596 [006] ..s21 11041.649288: bpf_trace_printk: PACKET RECIEVED
irq/168-iwlwifi-596 [006] ..s21 11041.649298: bpf_trace_printk: ETH 60 0x800
what might be the issue here.
Also any way can i print h_dest(MAC address)
Upvotes: 1
Views: 50