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