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 11 struct slirp_init { 12 struct arg_list_dummy_wrapper argw; /* XXX should be simpler... */ 13 }; 14 15 void 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 *spri = ((struct slirp_data) 25 { .argw = init->argw, 26 .pid = -1, 27 .slave = -1, 28 .ibuf = { '\0' }, 29 .obuf = { '\0' }, 30 .pos = 0, 31 .esc = 0, 32 .dev = dev }); 33 34 dev->init = NULL; 35 dev->hard_header_len = 0; 36 dev->header_cache_update = NULL; 37 dev->hard_header_cache = NULL; 38 dev->hard_header = NULL; 39 dev->addr_len = 0; 40 dev->type = ARPHRD_SLIP; 41 dev->tx_queue_len = 256; 42 dev->flags = IFF_NOARP; 43 printk("SLIRP backend - command line:"); 44 for(i=0;spri->argw.argv[i]!=NULL;i++) { 45 printk(" '%s'",spri->argw.argv[i]); 46 } 47 printk("\n"); 48 } 49 50 static unsigned short slirp_protocol(struct sk_buff *skbuff) 51 { 52 return(htons(ETH_P_IP)); 53 } 54 55 static int slirp_read(int fd, struct sk_buff **skb, 56 struct uml_net_private *lp) 57 { 58 return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 59 (struct slirp_data *) &lp->user)); 60 } 61 62 static int slirp_write(int fd, struct sk_buff **skb, 63 struct uml_net_private *lp) 64 { 65 return(slirp_user_write(fd, (*skb)->data, (*skb)->len, 66 (struct slirp_data *) &lp->user)); 67 } 68 69 struct net_kern_info slirp_kern_info = { 70 .init = slirp_init, 71 .protocol = slirp_protocol, 72 .read = slirp_read, 73 .write = slirp_write, 74 }; 75 76 static int slirp_setup(char *str, char **mac_out, void *data) 77 { 78 struct slirp_init *init = data; 79 int i=0; 80 81 *init = ((struct slirp_init) 82 { argw : { { "slirp", NULL } } }); 83 84 str = split_if_spec(str, mac_out, NULL); 85 86 if(str == NULL) { /* no command line given after MAC addr */ 87 return(1); 88 } 89 90 do { 91 if(i>=SLIRP_MAX_ARGS-1) { 92 printk("slirp_setup: truncating slirp arguments\n"); 93 break; 94 } 95 init->argw.argv[i++] = str; 96 while(*str && *str!=',') { 97 if(*str=='_') *str=' '; 98 str++; 99 } 100 if(*str!=',') 101 break; 102 *str++='\0'; 103 } while(1); 104 init->argw.argv[i]=NULL; 105 return(1); 106 } 107 108 static struct transport slirp_transport = { 109 .list = LIST_HEAD_INIT(slirp_transport.list), 110 .name = "slirp", 111 .setup = slirp_setup, 112 .user = &slirp_user_info, 113 .kern = &slirp_kern_info, 114 .private_size = sizeof(struct slirp_data), 115 .setup_size = sizeof(struct slirp_init), 116 }; 117 118 static int register_slirp(void) 119 { 120 register_transport(&slirp_transport); 121 return(1); 122 } 123 124 __initcall(register_slirp); 125 126 /* 127 * Overrides for Emacs so that we follow Linus's tabbing style. 128 * Emacs will notice this stuff at the end of the file and automatically 129 * adjust the settings for this buffer only. This must remain at the end 130 * of the file. 131 * --------------------------------------------------------------------------- 132 * Local variables: 133 * c-file-style: "linux" 134 * End: 135 */ 136