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 13struct pcap_init { 14 char *host_if; 15 int promisc; 16 int optimize; 17 char *filter; 18}; 19 20void 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 printk("pcap backend, host interface %s\n", ppri->host_if); 34} 35 36static int pcap_read(int fd, struct sk_buff **skb, 37 struct uml_net_private *lp) 38{ 39 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 40 if(*skb == NULL) 41 return -ENOMEM; 42 43 return pcap_user_read(fd, skb_mac_header(*skb), 44 (*skb)->dev->mtu + ETH_HEADER_OTHER, 45 (struct pcap_data *) &lp->user); 46} 47 48static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) 49{ 50 return -EPERM; 51} 52 53static const struct net_kern_info pcap_kern_info = { 54 .init = pcap_init, 55 .protocol = eth_protocol, 56 .read = pcap_read, 57 .write = pcap_write, 58}; 59 60int pcap_setup(char *str, char **mac_out, void *data) 61{ 62 struct pcap_init *init = data; 63 char *remain, *host_if = NULL, *options[2] = { NULL, NULL }; 64 int i; 65 66 *init = ((struct pcap_init) 67 { .host_if = "eth0", 68 .promisc = 1, 69 .optimize = 0, 70 .filter = NULL }); 71 72 remain = split_if_spec(str, &host_if, &init->filter, 73 &options[0], &options[1], mac_out, NULL); 74 if(remain != NULL){ 75 printk(KERN_ERR "pcap_setup - Extra garbage on " 76 "specification : '%s'\n", remain); 77 return 0; 78 } 79 80 if(host_if != NULL) 81 init->host_if = host_if; 82 83 for(i = 0; i < ARRAY_SIZE(options); i++){ 84 if(options[i] == NULL) 85 continue; 86 if(!strcmp(options[i], "promisc")) 87 init->promisc = 1; 88 else if(!strcmp(options[i], "nopromisc")) 89 init->promisc = 0; 90 else if(!strcmp(options[i], "optimize")) 91 init->optimize = 1; 92 else if(!strcmp(options[i], "nooptimize")) 93 init->optimize = 0; 94 else { 95 printk("pcap_setup : bad option - '%s'\n", options[i]); 96 return 0; 97 } 98 } 99 100 return 1; 101} 102 103static struct transport pcap_transport = { 104 .list = LIST_HEAD_INIT(pcap_transport.list), 105 .name = "pcap", 106 .setup = pcap_setup, 107 .user = &pcap_user_info, 108 .kern = &pcap_kern_info, 109 .private_size = sizeof(struct pcap_data), 110 .setup_size = sizeof(struct pcap_init), 111}; 112 113static int register_pcap(void) 114{ 115 register_transport(&pcap_transport); 116 return 0; 117} 118 119late_initcall(register_pcap); 120