1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
11 #include "pcap_user.h"
12 #include <um_malloc.h>
14 #define PCAP_FD(p) (*(int *)(p))
16 static int pcap_user_init(void *data
, void *dev
)
18 struct pcap_data
*pri
= data
;
20 char errors
[PCAP_ERRBUF_SIZE
];
22 p
= pcap_open_live(pri
->host_if
, ETH_MAX_PACKET
+ ETH_HEADER_OTHER
,
23 pri
->promisc
, 0, errors
);
25 printk(UM_KERN_ERR
"pcap_user_init : pcap_open_live failed - "
35 static int pcap_open(void *data
)
37 struct pcap_data
*pri
= data
;
41 if (pri
->pcap
== NULL
)
44 if (pri
->filter
!= NULL
) {
45 err
= dev_netmask(pri
->dev
, &netmask
);
47 printk(UM_KERN_ERR
"pcap_open : dev_netmask failed\n");
51 pri
->compiled
= uml_kmalloc(sizeof(struct bpf_program
),
53 if (pri
->compiled
== NULL
) {
54 printk(UM_KERN_ERR
"pcap_open : kmalloc failed\n");
58 err
= pcap_compile(pri
->pcap
,
59 (struct bpf_program
*) pri
->compiled
,
60 pri
->filter
, pri
->optimize
, netmask
);
62 printk(UM_KERN_ERR
"pcap_open : pcap_compile failed - "
63 "'%s'\n", pcap_geterr(pri
->pcap
));
67 err
= pcap_setfilter(pri
->pcap
, pri
->compiled
);
69 printk(UM_KERN_ERR
"pcap_open : pcap_setfilter "
70 "failed - '%s'\n", pcap_geterr(pri
->pcap
));
75 return PCAP_FD(pri
->pcap
);
82 static void pcap_remove(void *data
)
84 struct pcap_data
*pri
= data
;
86 if (pri
->compiled
!= NULL
)
87 pcap_freecode(pri
->compiled
);
89 if (pri
->pcap
!= NULL
)
90 pcap_close(pri
->pcap
);
93 struct pcap_handler_data
{
98 static void handler(u_char
*data
, const struct pcap_pkthdr
*header
,
103 struct pcap_handler_data
*hdata
= (struct pcap_handler_data
*) data
;
105 len
= hdata
->len
< header
->caplen
? hdata
->len
: header
->caplen
;
106 memcpy(hdata
->buffer
, packet
, len
);
110 int pcap_user_read(int fd
, void *buffer
, int len
, struct pcap_data
*pri
)
112 struct pcap_handler_data hdata
= ((struct pcap_handler_data
)
117 n
= pcap_dispatch(pri
->pcap
, 1, handler
, (u_char
*) &hdata
);
119 printk(UM_KERN_ERR
"pcap_dispatch failed - %s\n",
120 pcap_geterr(pri
->pcap
));
128 const struct net_user_info pcap_user_info
= {
129 .init
= pcap_user_init
,
132 .remove
= pcap_remove
,
134 .delete_address
= NULL
,
135 .mtu
= ETH_MAX_PACKET
,
136 .max_packet
= ETH_MAX_PACKET
+ ETH_HEADER_OTHER
,