11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * James Leu (jleu@mindspring.net).
4cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2001 by various other people who didn't put their name here.
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Licensed under the GPL.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
937185b33240870719b6b5913a46e6a441f1ae96fAl Viro#include <linux/init.h>
10cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike#include <linux/netdevice.h>
1137185b33240870719b6b5913a46e6a441f1ae96fAl Viro#include <net_kern.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "daemon.h"
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct daemon_init {
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *sock_type;
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *ctl_sock;
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1942947cb98fd16bff21e0000a974ff6bd1e620cd4Paolo 'Blaisorblade' Giarrussostatic void daemon_init(struct net_device *dev, void *data)
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct uml_net_private *pri;
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct daemon_data *dpri;
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct daemon_init *init = data;
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2517c324fa80914e5b39d423dfd1a3cd61a3ec9866Wang Chen	pri = netdev_priv(dev);
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dpri = (struct daemon_data *) pri->user;
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dpri->sock_type = init->sock_type;
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dpri->ctl_sock = init->ctl_sock;
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dpri->fd = -1;
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dpri->control = -1;
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dpri->dev = dev;
32c42791b6ec5453cd7910eac7bfdd88f27173f81cPaolo 'Blaisorblade' Giarrusso	/* We will free this pointer. If it contains crap we're burned. */
33c42791b6ec5453cd7910eac7bfdd88f27173f81cPaolo 'Blaisorblade' Giarrusso	dpri->ctl_addr = NULL;
34c42791b6ec5453cd7910eac7bfdd88f27173f81cPaolo 'Blaisorblade' Giarrusso	dpri->data_addr = NULL;
35c42791b6ec5453cd7910eac7bfdd88f27173f81cPaolo 'Blaisorblade' Giarrusso	dpri->local_addr = NULL;
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
37cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike	printk("daemon backend (uml_switch version %d) - %s:%s",
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("\n");
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
42b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dikestatic int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
44b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dike	return net_recvfrom(fd, skb_mac_header(skb),
45b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dike			    skb->dev->mtu + ETH_HEADER_OTHER);
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
48b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dikestatic int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
50b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dike	return daemon_user_write(fd, skb->data, skb->len,
51cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike				 (struct daemon_data *) &lp->user);
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
545e7672ec3f059f764fcc5c78216e24bb16c44dbaJeff Dikestatic const struct net_kern_info daemon_kern_info = {
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.init			= daemon_init,
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.protocol		= eth_protocol,
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.read			= daemon_read,
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.write			= daemon_write,
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6142947cb98fd16bff21e0000a974ff6bd1e620cd4Paolo 'Blaisorblade' Giarrussostatic int daemon_setup(char *str, char **mac_out, void *data)
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct daemon_init *init = data;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *remain;
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*init = ((struct daemon_init)
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		{ .sock_type 		= "unix",
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		  .ctl_sock 		= "/tmp/uml.ctl" });
69cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       NULL);
72cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike	if (remain != NULL)
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_WARNING "daemon_setup : Ignoring data socket "
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       "specification\n");
75cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike
76cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike	return 1;
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct transport daemon_transport = {
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.list 		= LIST_HEAD_INIT(daemon_transport.list),
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name 		= "daemon",
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.setup  	= daemon_setup,
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.user 		= &daemon_user_info,
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.kern 		= &daemon_kern_info,
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.private_size 	= sizeof(struct daemon_data),
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.setup_size 	= sizeof(struct daemon_init),
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int register_daemon(void)
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	register_transport(&daemon_transport);
92f4c57a78e2c49f188babf675ba0a9264b5374c26Jeff Dike	return 0;
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
958210fd2a9fe4b36e99ab777a1a81eb47b703c235Jeff Dikelate_initcall(register_daemon);
96