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