1#include "linux/kernel.h" 2#include "linux/stddef.h" 3#include "linux/init.h" 4#include "linux/netdevice.h" 5#include "linux/if_arp.h" 6#include "net_kern.h" 7#include "net_user.h" 8#include "kern.h" 9#include "slirp.h" 10 11struct slirp_init { 12 struct arg_list_dummy_wrapper argw; 13}; 14 15void slirp_init(struct net_device *dev, void *data) 16{ 17 struct uml_net_private *private; 18 struct slirp_data *spri; 19 struct slirp_init *init = data; 20 int i; 21 22 private = dev->priv; 23 spri = (struct slirp_data *) private->user; 24 25 spri->argw = init->argw; 26 spri->pid = -1; 27 spri->slave = -1; 28 spri->dev = dev; 29 30 slip_proto_init(&spri->slip); 31 32 dev->init = NULL; 33 dev->hard_header_len = 0; 34 dev->header_cache_update = NULL; 35 dev->hard_header_cache = NULL; 36 dev->hard_header = NULL; 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:"); 42 for(i=0;spri->argw.argv[i]!=NULL;i++) { 43 printk(" '%s'",spri->argw.argv[i]); 44 } 45 printk("\n"); 46} 47 48static unsigned short slirp_protocol(struct sk_buff *skbuff) 49{ 50 return(htons(ETH_P_IP)); 51} 52 53static int slirp_read(int fd, struct sk_buff **skb, 54 struct uml_net_private *lp) 55{ 56 return(slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, 57 (struct slirp_data *) &lp->user)); 58} 59 60static int slirp_write(int fd, struct sk_buff **skb, 61 struct uml_net_private *lp) 62{ 63 return(slirp_user_write(fd, (*skb)->data, (*skb)->len, 64 (struct slirp_data *) &lp->user)); 65} 66 67const struct net_kern_info slirp_kern_info = { 68 .init = slirp_init, 69 .protocol = slirp_protocol, 70 .read = slirp_read, 71 .write = slirp_write, 72}; 73 74static int slirp_setup(char *str, char **mac_out, void *data) 75{ 76 struct slirp_init *init = data; 77 int i=0; 78 79 *init = ((struct slirp_init) 80 { .argw = { { "slirp", NULL } } }); 81 82 str = split_if_spec(str, mac_out, NULL); 83 84 if(str == NULL) { /* no command line given after MAC addr */ 85 return(1); 86 } 87 88 do { 89 if(i>=SLIRP_MAX_ARGS-1) { 90 printk("slirp_setup: truncating slirp arguments\n"); 91 break; 92 } 93 init->argw.argv[i++] = str; 94 while(*str && *str!=',') { 95 if(*str=='_') *str=' '; 96 str++; 97 } 98 if(*str!=',') 99 break; 100 *str++='\0'; 101 } while(1); 102 init->argw.argv[i]=NULL; 103 return(1); 104} 105 106static struct transport slirp_transport = { 107 .list = LIST_HEAD_INIT(slirp_transport.list), 108 .name = "slirp", 109 .setup = slirp_setup, 110 .user = &slirp_user_info, 111 .kern = &slirp_kern_info, 112 .private_size = sizeof(struct slirp_data), 113 .setup_size = sizeof(struct slirp_init), 114}; 115 116static int register_slirp(void) 117{ 118 register_transport(&slirp_transport); 119 return 0; 120} 121 122late_initcall(register_slirp); 123