mcast_kern.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * user-mode-linux networking multicast transport
  3. * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
  4. * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  5. *
  6. * based on the existing uml-networking code, which is
  7. * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
  8. * 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. #include "linux/init.h"
  14. #include <linux/netdevice.h>
  15. #include "mcast.h"
  16. #include "net_kern.h"
  17. struct mcast_init {
  18. char *addr;
  19. int port;
  20. int ttl;
  21. };
  22. static void mcast_init(struct net_device *dev, void *data)
  23. {
  24. struct uml_net_private *pri;
  25. struct mcast_data *dpri;
  26. struct mcast_init *init = data;
  27. pri = dev->priv;
  28. dpri = (struct mcast_data *) pri->user;
  29. dpri->addr = init->addr;
  30. dpri->port = init->port;
  31. dpri->ttl = init->ttl;
  32. dpri->dev = dev;
  33. printk("mcast backend multicast address: %s:%u, TTL:%u\n",
  34. dpri->addr, dpri->port, dpri->ttl);
  35. }
  36. static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
  37. {
  38. *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
  39. if (*skb == NULL)
  40. return -ENOMEM;
  41. return net_recvfrom(fd, skb_mac_header(*skb),
  42. (*skb)->dev->mtu + ETH_HEADER_OTHER);
  43. }
  44. static int mcast_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
  45. {
  46. return mcast_user_write(fd, (*skb)->data, (*skb)->len,
  47. (struct mcast_data *) &lp->user);
  48. }
  49. static const struct net_kern_info mcast_kern_info = {
  50. .init = mcast_init,
  51. .protocol = eth_protocol,
  52. .read = mcast_read,
  53. .write = mcast_write,
  54. };
  55. int mcast_setup(char *str, char **mac_out, void *data)
  56. {
  57. struct mcast_init *init = data;
  58. char *port_str = NULL, *ttl_str = NULL, *remain;
  59. char *last;
  60. *init = ((struct mcast_init)
  61. { .addr = "239.192.168.1",
  62. .port = 1102,
  63. .ttl = 1 });
  64. remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
  65. NULL);
  66. if (remain != NULL) {
  67. printk(KERN_ERR "mcast_setup - Extra garbage on "
  68. "specification : '%s'\n", remain);
  69. return 0;
  70. }
  71. if (port_str != NULL) {
  72. init->port = simple_strtoul(port_str, &last, 10);
  73. if ((*last != '\0') || (last == port_str)) {
  74. printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
  75. port_str);
  76. return 0;
  77. }
  78. }
  79. if (ttl_str != NULL) {
  80. init->ttl = simple_strtoul(ttl_str, &last, 10);
  81. if ((*last != '\0') || (last == ttl_str)) {
  82. printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
  83. ttl_str);
  84. return 0;
  85. }
  86. }
  87. printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
  88. init->port, init->ttl);
  89. return 1;
  90. }
  91. static struct transport mcast_transport = {
  92. .list = LIST_HEAD_INIT(mcast_transport.list),
  93. .name = "mcast",
  94. .setup = mcast_setup,
  95. .user = &mcast_user_info,
  96. .kern = &mcast_kern_info,
  97. .private_size = sizeof(struct mcast_data),
  98. .setup_size = sizeof(struct mcast_init),
  99. };
  100. static int register_mcast(void)
  101. {
  102. register_transport(&mcast_transport);
  103. return 0;
  104. }
  105. late_initcall(register_mcast);