11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Licensed under the GPL. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 637185b33240870719b6b5913a46e6a441f1ae96fAl Viro#include <linux/init.h> 7cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike#include <linux/netdevice.h> 837185b33240870719b6b5913a46e6a441f1ae96fAl Viro#include <net_kern.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pcap_user.h" 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pcap_init { 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *host_if; 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int promisc; 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int optimize; 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *filter; 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid pcap_init(struct net_device *dev, void *data) 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct uml_net_private *pri; 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pcap_data *ppri; 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pcap_init *init = data; 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2417c324fa80914e5b39d423dfd1a3cd61a3ec9866Wang Chen pri = netdev_priv(dev); 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppri = (struct pcap_data *) pri->user; 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppri->host_if = init->host_if; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppri->promisc = init->promisc; 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppri->optimize = init->optimize; 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppri->filter = init->filter; 307d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike 317d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike printk("pcap backend, host interface %s\n", ppri->host_if); 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dikestatic int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 36b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dike return pcap_user_read(fd, skb_mac_header(skb), 37b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dike skb->dev->mtu + ETH_HEADER_OTHER, 387d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike (struct pcap_data *) &lp->user); 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dikestatic int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 437d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike return -EPERM; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 465e7672ec3f059f764fcc5c78216e24bb16c44dbaJeff Dikestatic const struct net_kern_info pcap_kern_info = { 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = pcap_init, 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .protocol = eth_protocol, 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read = pcap_read, 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = pcap_write, 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint pcap_setup(char *str, char **mac_out, void *data) 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pcap_init *init = data; 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *remain, *host_if = NULL, *options[2] = { NULL, NULL }; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *init = ((struct pcap_init) 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { .host_if = "eth0", 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .promisc = 1, 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .optimize = 0, 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .filter = NULL }); 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 657d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike remain = split_if_spec(str, &host_if, &init->filter, 660ba34e197a45c1639aa56aea0399e97f827abb35Jeff Dike &options[0], &options[1], mac_out, NULL); 67cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (remain != NULL) { 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "pcap_setup - Extra garbage on " 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "specification : '%s'\n", remain); 707d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike return 0; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 73cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (host_if != NULL) 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init->host_if = host_if; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 76cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike for (i = 0; i < ARRAY_SIZE(options); i++) { 77cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (options[i] == NULL) 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 79cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (!strcmp(options[i], "promisc")) 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init->promisc = 1; 81cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike else if (!strcmp(options[i], "nopromisc")) 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init->promisc = 0; 83cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike else if (!strcmp(options[i], "optimize")) 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init->optimize = 1; 85cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike else if (!strcmp(options[i], "nooptimize")) 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init->optimize = 0; 877d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike else { 88cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(KERN_ERR "pcap_setup : bad option - '%s'\n", 89cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike options[i]); 907d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike return 0; 917d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike } 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 947d98230a73c21b4d0cee9c3aca38190d215e0e39Jeff Dike return 1; 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct transport pcap_transport = { 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .list = LIST_HEAD_INIT(pcap_transport.list), 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "pcap", 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup = pcap_setup, 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .user = &pcap_user_info, 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kern = &pcap_kern_info, 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .private_size = sizeof(struct pcap_data), 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .setup_size = sizeof(struct pcap_init), 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int register_pcap(void) 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register_transport(&pcap_transport); 110f4c57a78e2c49f188babf675ba0a9264b5374c26Jeff Dike return 0; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1138210fd2a9fe4b36e99ab777a1a81eb47b703c235Jeff Dikelate_initcall(register_pcap); 114