blob: 822092f149bedb666740b1958b0778cd9ca01b3d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * user-mode-linux networking multicast transport
3 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
Jeff Dikecd1ae0e2007-10-16 01:27:29 -07004 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 * based on the existing uml-networking code, which is
Jeff Dikecd1ae0e2007-10-16 01:27:29 -07007 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 * James Leu (jleu@mindspring.net).
9 * Copyright (C) 2001 by various other people who didn't put their name here.
10 *
11 * Licensed under the GPL.
12 */
13
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#include "linux/init.h"
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070015#include <linux/netdevice.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include "mcast.h"
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070017#include "net_kern.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
19struct mcast_init {
20 char *addr;
21 int port;
22 int ttl;
23};
24
Paolo 'Blaisorblade' Giarrusso42947cb2006-02-01 03:06:29 -080025static void mcast_init(struct net_device *dev, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -070026{
27 struct uml_net_private *pri;
28 struct mcast_data *dpri;
29 struct mcast_init *init = data;
30
31 pri = dev->priv;
32 dpri = (struct mcast_data *) pri->user;
33 dpri->addr = init->addr;
34 dpri->port = init->port;
35 dpri->ttl = init->ttl;
36 dpri->dev = dev;
37
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070038 printk("mcast backend multicast address: %s:%u, TTL:%u\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 dpri->addr, dpri->port, dpri->ttl);
Linus Torvalds1da177e2005-04-16 15:20:36 -070040}
41
Jeff Dikeb53f35a2007-10-16 01:27:31 -070042static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070043{
Jeff Dikeb53f35a2007-10-16 01:27:31 -070044 return net_recvfrom(fd, skb_mac_header(skb),
45 skb->dev->mtu + ETH_HEADER_OTHER);
Linus Torvalds1da177e2005-04-16 15:20:36 -070046}
47
Jeff Dikeb53f35a2007-10-16 01:27:31 -070048static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070049{
Jeff Dikeb53f35a2007-10-16 01:27:31 -070050 return mcast_user_write(fd, skb->data, skb->len,
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070051 (struct mcast_data *) &lp->user);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052}
53
Jeff Dike5e7672e2006-09-27 01:50:33 -070054static const struct net_kern_info mcast_kern_info = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 .init = mcast_init,
56 .protocol = eth_protocol,
57 .read = mcast_read,
58 .write = mcast_write,
59};
60
61int mcast_setup(char *str, char **mac_out, void *data)
62{
63 struct mcast_init *init = data;
64 char *port_str = NULL, *ttl_str = NULL, *remain;
65 char *last;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
67 *init = ((struct mcast_init)
68 { .addr = "239.192.168.1",
69 .port = 1102,
70 .ttl = 1 });
71
72 remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
73 NULL);
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070074 if (remain != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 printk(KERN_ERR "mcast_setup - Extra garbage on "
76 "specification : '%s'\n", remain);
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070077 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 }
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070079
80 if (port_str != NULL) {
Jeff Dike7c00c312005-05-20 13:59:09 -070081 init->port = simple_strtoul(port_str, &last, 10);
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070082 if ((*last != '\0') || (last == port_str)) {
83 printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 port_str);
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070085 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 }
88
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070089 if (ttl_str != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 init->ttl = simple_strtoul(ttl_str, &last, 10);
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070091 if ((*last != '\0') || (last == ttl_str)) {
92 printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 ttl_str);
Jeff Dikecd1ae0e2007-10-16 01:27:29 -070094 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 }
96 }
97
98 printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
99 init->port, init->ttl);
100
Jeff Dikecd1ae0e2007-10-16 01:27:29 -0700101 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102}
103
104static struct transport mcast_transport = {
105 .list = LIST_HEAD_INIT(mcast_transport.list),
106 .name = "mcast",
107 .setup = mcast_setup,
108 .user = &mcast_user_info,
109 .kern = &mcast_kern_info,
110 .private_size = sizeof(struct mcast_data),
111 .setup_size = sizeof(struct mcast_init),
112};
113
114static int register_mcast(void)
115{
116 register_transport(&mcast_transport);
Jeff Dikef4c57a72006-03-31 02:30:10 -0800117 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118}
119
Jeff Dike8210fd22006-12-06 20:34:55 -0800120late_initcall(register_mcast);