Commit | Line | Data |
---|---|---|
cd1ae0e4 JD |
1 | /* |
2 | * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) | |
3 | * Licensed under the GPL. | |
4 | */ | |
5 | ||
6 | #include <linux/if_arp.h> | |
37185b33 | 7 | #include <linux/init.h> |
cd1ae0e4 JD |
8 | #include <linux/netdevice.h> |
9 | #include <linux/string.h> | |
37185b33 AV |
10 | #include <net_kern.h> |
11 | #include <net_user.h> | |
1da177e4 LT |
12 | #include "slirp.h" |
13 | ||
14 | struct slirp_init { | |
15 | struct arg_list_dummy_wrapper argw; /* XXX should be simpler... */ | |
16 | }; | |
17 | ||
18 | void slirp_init(struct net_device *dev, void *data) | |
19 | { | |
20 | struct uml_net_private *private; | |
21 | struct slirp_data *spri; | |
22 | struct slirp_init *init = data; | |
23 | int i; | |
24 | ||
17c324fa | 25 | private = netdev_priv(dev); |
1da177e4 | 26 | spri = (struct slirp_data *) private->user; |
854e981c PBG |
27 | |
28 | spri->argw = init->argw; | |
29 | spri->pid = -1; | |
30 | spri->slave = -1; | |
31 | spri->dev = dev; | |
32 | ||
33 | slip_proto_init(&spri->slip); | |
1da177e4 | 34 | |
1da177e4 | 35 | dev->hard_header_len = 0; |
be8ad5a4 | 36 | dev->header_ops = NULL; |
1da177e4 LT |
37 | dev->addr_len = 0; |
38 | dev->type = ARPHRD_SLIP; | |
39 | dev->tx_queue_len = 256; | |
40 | dev->flags = IFF_NOARP; | |
41 | printk("SLIRP backend - command line:"); | |
cd1ae0e4 | 42 | for (i = 0; spri->argw.argv[i] != NULL; i++) |
1da177e4 | 43 | printk(" '%s'",spri->argw.argv[i]); |
1da177e4 LT |
44 | printk("\n"); |
45 | } | |
46 | ||
47 | static unsigned short slirp_protocol(struct sk_buff *skbuff) | |
48 | { | |
cd1ae0e4 | 49 | return htons(ETH_P_IP); |
1da177e4 LT |
50 | } |
51 | ||
b53f35a8 | 52 | static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
1da177e4 | 53 | { |
b53f35a8 JD |
54 | return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu, |
55 | (struct slirp_data *) &lp->user); | |
1da177e4 LT |
56 | } |
57 | ||
b53f35a8 | 58 | static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
1da177e4 | 59 | { |
b53f35a8 JD |
60 | return slirp_user_write(fd, skb->data, skb->len, |
61 | (struct slirp_data *) &lp->user); | |
1da177e4 LT |
62 | } |
63 | ||
5e7672ec | 64 | const struct net_kern_info slirp_kern_info = { |
1da177e4 LT |
65 | .init = slirp_init, |
66 | .protocol = slirp_protocol, | |
67 | .read = slirp_read, | |
68 | .write = slirp_write, | |
69 | }; | |
70 | ||
71 | static int slirp_setup(char *str, char **mac_out, void *data) | |
72 | { | |
73 | struct slirp_init *init = data; | |
74 | int i=0; | |
75 | ||
cd1ae0e4 | 76 | *init = ((struct slirp_init) { .argw = { { "slirp", NULL } } }); |
1da177e4 LT |
77 | |
78 | str = split_if_spec(str, mac_out, NULL); | |
79 | ||
cd1ae0e4 JD |
80 | if (str == NULL) /* no command line given after MAC addr */ |
81 | return 1; | |
1da177e4 LT |
82 | |
83 | do { | |
cd1ae0e4 JD |
84 | if (i >= SLIRP_MAX_ARGS - 1) { |
85 | printk(KERN_WARNING "slirp_setup: truncating slirp " | |
86 | "arguments\n"); | |
1da177e4 LT |
87 | break; |
88 | } | |
89 | init->argw.argv[i++] = str; | |
90 | while(*str && *str!=',') { | |
cd1ae0e4 JD |
91 | if (*str == '_') |
92 | *str=' '; | |
1da177e4 LT |
93 | str++; |
94 | } | |
cd1ae0e4 | 95 | if (*str != ',') |
1da177e4 | 96 | break; |
cd1ae0e4 JD |
97 | *str++ = '\0'; |
98 | } while (1); | |
99 | ||
100 | init->argw.argv[i] = NULL; | |
101 | return 1; | |
1da177e4 LT |
102 | } |
103 | ||
104 | static struct transport slirp_transport = { | |
105 | .list = LIST_HEAD_INIT(slirp_transport.list), | |
106 | .name = "slirp", | |
107 | .setup = slirp_setup, | |
108 | .user = &slirp_user_info, | |
109 | .kern = &slirp_kern_info, | |
110 | .private_size = sizeof(struct slirp_data), | |
111 | .setup_size = sizeof(struct slirp_init), | |
112 | }; | |
113 | ||
114 | static int register_slirp(void) | |
115 | { | |
116 | register_transport(&slirp_transport); | |
f4c57a78 | 117 | return 0; |
1da177e4 LT |
118 | } |
119 | ||
8210fd2a | 120 | late_initcall(register_slirp); |