]>
The Tcpdump Group git mirrors - libpcap/blob - pcap-hurd.c
3 /* XXX Hack not to include the Mach BPF interface */
19 #include <device/device.h>
20 #include <device/device_types.h>
21 #include <device/net_status.h>
22 #include <net/if_ether.h>
27 struct pcap_stat stat
;
32 static struct bpf_insn filter
[] = {
33 { NETF_IN
| NETF_OUT
| NETF_BPF
, 0, 0, 0 },
34 { BPF_RET
| BPF_K
, 0, 0, MAXIMUM_SNAPLEN
},
37 #define FILTER_COUNT (sizeof(filter) / sizeof(short))
40 pcap_read_hurd(pcap_t
*p
, int cnt
, pcap_handler callback
, u_char
*user
)
42 struct net_rcv_msg
*msg
;
46 int ret
, wirelen
, caplen
;
51 msg
= (struct net_rcv_msg
*)p
->buffer
;
56 return PCAP_ERROR_BREAK
;
59 kr
= mach_msg(&msg
->msg_hdr
, MACH_RCV_MSG
| MACH_RCV_INTERRUPT
, 0,
60 p
->bufsize
, ph
->rcv_port
, MACH_MSG_TIMEOUT_NONE
,
64 if (kr
== MACH_RCV_INTERRUPTED
)
67 snprintf(p
->errbuf
, sizeof(p
->errbuf
), "mach_msg: %s",
74 /* XXX Ethernet support only */
75 wirelen
= ETH_HLEN
+ msg
->net_rcv_msg_packet_count
76 - sizeof(struct packet_header
);
77 pkt
= p
->buffer
+ offsetof(struct net_rcv_msg
, packet
)
78 + sizeof(struct packet_header
) - ETH_HLEN
;
79 memmove(pkt
, p
->buffer
+ offsetof(struct net_rcv_msg
, header
),
82 caplen
= (wirelen
> p
->snapshot
) ? p
->snapshot
: wirelen
;
83 ret
= bpf_filter(p
->fcode
.bf_insns
, pkt
, wirelen
, caplen
);
88 clock_gettime(CLOCK_REALTIME
, &ts
);
89 h
.ts
.tv_sec
= ts
.tv_sec
;
90 h
.ts
.tv_usec
= ts
.tv_nsec
/ 1000;
93 callback(user
, &h
, pkt
);
100 pcap_inject_hurd(pcap_t
*p
, const void *buf
, int size
)
102 struct pcap_hurd
*ph
;
107 kr
= device_write(ph
->mach_dev
, D_NOWAIT
, 0,
108 (io_buf_ptr_t
)buf
, size
, &count
);
111 snprintf(p
->errbuf
, sizeof(p
->errbuf
), "device_write: %s",
120 pcap_stats_hurd(pcap_t
*p
, struct pcap_stat
*ps
)
122 struct pcap_hurd
*ph
;
130 pcap_cleanup_hurd(pcap_t
*p
)
132 struct pcap_hurd
*ph
;
136 if (ph
->rcv_port
!= MACH_PORT_NULL
) {
137 mach_port_deallocate(mach_task_self(), ph
->rcv_port
);
138 ph
->rcv_port
= MACH_PORT_NULL
;
141 if (ph
->mach_dev
!= MACH_PORT_NULL
) {
142 device_close(ph
->mach_dev
);
143 ph
->mach_dev
= MACH_PORT_NULL
;
146 pcap_cleanup_live_common(p
);
150 pcap_activate_hurd(pcap_t
*p
)
152 struct pcap_hurd
*ph
;
158 /* Try devnode first */
159 master
= file_name_lookup(p
->opt
.device
, O_READ
| O_WRITE
, 0);
161 if (master
!= MACH_PORT_NULL
)
162 kr
= device_open(master
, D_WRITE
| D_READ
, "eth", &ph
->mach_dev
);
164 /* If unsuccessful, try Mach device */
165 kr
= get_privileged_ports(NULL
, &master
);
168 snprintf(p
->errbuf
, sizeof(p
->errbuf
),
169 "get_privileged_ports: %s", pcap_strerror(kr
));
173 kr
= device_open(master
, D_READ
| D_WRITE
, p
->opt
.device
,
177 mach_port_deallocate(mach_task_self(), master
);
180 snprintf(p
->errbuf
, sizeof(p
->errbuf
), "device_open: %s",
185 kr
= mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE
,
189 snprintf(p
->errbuf
, sizeof(p
->errbuf
), "mach_port_allocate: %s",
194 kr
= device_set_filter(ph
->mach_dev
, ph
->rcv_port
,
195 MACH_MSG_TYPE_MAKE_SEND
, 0,
196 (filter_array_t
)filter
, FILTER_COUNT
);
199 snprintf(p
->errbuf
, sizeof(p
->errbuf
), "device_set_filter: %s",
204 /* XXX Ethernet only currently */
205 p
->linktype
= DLT_EN10MB
;
207 p
->bufsize
= sizeof(struct net_rcv_msg
);
208 p
->buffer
= malloc(p
->bufsize
);
210 if (p
->buffer
== NULL
) {
211 snprintf(p
->errbuf
, sizeof(p
->errbuf
), "malloc: %s",
212 pcap_strerror(errno
));
216 p
->dlt_list
= malloc(sizeof(*p
->dlt_list
));
218 if (p
->dlt_list
!= NULL
)
219 *p
->dlt_list
= DLT_EN10MB
;
221 p
->read_op
= pcap_read_hurd
;
222 p
->inject_op
= pcap_inject_hurd
;
223 p
->setfilter_op
= install_bpf_program
;
224 p
->stats_op
= pcap_stats_hurd
;
229 pcap_cleanup_hurd(p
);
234 pcap_create_interface(const char *device _U_
, char *ebuf
)
236 struct pcap_hurd
*ph
;
239 p
= PCAP_CREATE_COMMON(ebuf
, struct pcap_hurd
);
244 ph
->mach_dev
= MACH_PORT_NULL
;
245 ph
->rcv_port
= MACH_PORT_NULL
;
246 p
->activate_op
= pcap_activate_hurd
;
251 pcap_platform_finddevs(pcap_if_list_t
*alldevsp
, char *errbuf
)
257 * Libpcap version string.
260 pcap_lib_version(void)
262 return PCAP_VERSION_STRING
;