^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <net_kern.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "pcap_user.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct pcap_init {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) char *host_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) int promisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) int optimize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) char *filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) void pcap_init(struct net_device *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct uml_net_private *pri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct pcap_data *ppri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct pcap_init *init = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) pri = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) ppri = (struct pcap_data *) pri->user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ppri->host_if = init->host_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ppri->promisc = init->promisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ppri->optimize = init->optimize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ppri->filter = init->filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) printk("pcap backend, host interface %s\n", ppri->host_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return pcap_user_read(fd, skb_mac_header(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) skb->dev->mtu + ETH_HEADER_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) (struct pcap_data *) &lp->user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static const struct net_kern_info pcap_kern_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .init = pcap_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .protocol = eth_protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .read = pcap_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .write = pcap_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int pcap_setup(char *str, char **mac_out, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct pcap_init *init = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *init = ((struct pcap_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) { .host_if = "eth0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .promisc = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .optimize = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .filter = NULL });
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) remain = split_if_spec(str, &host_if, &init->filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) &options[0], &options[1], mac_out, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (remain != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) printk(KERN_ERR "pcap_setup - Extra garbage on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) "specification : '%s'\n", remain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (host_if != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) init->host_if = host_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) for (i = 0; i < ARRAY_SIZE(options); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (options[i] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!strcmp(options[i], "promisc"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) init->promisc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) else if (!strcmp(options[i], "nopromisc"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) init->promisc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) else if (!strcmp(options[i], "optimize"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) init->optimize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) else if (!strcmp(options[i], "nooptimize"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) init->optimize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) printk(KERN_ERR "pcap_setup : bad option - '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) options[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static struct transport pcap_transport = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .list = LIST_HEAD_INIT(pcap_transport.list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .name = "pcap",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .setup = pcap_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .user = &pcap_user_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .kern = &pcap_kern_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .private_size = sizeof(struct pcap_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .setup_size = sizeof(struct pcap_init),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int register_pcap(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) register_transport(&pcap_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) late_initcall(register_pcap);