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 49 static const struct net_kern_info pcap_kern_info = { 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 79 for(i = 0; i < ARRAY_SIZE(options); i++){ 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); 109 return 0; 110 } 111 112 __initcall(register_pcap); 113