11da177e4SLinus Torvalds #include "linux/kernel.h" 21da177e4SLinus Torvalds #include "linux/stddef.h" 31da177e4SLinus Torvalds #include "linux/init.h" 41da177e4SLinus Torvalds #include "linux/netdevice.h" 51da177e4SLinus Torvalds #include "linux/if_arp.h" 61da177e4SLinus Torvalds #include "net_kern.h" 71da177e4SLinus Torvalds #include "net_user.h" 81da177e4SLinus Torvalds #include "kern.h" 91da177e4SLinus Torvalds #include "slirp.h" 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds struct slirp_init { 121da177e4SLinus Torvalds struct arg_list_dummy_wrapper argw; /* XXX should be simpler... */ 131da177e4SLinus Torvalds }; 141da177e4SLinus Torvalds 151da177e4SLinus Torvalds void slirp_init(struct net_device *dev, void *data) 161da177e4SLinus Torvalds { 171da177e4SLinus Torvalds struct uml_net_private *private; 181da177e4SLinus Torvalds struct slirp_data *spri; 191da177e4SLinus Torvalds struct slirp_init *init = data; 201da177e4SLinus Torvalds int i; 211da177e4SLinus Torvalds 221da177e4SLinus Torvalds private = dev->priv; 231da177e4SLinus Torvalds spri = (struct slirp_data *) private->user; 24854e981cSPaolo 'Blaisorblade' Giarrusso 25854e981cSPaolo 'Blaisorblade' Giarrusso spri->argw = init->argw; 26854e981cSPaolo 'Blaisorblade' Giarrusso spri->pid = -1; 27854e981cSPaolo 'Blaisorblade' Giarrusso spri->slave = -1; 28854e981cSPaolo 'Blaisorblade' Giarrusso spri->dev = dev; 29854e981cSPaolo 'Blaisorblade' Giarrusso 30854e981cSPaolo 'Blaisorblade' Giarrusso slip_proto_init(&spri->slip); 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds dev->init = NULL; 331da177e4SLinus Torvalds dev->hard_header_len = 0; 341da177e4SLinus Torvalds dev->header_cache_update = NULL; 351da177e4SLinus Torvalds dev->hard_header_cache = NULL; 361da177e4SLinus Torvalds dev->hard_header = NULL; 371da177e4SLinus Torvalds dev->addr_len = 0; 381da177e4SLinus Torvalds dev->type = ARPHRD_SLIP; 391da177e4SLinus Torvalds dev->tx_queue_len = 256; 401da177e4SLinus Torvalds dev->flags = IFF_NOARP; 411da177e4SLinus Torvalds printk("SLIRP backend - command line:"); 421da177e4SLinus Torvalds for(i=0;spri->argw.argv[i]!=NULL;i++) { 431da177e4SLinus Torvalds printk(" '%s'",spri->argw.argv[i]); 441da177e4SLinus Torvalds } 451da177e4SLinus Torvalds printk("\n"); 461da177e4SLinus Torvalds } 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds static unsigned short slirp_protocol(struct sk_buff *skbuff) 491da177e4SLinus Torvalds { 501da177e4SLinus Torvalds return(htons(ETH_P_IP)); 511da177e4SLinus Torvalds } 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds static int slirp_read(int fd, struct sk_buff **skb, 541da177e4SLinus Torvalds struct uml_net_private *lp) 551da177e4SLinus Torvalds { 561da177e4SLinus Torvalds return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 571da177e4SLinus Torvalds (struct slirp_data *) &lp->user)); 581da177e4SLinus Torvalds } 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds static int slirp_write(int fd, struct sk_buff **skb, 611da177e4SLinus Torvalds struct uml_net_private *lp) 621da177e4SLinus Torvalds { 631da177e4SLinus Torvalds return(slirp_user_write(fd, (*skb)->data, (*skb)->len, 641da177e4SLinus Torvalds (struct slirp_data *) &lp->user)); 651da177e4SLinus Torvalds } 661da177e4SLinus Torvalds 671da177e4SLinus Torvalds struct net_kern_info slirp_kern_info = { 681da177e4SLinus Torvalds .init = slirp_init, 691da177e4SLinus Torvalds .protocol = slirp_protocol, 701da177e4SLinus Torvalds .read = slirp_read, 711da177e4SLinus Torvalds .write = slirp_write, 721da177e4SLinus Torvalds }; 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds static int slirp_setup(char *str, char **mac_out, void *data) 751da177e4SLinus Torvalds { 761da177e4SLinus Torvalds struct slirp_init *init = data; 771da177e4SLinus Torvalds int i=0; 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds *init = ((struct slirp_init) 801da177e4SLinus Torvalds { argw : { { "slirp", NULL } } }); 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds str = split_if_spec(str, mac_out, NULL); 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds if(str == NULL) { /* no command line given after MAC addr */ 851da177e4SLinus Torvalds return(1); 861da177e4SLinus Torvalds } 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds do { 891da177e4SLinus Torvalds if(i>=SLIRP_MAX_ARGS-1) { 901da177e4SLinus Torvalds printk("slirp_setup: truncating slirp arguments\n"); 911da177e4SLinus Torvalds break; 921da177e4SLinus Torvalds } 931da177e4SLinus Torvalds init->argw.argv[i++] = str; 941da177e4SLinus Torvalds while(*str && *str!=',') { 951da177e4SLinus Torvalds if(*str=='_') *str=' '; 961da177e4SLinus Torvalds str++; 971da177e4SLinus Torvalds } 981da177e4SLinus Torvalds if(*str!=',') 991da177e4SLinus Torvalds break; 1001da177e4SLinus Torvalds *str++='\0'; 1011da177e4SLinus Torvalds } while(1); 1021da177e4SLinus Torvalds init->argw.argv[i]=NULL; 1031da177e4SLinus Torvalds return(1); 1041da177e4SLinus Torvalds } 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds static struct transport slirp_transport = { 1071da177e4SLinus Torvalds .list = LIST_HEAD_INIT(slirp_transport.list), 1081da177e4SLinus Torvalds .name = "slirp", 1091da177e4SLinus Torvalds .setup = slirp_setup, 1101da177e4SLinus Torvalds .user = &slirp_user_info, 1111da177e4SLinus Torvalds .kern = &slirp_kern_info, 1121da177e4SLinus Torvalds .private_size = sizeof(struct slirp_data), 1131da177e4SLinus Torvalds .setup_size = sizeof(struct slirp_init), 1141da177e4SLinus Torvalds }; 1151da177e4SLinus Torvalds 1161da177e4SLinus Torvalds static int register_slirp(void) 1171da177e4SLinus Torvalds { 1181da177e4SLinus Torvalds register_transport(&slirp_transport); 119*f4c57a78SJeff Dike return 0; 1201da177e4SLinus Torvalds } 1211da177e4SLinus Torvalds 1221da177e4SLinus Torvalds __initcall(register_slirp); 123