11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Copyright (C) 2002 Jeff Dike <jdike@karaya.com> 31da177e4SLinus Torvalds * Licensed under the GPL. 41da177e4SLinus Torvalds */ 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds #include "linux/init.h" 71da177e4SLinus Torvalds #include "linux/netdevice.h" 81da177e4SLinus Torvalds #include "linux/etherdevice.h" 91da177e4SLinus Torvalds #include "net_kern.h" 101da177e4SLinus Torvalds #include "net_user.h" 111da177e4SLinus Torvalds #include "pcap_user.h" 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds struct pcap_init { 141da177e4SLinus Torvalds char *host_if; 151da177e4SLinus Torvalds int promisc; 161da177e4SLinus Torvalds int optimize; 171da177e4SLinus Torvalds char *filter; 181da177e4SLinus Torvalds }; 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds void pcap_init(struct net_device *dev, void *data) 211da177e4SLinus Torvalds { 221da177e4SLinus Torvalds struct uml_net_private *pri; 231da177e4SLinus Torvalds struct pcap_data *ppri; 241da177e4SLinus Torvalds struct pcap_init *init = data; 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds pri = dev->priv; 271da177e4SLinus Torvalds ppri = (struct pcap_data *) pri->user; 281da177e4SLinus Torvalds ppri->host_if = init->host_if; 291da177e4SLinus Torvalds ppri->promisc = init->promisc; 301da177e4SLinus Torvalds ppri->optimize = init->optimize; 311da177e4SLinus Torvalds ppri->filter = init->filter; 321da177e4SLinus Torvalds } 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds static int pcap_read(int fd, struct sk_buff **skb, 351da177e4SLinus Torvalds struct uml_net_private *lp) 361da177e4SLinus Torvalds { 371da177e4SLinus Torvalds *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 381da177e4SLinus Torvalds if(*skb == NULL) return(-ENOMEM); 391da177e4SLinus Torvalds return(pcap_user_read(fd, (*skb)->mac.raw, 401da177e4SLinus Torvalds (*skb)->dev->mtu + ETH_HEADER_OTHER, 411da177e4SLinus Torvalds (struct pcap_data *) &lp->user)); 421da177e4SLinus Torvalds } 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) 451da177e4SLinus Torvalds { 461da177e4SLinus Torvalds return(-EPERM); 471da177e4SLinus Torvalds } 481da177e4SLinus Torvalds 495e7672ecSJeff Dike static const struct net_kern_info pcap_kern_info = { 501da177e4SLinus Torvalds .init = pcap_init, 511da177e4SLinus Torvalds .protocol = eth_protocol, 521da177e4SLinus Torvalds .read = pcap_read, 531da177e4SLinus Torvalds .write = pcap_write, 541da177e4SLinus Torvalds }; 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds int pcap_setup(char *str, char **mac_out, void *data) 571da177e4SLinus Torvalds { 581da177e4SLinus Torvalds struct pcap_init *init = data; 591da177e4SLinus Torvalds char *remain, *host_if = NULL, *options[2] = { NULL, NULL }; 601da177e4SLinus Torvalds int i; 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds *init = ((struct pcap_init) 631da177e4SLinus Torvalds { .host_if = "eth0", 641da177e4SLinus Torvalds .promisc = 1, 651da177e4SLinus Torvalds .optimize = 0, 661da177e4SLinus Torvalds .filter = NULL }); 671da177e4SLinus Torvalds 681da177e4SLinus Torvalds remain = split_if_spec(str, &host_if, &init->filter, 691da177e4SLinus Torvalds &options[0], &options[1], NULL); 701da177e4SLinus Torvalds if(remain != NULL){ 711da177e4SLinus Torvalds printk(KERN_ERR "pcap_setup - Extra garbage on " 721da177e4SLinus Torvalds "specification : '%s'\n", remain); 731da177e4SLinus Torvalds return(0); 741da177e4SLinus Torvalds } 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds if(host_if != NULL) 771da177e4SLinus Torvalds init->host_if = host_if; 781da177e4SLinus Torvalds 7991b165c0SJeff Dike for(i = 0; i < ARRAY_SIZE(options); i++){ 801da177e4SLinus Torvalds if(options[i] == NULL) 811da177e4SLinus Torvalds continue; 821da177e4SLinus Torvalds if(!strcmp(options[i], "promisc")) 831da177e4SLinus Torvalds init->promisc = 1; 841da177e4SLinus Torvalds else if(!strcmp(options[i], "nopromisc")) 851da177e4SLinus Torvalds init->promisc = 0; 861da177e4SLinus Torvalds else if(!strcmp(options[i], "optimize")) 871da177e4SLinus Torvalds init->optimize = 1; 881da177e4SLinus Torvalds else if(!strcmp(options[i], "nooptimize")) 891da177e4SLinus Torvalds init->optimize = 0; 901da177e4SLinus Torvalds else printk("pcap_setup : bad option - '%s'\n", options[i]); 911da177e4SLinus Torvalds } 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds return(1); 941da177e4SLinus Torvalds } 951da177e4SLinus Torvalds 961da177e4SLinus Torvalds static struct transport pcap_transport = { 971da177e4SLinus Torvalds .list = LIST_HEAD_INIT(pcap_transport.list), 981da177e4SLinus Torvalds .name = "pcap", 991da177e4SLinus Torvalds .setup = pcap_setup, 1001da177e4SLinus Torvalds .user = &pcap_user_info, 1011da177e4SLinus Torvalds .kern = &pcap_kern_info, 1021da177e4SLinus Torvalds .private_size = sizeof(struct pcap_data), 1031da177e4SLinus Torvalds .setup_size = sizeof(struct pcap_init), 1041da177e4SLinus Torvalds }; 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds static int register_pcap(void) 1071da177e4SLinus Torvalds { 1081da177e4SLinus Torvalds register_transport(&pcap_transport); 109f4c57a78SJeff Dike return 0; 1101da177e4SLinus Torvalds } 1111da177e4SLinus Torvalds 112*8210fd2aSJeff Dike late_initcall(register_pcap); 113