Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
um
drivers
pcap_user.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3
* Licensed under the GPL.
4
*/
5
6
#include <errno.h>
7
#include <pcap.h>
8
#include <string.h>
9
#include <asm/types.h>
10
#include <
net_user.h
>
11
#include "
pcap_user.h
"
12
#include <
um_malloc.h
>
13
14
#define PCAP_FD(p) (*(int *)(p))
15
16
static
int
pcap_user_init(
void
*
data
,
void
*
dev
)
17
{
18
struct
pcap_data
*
pri
=
data
;
19
pcap_t *
p
;
20
char
errors
[PCAP_ERRBUF_SIZE];
21
22
p = pcap_open_live(pri->
host_if
,
ETH_MAX_PACKET
+
ETH_HEADER_OTHER
,
23
pri->
promisc
, 0, errors);
24
if
(p ==
NULL
) {
25
printk
(
UM_KERN_ERR
"pcap_user_init : pcap_open_live failed - "
26
"'%s'\n"
, errors);
27
return
-
EINVAL
;
28
}
29
30
pri->
dev
=
dev
;
31
pri->
pcap
=
p
;
32
return
0;
33
}
34
35
static
int
pcap_open(
void
*
data
)
36
{
37
struct
pcap_data
*
pri
=
data
;
38
__u32
netmask;
39
int
err
;
40
41
if
(pri->
pcap
==
NULL
)
42
return
-
ENODEV
;
43
44
if
(pri->
filter
!=
NULL
) {
45
err =
dev_netmask
(pri->
dev
, &netmask);
46
if
(err < 0) {
47
printk
(
UM_KERN_ERR
"pcap_open : dev_netmask failed\n"
);
48
return
-
EIO
;
49
}
50
51
pri->
compiled
=
uml_kmalloc
(
sizeof
(
struct
bpf_program),
52
UM_GFP_KERNEL);
53
if
(pri->
compiled
==
NULL
) {
54
printk
(
UM_KERN_ERR
"pcap_open : kmalloc failed\n"
);
55
return
-
ENOMEM
;
56
}
57
58
err = pcap_compile(pri->
pcap
,
59
(
struct
bpf_program *) pri->
compiled
,
60
pri->
filter
, pri->
optimize
, netmask);
61
if
(err < 0) {
62
printk
(
UM_KERN_ERR
"pcap_open : pcap_compile failed - "
63
"'%s'\n"
, pcap_geterr(pri->
pcap
));
64
goto
out
;
65
}
66
67
err = pcap_setfilter(pri->
pcap
, pri->
compiled
);
68
if
(err < 0) {
69
printk
(
UM_KERN_ERR
"pcap_open : pcap_setfilter "
70
"failed - '%s'\n"
, pcap_geterr(pri->
pcap
));
71
goto
out
;
72
}
73
}
74
75
return
PCAP_FD
(pri->
pcap
);
76
77
out
:
78
kfree
(pri->
compiled
);
79
return
-
EIO
;
80
}
81
82
static
void
pcap_remove(
void
*data)
83
{
84
struct
pcap_data
*pri =
data
;
85
86
if
(pri->
compiled
!=
NULL
)
87
pcap_freecode(pri->
compiled
);
88
89
if
(pri->
pcap
!=
NULL
)
90
pcap_close(pri->
pcap
);
91
}
92
93
struct
pcap_handler_data
{
94
char
*
buffer
;
95
int
len
;
96
};
97
98
static
void
handler
(
u_char
*data,
const
struct
pcap_pkthdr *
header
,
99
const
u_char
*
packet
)
100
{
101
int
len
;
102
103
struct
pcap_handler_data
*hdata = (
struct
pcap_handler_data
*) data;
104
105
len = hdata->
len
< header->caplen ? hdata->
len
: header->caplen;
106
memcpy
(hdata->
buffer
, packet, len);
107
hdata->
len
=
len
;
108
}
109
110
int
pcap_user_read
(
int
fd
,
void
*
buffer
,
int
len
,
struct
pcap_data
*pri)
111
{
112
struct
pcap_handler_data
hdata = ((
struct
pcap_handler_data
)
113
{ .buffer =
buffer
,
114
.len = len });
115
int
n
;
116
117
n = pcap_dispatch(pri->
pcap
, 1,
handler
, (
u_char
*) &hdata);
118
if
(n < 0) {
119
printk
(
UM_KERN_ERR
"pcap_dispatch failed - %s\n"
,
120
pcap_geterr(pri->
pcap
));
121
return
-
EIO
;
122
}
123
else
if
(n == 0)
124
return
0;
125
return
hdata.
len
;
126
}
127
128
const
struct
net_user_info
pcap_user_info
= {
129
.init = pcap_user_init,
130
.open = pcap_open,
131
.close =
NULL
,
132
.remove = pcap_remove,
133
.add_address =
NULL
,
134
.delete_address =
NULL
,
135
.mtu =
ETH_MAX_PACKET
,
136
.max_packet =
ETH_MAX_PACKET
+
ETH_HEADER_OTHER
,
137
};
Generated on Thu Jan 10 2013 13:19:20 for Linux Kernel by
1.8.2