Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Copyright (C) 2002 Jeff Dike <jdike@karaya.com> | |
3 | * Licensed under the GPL. | |
4 | */ | |
5 | ||
6 | #include "linux/init.h" | |
7 | #include "linux/netdevice.h" | |
8 | #include "linux/etherdevice.h" | |
9 | #include "net_kern.h" | |
10 | #include "net_user.h" | |
11 | #include "pcap_user.h" | |
12 | ||
13 | struct pcap_init { | |
14 | char *host_if; | |
15 | int promisc; | |
16 | int optimize; | |
17 | char *filter; | |
18 | }; | |
19 | ||
20 | void pcap_init(struct net_device *dev, void *data) | |
21 | { | |
22 | struct uml_net_private *pri; | |
23 | struct pcap_data *ppri; | |
24 | struct pcap_init *init = data; | |
25 | ||
26 | pri = dev->priv; | |
27 | ppri = (struct pcap_data *) pri->user; | |
28 | ppri->host_if = init->host_if; | |
29 | ppri->promisc = init->promisc; | |
30 | ppri->optimize = init->optimize; | |
31 | ppri->filter = init->filter; | |
32 | } | |
33 | ||
34 | static int pcap_read(int fd, struct sk_buff **skb, | |
35 | struct uml_net_private *lp) | |
36 | { | |
37 | *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); | |
38 | if(*skb == NULL) return(-ENOMEM); | |
39 | return(pcap_user_read(fd, (*skb)->mac.raw, | |
40 | (*skb)->dev->mtu + ETH_HEADER_OTHER, | |
41 | (struct pcap_data *) &lp->user)); | |
42 | } | |
43 | ||
44 | static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) | |
45 | { | |
46 | return(-EPERM); | |
47 | } | |
48 | ||
5e7672ec | 49 | static const struct net_kern_info pcap_kern_info = { |
1da177e4 LT |
50 | .init = pcap_init, |
51 | .protocol = eth_protocol, | |
52 | .read = pcap_read, | |
53 | .write = pcap_write, | |
54 | }; | |
55 | ||
56 | int pcap_setup(char *str, char **mac_out, void *data) | |
57 | { | |
58 | struct pcap_init *init = data; | |
59 | char *remain, *host_if = NULL, *options[2] = { NULL, NULL }; | |
60 | int i; | |
61 | ||
62 | *init = ((struct pcap_init) | |
63 | { .host_if = "eth0", | |
64 | .promisc = 1, | |
65 | .optimize = 0, | |
66 | .filter = NULL }); | |
67 | ||
68 | remain = split_if_spec(str, &host_if, &init->filter, | |
69 | &options[0], &options[1], NULL); | |
70 | if(remain != NULL){ | |
71 | printk(KERN_ERR "pcap_setup - Extra garbage on " | |
72 | "specification : '%s'\n", remain); | |
73 | return(0); | |
74 | } | |
75 | ||
76 | if(host_if != NULL) | |
77 | init->host_if = host_if; | |
78 | ||
91b165c0 | 79 | for(i = 0; i < ARRAY_SIZE(options); i++){ |
1da177e4 LT |
80 | if(options[i] == NULL) |
81 | continue; | |
82 | if(!strcmp(options[i], "promisc")) | |
83 | init->promisc = 1; | |
84 | else if(!strcmp(options[i], "nopromisc")) | |
85 | init->promisc = 0; | |
86 | else if(!strcmp(options[i], "optimize")) | |
87 | init->optimize = 1; | |
88 | else if(!strcmp(options[i], "nooptimize")) | |
89 | init->optimize = 0; | |
90 | else printk("pcap_setup : bad option - '%s'\n", options[i]); | |
91 | } | |
92 | ||
93 | return(1); | |
94 | } | |
95 | ||
96 | static struct transport pcap_transport = { | |
97 | .list = LIST_HEAD_INIT(pcap_transport.list), | |
98 | .name = "pcap", | |
99 | .setup = pcap_setup, | |
100 | .user = &pcap_user_info, | |
101 | .kern = &pcap_kern_info, | |
102 | .private_size = sizeof(struct pcap_data), | |
103 | .setup_size = sizeof(struct pcap_init), | |
104 | }; | |
105 | ||
106 | static int register_pcap(void) | |
107 | { | |
108 | register_transport(&pcap_transport); | |
f4c57a78 | 109 | return 0; |
1da177e4 LT |
110 | } |
111 | ||
8210fd2a | 112 | late_initcall(register_pcap); |