11#include <arpa/inet.h>
22#include <bpf/bpf.h>
3- #include <linux/if_packet.h>
4- #include <linux/if_ether.h>
53#include <net/if.h>
64#include <sys/stat.h>
75#include <sys/mman.h>
@@ -24,31 +22,23 @@ struct resource {
2422 struct resource * parent , * sibling , * child ;
2523};
2624
27- /* Ethernet frame structure for XDP trigger packets */
28- struct trigger_frame {
29- struct ethhdr eth_header ;
30- struct read_mem_args args ;
31- char padding [ETH_ZLEN - sizeof (struct ethhdr ) - sizeof (struct read_mem_args )];
32- } __attribute__((packed ));
33-
3425#define IORESOURCE_MEM 0x00000200
3526#define IORESOURCE_SYSRAM 0x01000000
3627#define IORESOURCE_BUSY 0x80000000
3728#define IORESOURCE_SYSTEM_RAM (IORESOURCE_MEM|IORESOURCE_SYSRAM)
38- #define SYSTEM_RAM_FLAGS (IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY)
29+ #define SYSTEM_RAM_FLAGS (IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY)
3930
4031extern int check_capability (const cap_value_t cap );
4132
42- /* eBPF memory read program skeleton and fd of the XDP program */
43- int read_kernel_memory_xdp_fd ;
33+ /* eBPF memory read program skeleton */
4434struct mem_ebpf * mem_ebpf_skel ;
4535
46- /* XDP attachment and network trigger resources */
47- int raw_sockfd = -1 ;
48- struct bpf_link * bpf_prog_link = NULL ;
36+ /* XDP and UDP trigger resources */
37+ int udp_sockfd = -1 ;
4938const char * loopback_interface = "lo" ;
39+ struct bpf_link * bpf_prog_link = NULL ;
5040
51- /* File descriptor and mmap() pointer associated to the eBPF map. */
41+ /* File descriptor and mmap() pointer associated to the eBPF map */
5242int read_mem_result_fd ;
5343struct read_mem_result * read_mem_result ;
5444
@@ -59,7 +49,7 @@ struct read_mem_result *read_mem_result;
5949 static int64_t v2p_offset ;
6050#endif
6151
62- /*Address of root of struct resources list (physical memory regions list) */
52+ /* Address of root of struct resources list (physical memory regions list) */
6353static uintptr_t iomem_resource ;
6454
6555#if defined(__TARGET_ARCH_arm64 )
@@ -149,34 +139,26 @@ static int init_mmap() {
149139}
150140
151141/*
152- * init_raw_socket () - Create and bind a raw socket for sending Ethernet frames
142+ * init_udp_socket () - Create and configure UDP socket for sending trigger packets
153143 *
154- * Creates a raw socket with ETH_P_ALL protocol to send custom Ethernet frames,
155- * and binds it to loopback interface.
144+ * Creates a UDP socket for sending XDP trigger packets to the loopback interface.
156145 * Returns 0 on success, negative errno value on failure.
157146 */
158- static int init_raw_socket ( int ifindex ) {
159- struct sockaddr_ll sll ;
147+ static int init_udp_socket ( ) {
148+ struct sockaddr_in local_addr ;
160149
161- /* Create raw socket */
162- raw_sockfd = socket (AF_PACKET , SOCK_RAW , htons ( ETH_P_ALL ) );
163- if (raw_sockfd < 0 ) {
164- perror ("Failed to create raw socket for XDP trigger" );
150+ /* Create UDP socket */
151+ udp_sockfd = socket (AF_INET , SOCK_DGRAM , 0 );
152+ if (udp_sockfd < 0 ) {
153+ perror ("Failed to create UDP socket for XDP trigger" );
165154 return - errno ;
166155 }
167156
168- /* Bind raw socket to loopback interface */
169- memset (& sll , 0 , sizeof (sll ));
170- sll .sll_family = AF_PACKET ;
171- sll .sll_ifindex = ifindex ;
172- sll .sll_protocol = htons (ETH_P_ALL );
173-
174- if (bind (raw_sockfd , (struct sockaddr * )& sll , sizeof (sll )) < 0 ) {
175- perror ("Failed to bind raw socket to interface" );
176- close (raw_sockfd );
177- raw_sockfd = -1 ;
178- return - errno ;
179- }
157+ /* Setup local address structure for binding*/
158+ memset (& local_addr , 0 , sizeof (local_addr ));
159+ local_addr .sin_family = AF_INET ;
160+ local_addr .sin_addr .s_addr = INADDR_ANY ;
161+ local_addr .sin_port = 0 ;
180162
181163 return 0 ;
182164}
@@ -226,11 +208,6 @@ int load_ebpf_mem_progs() {
226208 if (!bpf_prog_link ) {
227209 fprintf (stderr , "Failed to attach eBPF Uprobe program, use XDP fallback...\n" );
228210
229- /* Check if can create raw sockets for XDP */
230- if (check_capability (CAP_NET_RAW ) <= 0 ) {
231- WARN ("LEMON does not have CAP_NET_RAW to create raw sockets for XDP" );
232- }
233-
234211 /* Get loopback interface index by name "lo" (usually 1) */
235212 int ifindex = if_nametoindex (loopback_interface );
236213 if (ifindex <= 0 ) {
@@ -245,7 +222,7 @@ int load_ebpf_mem_progs() {
245222 }
246223
247224 /* Create socket for sending trigger packets */
248- if ((ret = init_raw_socket ( ifindex ))) {
225+ if ((ret = init_udp_socket ( ))) {
249226 return ret ;
250227 }
251228 }
@@ -266,17 +243,17 @@ void cleanup_mem_ebpf() {
266243 if (read_mem_result ) munmap (read_mem_result , sizeof (struct read_mem_result ));
267244 mem_ebpf__destroy (mem_ebpf_skel );
268245 }
269-
246+
270247 /* Destroy bpf_link if it exists*/
271248 if (bpf_prog_link ) {
272249 bpf_link__destroy (bpf_prog_link );
273250 bpf_prog_link = NULL ;
274251 }
275252
276- /* Close raw socket if it's open */
277- if (raw_sockfd ) {
278- close (raw_sockfd );
279- raw_sockfd = -1 ;
253+ /* Close UDP socket if it's open */
254+ if (udp_sockfd > 0 ) {
255+ close (udp_sockfd );
256+ udp_sockfd = -1 ;
280257 }
281258}
282259
@@ -298,59 +275,39 @@ uintptr_t phys_to_virt(const uintptr_t phy_addr) {
298275}
299276
300277/*
301- * send_xdp_trigger_packet () - Send Ethernet frame to trigger XDP program
278+ * send_udp_trigger_packet () - Send UDP packets to trigger XDP program
302279 * @addr: Virtual address of the memory region to read
303280 * @size: Size of the memory region to read
304- *
305- * Constructs and sends an Ethernet frame with the memory read arguments as payload
306- * to the loopback interface triggering the XDP program to perform the read.
307- * Uses a minimal Ethernet frame with broadcast destination.
308- * Returns 0 on success, negative errno value on failure.
309281 */
310- static int send_xdp_trigger_packet (const uintptr_t addr , const size_t size ) {
311- int ifindex ;
282+ static int send_udp_trigger_packet (const uintptr_t addr , const size_t size ) {
312283 ssize_t sent_bytes ;
313- struct trigger_frame frame ;
314- struct sockaddr_ll dest_addr ;
315-
316- ifindex = if_nametoindex (loopback_interface );
317-
318- /* Initialize frame structure */
319- memset (& frame , 0 , sizeof (frame ));
320-
321- /* Setup Ethernet header, and use broadcast address for simplicity */
322- memset (frame .eth_header .h_dest , 0xFF , ETH_ALEN ); /* Broadcast destination */
323- memset (frame .eth_header .h_source , 0x00 , ETH_ALEN );
324- frame .eth_header .h_proto = htons (0x0800 );
325-
284+ struct sockaddr_in dest_addr ;
285+ struct read_mem_args args ;
286+
326287 /* Setup memory read arguments in payload */
327- frame . args .addr = addr ;
328- frame . args .size = size ;
329-
330- /* Setup destination address */
288+ args .addr = addr ;
289+ args .size = size ;
290+
291+ /* Setup destination address (loopback) */
331292 memset (& dest_addr , 0 , sizeof (dest_addr ));
332- dest_addr .sll_family = AF_PACKET ;
333- dest_addr .sll_ifindex = ifindex ;
334- dest_addr .sll_protocol = htons (ETH_P_ALL );
335- dest_addr .sll_halen = ETH_ALEN ;
336- memset (dest_addr .sll_addr , 0xFF , ETH_ALEN ); /* Broadcast destination */
337-
338- /* Send the frame */
339- sent_bytes = sendto (raw_sockfd , & frame , sizeof (frame ), 0 ,
340- (struct sockaddr * )& dest_addr , sizeof (dest_addr ));
341-
293+ dest_addr .sin_family = AF_INET ;
294+ dest_addr .sin_addr .s_addr = inet_addr ("127.0.0.1" );
295+ dest_addr .sin_port = htons (9999 );
296+
297+ /* Send the UDP packet */
298+ sent_bytes = sendto (udp_sockfd , & args , sizeof (args ), 0 , (struct sockaddr * )& dest_addr , sizeof (dest_addr ));
299+
342300 if (sent_bytes < 0 ) {
343- perror ("Failed to send XDP trigger packet" );
301+ perror ("Failed to send UDP trigger packet" );
344302 return - errno ;
345303 }
346-
347- /* For raw packets, partial send should not happen */
348- if (sent_bytes != sizeof (frame )) {
349- fprintf (stderr , "Incomplete packet send: %zd of %zu bytes\n" ,
350- sent_bytes , sizeof (frame ));
304+
305+ /* Check partial send*/
306+ if (sent_bytes != sizeof (args )) {
307+ fprintf (stderr , "Incomplete packet send: %zd of %zu bytes\n" , sent_bytes , sizeof (args ));
351308 return - EIO ;
352309 }
353-
310+
354311 return 0 ;
355312}
356313
@@ -365,11 +322,11 @@ static int send_xdp_trigger_packet(const uintptr_t addr, const size_t size) {
365322 */
366323int __attribute__((noinline , optnone )) read_kernel_memory (const uintptr_t addr , const size_t size , __u8 * * restrict data ) {
367324 /* If the Uprobe support is not active in kernel, use XDP to read the memory*/
368- if (raw_sockfd > 0 ) {
325+ if (udp_sockfd > 0 ) {
369326 int ret ;
370-
371- /* Send XDP trigger packet */
372- ret = send_xdp_trigger_packet (addr , size );
327+
328+ /* Send UDP trigger packet for XDP */
329+ ret = send_udp_trigger_packet (addr , size );
373330 if (ret < 0 ) {
374331 read_mem_result -> ret_code = ret ;
375332 return ret ;
0 commit comments