linux/arch/um/drivers/slirp_kern.c
<<
>>
Prefs
   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>
   7#include "linux/init.h"
   8#include <linux/netdevice.h>
   9#include <linux/string.h>
  10#include "net_kern.h"
  11#include "net_user.h"
  12#include "slirp.h"
  13
  14struct slirp_init {
  15        struct arg_list_dummy_wrapper argw;  /* XXX should be simpler... */
  16};
  17
  18void 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
  25        private = netdev_priv(dev);
  26        spri = (struct slirp_data *) private->user;
  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);
  34
  35        dev->hard_header_len = 0;
  36        dev->header_ops = 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        printk("\n");
  45}
  46
  47static unsigned short slirp_protocol(struct sk_buff *skbuff)
  48{
  49        return htons(ETH_P_IP);
  50}
  51
  52static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
  53{
  54        return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
  55                               (struct slirp_data *) &lp->user);
  56}
  57
  58static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
  59{
  60        return slirp_user_write(fd, skb->data, skb->len,
  61                                (struct slirp_data *) &lp->user);
  62}
  63
  64const struct net_kern_info slirp_kern_info = {
  65        .init                   = slirp_init,
  66        .protocol               = slirp_protocol,
  67        .read                   = slirp_read,
  68        .write                  = slirp_write,
  69};
  70
  71static int slirp_setup(char *str, char **mac_out, void *data)
  72{
  73        struct slirp_init *init = data;
  74        int i=0;
  75
  76        *init = ((struct slirp_init) { .argw = { { "slirp", NULL  } } });
  77
  78        str = split_if_spec(str, mac_out, NULL);
  79
  80        if (str == NULL) /* no command line given after MAC addr */
  81                return 1;
  82
  83        do {
  84                if (i >= SLIRP_MAX_ARGS - 1) {
  85                        printk(KERN_WARNING "slirp_setup: truncating slirp "
  86                               "arguments\n");
  87                        break;
  88                }
  89                init->argw.argv[i++] = str;
  90                while(*str && *str!=',') {
  91                        if (*str == '_')
  92                                *str=' ';
  93                        str++;
  94                }
  95                if (*str != ',')
  96                        break;
  97                *str++ = '\0';
  98        } while (1);
  99
 100        init->argw.argv[i] = NULL;
 101        return 1;
 102}
 103
 104static 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
 114static int register_slirp(void)
 115{
 116        register_transport(&slirp_transport);
 117        return 0;
 118}
 119
 120late_initcall(register_slirp);
 121