aboutsummaryrefslogtreecommitdiffstats
path: root/network_cmds/mnc.tproj
diff options
context:
space:
mode:
authorCameron Katri <me@cameronkatri.com>2021-05-09 14:20:58 -0400
committerCameron Katri <me@cameronkatri.com>2021-05-09 14:20:58 -0400
commit5fd83771641d15c418f747bd343ba6738d3875f7 (patch)
tree5abf0f78f680d9837dbd93d4d4c3933bb7509599 /network_cmds/mnc.tproj
downloadapple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.gz
apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.zst
apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.zip
Import macOS userland
adv_cmds-176 basic_cmds-55 bootstrap_cmds-116.100.1 developer_cmds-66 diskdev_cmds-667.40.1 doc_cmds-53.60.1 file_cmds-321.40.3 mail_cmds-35 misc_cmds-34 network_cmds-606.40.1 patch_cmds-17 remote_cmds-63 shell_cmds-216.60.1 system_cmds-880.60.2 text_cmds-106
Diffstat (limited to 'network_cmds/mnc.tproj')
-rw-r--r--network_cmds/mnc.tproj/LICENCE37
-rw-r--r--network_cmds/mnc.tproj/README63
-rw-r--r--network_cmds/mnc.tproj/mnc.1101
-rw-r--r--network_cmds/mnc.tproj/mnc.h92
-rw-r--r--network_cmds/mnc.tproj/mnc_error.c95
-rw-r--r--network_cmds/mnc.tproj/mnc_main.c131
-rw-r--r--network_cmds/mnc.tproj/mnc_multicast.c404
-rw-r--r--network_cmds/mnc.tproj/mnc_opts.c182
8 files changed, 1105 insertions, 0 deletions
diff --git a/network_cmds/mnc.tproj/LICENCE b/network_cmds/mnc.tproj/LICENCE
new file mode 100644
index 0000000..4fec3e3
--- /dev/null
+++ b/network_cmds/mnc.tproj/LICENCE
@@ -0,0 +1,37 @@
+/*
+ * Colm MacCarthaigh, <colm@apache.org>
+ *
+ * Copyright (c) 2007, Colm MacCarthaigh.
+ * Copyright (c) 2004 - 2006, HEAnet Ltd.
+ *
+ * This software is an open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HEAnet Ltd. nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
diff --git a/network_cmds/mnc.tproj/README b/network_cmds/mnc.tproj/README
new file mode 100644
index 0000000..77cbaa8
--- /dev/null
+++ b/network_cmds/mnc.tproj/README
@@ -0,0 +1,63 @@
+1 MNC - Multicast NetCat
+ ------------------------
+
+1. Introduction
+
+mnc is a simple, one-direction-at-a-time, "netcat"-like application using
+multicast. The aim is to provide a tool for easy debugging and testing when
+setting up a multicast network or host. MNC supports IPv4 and IPv6
+any-source-multicast and single-source-multicast, but depending on your
+platform some of those features may not be available:
+
+ L = Listen (Implies IGMP/MLD mupport)
+ S = Send
+
+ +----------+----------+----------+----------+----------+
+ | Platform | IPv4 ASM | IPv4 SSM | IPv6 ASM | IPv6 SSM |
+ +----------+----------+----------+----------+----------+
+ | *nix | L + S | L + S | L + S | L + S |
+ +----------+----------+----------+----------+----------+
+ | Win2k | L + S | S | None | None |
+ +----------+----------+----------+----------+----------+
+ | WinXP | L + S | L + S | S | S |
+ +----------+----------+----------+----------+----------+
+ | Win2k3 | L + S | L + S | S | S |
+ +----------+----------+----------+----------+----------+
+
+man doc/mnc.1 for information and help on how to run multicast.
+
+2. Supported platforms
+
+As of September 2004, mnc has been compiled and tested with Linux 2.6.8
+kernels, the BSD KAME stack and Windows XP Profesional. Currently automatic
+interface selection does not work on a KAME-based host and you will need to
+specify the interface when in listening mode.
+
+3. Installing mnc from source on UNIX:
+
+ ./configure ; make ; make install
+
+4. Compiling from source on Windows:
+
+nmc is compilable with free utilities available from Microsoft. You need to
+download and install the free (as in beer) MS Visual C++ command-line tools
+from:
+
+ http://msdn.microsoft.com/visualc/vctoolkit2003/
+
+and the SDK relevant to your platform from:
+
+ http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
+
+You can run a Visual C++ command-line session, and use:
+
+ cl /DWINDOWS=1 /TC /c *.c
+ link /fixed /out:mnc.exe *.obj ws2_32.lib
+
+to compile a working mnc.exe. The Windows version of MNC does not yet fully
+support IPv6 due to underlying limitation in the Operating System.
+
+5. Reporting problems
+
+Any problems, bugs or suggested features should be mailed to colm
+at apache.org.
diff --git a/network_cmds/mnc.tproj/mnc.1 b/network_cmds/mnc.tproj/mnc.1
new file mode 100644
index 0000000..ed1073b
--- /dev/null
+++ b/network_cmds/mnc.tproj/mnc.1
@@ -0,0 +1,101 @@
+.\"
+.\" mnc.1 -- mnc manual
+.\"
+.\" Colm MacCárthaigh, <colm@apache.org>
+.\"
+.\" Copyright (c) 2007 Coolm MacCarthaigh.
+.\" Copyright (c) 2004-2006 HEAnet Ltd.
+.\"
+.\" This software is an open source.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" Neither the name of the HEAnet Ltd. nor the names of its contributors may
+.\" be used to endorse or promote products derived from this software without
+.\" specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH mnc 1 "17 September 2004" "mnc"
+.SH NAME
+mnc \- Multicast NetCat
+.SH SYNOPSIS
+.BR mnc
+[ -l ] [ -i interface ] [ -p port ] group-id [ source-address ]
+.SH DESCRIPTION
+.B mnc
+is designed for simple multicast debugging and testing. It supports
+IPv4 and IPv6 any-source multicast and source-specific multicast.
+In standard mode it will multicast the standard-input verbatim.
+In listening mode it recieves the content and displays it on the
+standard output.
+.PP
+When given the optional source-address, mnc will attempt to use
+source-specific multicast. You may also specify this address
+in standard mode and mnc will use this source-address for
+outgoing packets.
+.PP
+.SH OPTIONS
+.IP \-l
+Listen for multicast packets. Default is to send.
+.IP \-i\ "interface"
+When listening for multicast packets, use the specified interface.
+.IP \-p\ "port"
+Specify a UDP port to use for sending or receiving packets. Default is to use port 1234.
+.SH "SEE ALSO"
+.BR nc (1)
+.PP
+.SH EXAMPLES
+To send IPv4 packets to an ASM group-id:
+.PP
+.RS
+mnc 233.1.2.3
+.RE
+.PP
+To receive IPv4 ASM packets from the same group-id, using eth0 as
+the listening interface:
+.PP
+.RS
+mnc -l -i eth0 233.1.2.3
+.RE
+.PP
+To receive IPv4 packets from an SSM group-id, using eth1 as the
+listening interface and 193.1.219.90 as the permitted source:
+.PP
+.RS
+mnc -l -i eth1 232.0.0.1 193.1.219.90
+.RE
+.PP
+To receive IPv6 packets from an SSM group-id, using eth1 as the
+listening interface and 2001:770:18:2::90 as the permitted source:
+.PP
+.RS
+mnc -l -i eth1 ff31::12 2001:770:18:2::90
+.RE
+.PP
+.SH CREDITS
+mnc is by Colm MacCárthaigh <colm@apache.org> and is available from:
+.PP
+http://people.apache.org/~colm/mnc/
+.PP
+Additional multicast development and support provided by John Lyons
+<john.lyons@heanet.ie> and Eoin Kenny <eoin.kenny@heanet.ie>
diff --git a/network_cmds/mnc.tproj/mnc.h b/network_cmds/mnc.tproj/mnc.h
new file mode 100644
index 0000000..db6e68e
--- /dev/null
+++ b/network_cmds/mnc.tproj/mnc.h
@@ -0,0 +1,92 @@
+/*
+ * $Id: mnc.h,v 1.4 2004/09/22 14:07:10 colmmacc Exp $
+ *
+ * mnc.h -- Multicast NetCat
+ *
+ * Colm MacCarthaigh, <colm@apache.org>
+ *
+ * Copyright (c) 2007, Colm MacCarthaigh.
+ * Copyright (c) 2004 - 2006, HEAnet Ltd.
+ *
+ * This software is an open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HEAnet Ltd. nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _MNC_H_
+#define _MNC_H_
+
+#ifndef WINDOWS
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#else
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+#endif
+
+/* The UDP port MNC will use by default */
+#define MNC_DEFAULT_PORT "1234"
+
+struct mnc_configuration
+{
+ /* Are we sending or recieving ? */
+ enum {SENDER, LISTENER} mode;
+
+ /* What UDP port are we using ? */
+ char * port;
+
+ /* The group-id */
+ struct addrinfo * group;
+
+ /* The source */
+ struct addrinfo * source;
+
+ /* An interface index for listening */
+ char * iface;
+};
+
+
+/* Functions in mnc_opts.c */
+void usage(void);
+struct mnc_configuration * parse_arguments(int argc, char **argv);
+
+/* Functions in mnc_multicast.c */
+int multicast_setup_listen(int, struct addrinfo *, struct addrinfo *, char *);
+int multicast_setup_send(int, struct addrinfo *, struct addrinfo *);
+
+/* Functions in mnc_error.c */
+void mnc_warning(char * string, ...);
+void mnc_error(char * string, ...);
+
+#endif /* _MNC_H_ */
diff --git a/network_cmds/mnc.tproj/mnc_error.c b/network_cmds/mnc.tproj/mnc_error.c
new file mode 100644
index 0000000..4478e7e
--- /dev/null
+++ b/network_cmds/mnc.tproj/mnc_error.c
@@ -0,0 +1,95 @@
+/*
+ * $Id: mnc_error.c,v 1.2 2004/09/22 16:02:26 colmmacc Exp $
+ *
+ * mnc_multicast.c -- Multicast NetCat
+ *
+ * Colm MacCarthaigh, <colm@apache.org>
+ *
+ * Copyright (c) 2007, Colm MacCarthaigh.
+ * Copyright (c) 2004 - 2006, HEAnet Ltd.
+ *
+ * This software is an open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HEAnet Ltd. nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "mnc.h"
+
+void mnc_warning(char * string, ...)
+{
+ va_list ap;
+
+ /* Do the vararg stuff */
+ va_start(ap, string);
+
+ /* Output our name */
+ if (fprintf(stderr, "mnc: ") < 0)
+ {
+ exit(2);
+ }
+
+ /* Output our error */
+ if (vfprintf(stderr, string, ap) < 0)
+ {
+ exit(2);
+ }
+
+ /* End the vararg stuff */
+ va_end(ap);
+}
+
+void mnc_error(char * string, ...)
+{
+ va_list ap;
+
+ /* Do the vararg stuff */
+ va_start(ap, string);
+
+ /* Output our name */
+ if (fprintf(stderr, "mnc: ") < 0)
+ {
+ exit(2);
+ }
+
+ /* Output our error */
+ if (vfprintf(stderr, string, ap) < 0)
+ {
+ exit(2);
+ }
+
+ /* End the vararg stuff */
+ va_end(ap);
+
+ /* Die! */
+ exit(1);
+}
diff --git a/network_cmds/mnc.tproj/mnc_main.c b/network_cmds/mnc.tproj/mnc_main.c
new file mode 100644
index 0000000..1e5c5af
--- /dev/null
+++ b/network_cmds/mnc.tproj/mnc_main.c
@@ -0,0 +1,131 @@
+/*
+ * $Id: mnc_main.c,v 1.12 2004/09/22 19:14:23 colmmacc Exp $
+ *
+ * mnc_main.c -- Multicast NetCat
+ *
+ * Colm MacCarthaigh, <colm@apache.org>
+ *
+ * Copyright (c) 2007, Colm MacCarthaigh.
+ * Copyright (c) 2004 - 2006, HEAnet Ltd.
+ *
+ * This software is an open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HEAnet Ltd. nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WINDOWS
+
+/* Non-windows includes */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#else
+
+/* Windows-specific includes */
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#endif /* WINDOWS */
+
+#include "mnc.h"
+
+int main(int argc, char **argv)
+{
+ /* Utility variables */
+ int sock,
+ len;
+ char buffer[1024];
+
+ /* Our main configuration */
+ struct mnc_configuration * config;
+
+#ifdef WINDOWS
+ WSADATA wsaData;
+
+ if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
+ {
+ mnc_error("This operating system is not supported\n");
+ }
+#endif
+
+ /* Parse the command line */
+ config = parse_arguments(argc, argv);
+
+ /* Create a socket */
+ if ((sock = socket(config->group->ai_family, config->group->ai_socktype,
+ config->group->ai_protocol)) < 0)
+ {
+ mnc_error("Could not create socket\n");
+ }
+
+ /* Are we supposed to listen? */
+ if (config->mode == LISTENER)
+ {
+ /* Set up the socket for listening */
+ if (multicast_setup_listen(sock, config->group, config->source,
+ config->iface) < 0)
+ {
+ mnc_error("Can not listen for multicast packets.\n");
+ }
+
+ /* Recieve the packets */
+ while ((len = recvfrom(sock, buffer, sizeof(buffer),
+ 0, NULL, NULL)) >= 0)
+ {
+ write(STDOUT_FILENO, buffer, len);
+ }
+ }
+ else /* Assume MODE == SENDER */
+ {
+ /* Set up the socket for sending */
+ if (multicast_setup_send(sock, config->group, config->source)
+ < 0)
+ {
+ mnc_error("Can not send multicast packets\n");
+ }
+
+ /* Send the packets */
+ while((len = read(STDIN_FILENO, buffer, sizeof(buffer))) > 0)
+ {
+ sendto(sock, buffer, len, 0, config->group->ai_addr,
+ config->group->ai_addrlen);
+ }
+ }
+
+ /* Close the socket */
+ close(sock);
+
+ return 0;
+}
diff --git a/network_cmds/mnc.tproj/mnc_multicast.c b/network_cmds/mnc.tproj/mnc_multicast.c
new file mode 100644
index 0000000..35f3415
--- /dev/null
+++ b/network_cmds/mnc.tproj/mnc_multicast.c
@@ -0,0 +1,404 @@
+/*
+ * $Id: mnc_multicast.c,v 1.8 2004/09/22 19:14:23 colmmacc Exp $
+ *
+ * mnc_multicast.c -- Multicast NetCat
+ *
+ * Colm MacCarthaigh, <colm@apache.org>
+ *
+ * copyright (c) 2007, Colm MacCarthaigh.
+ * Copyright (c) 2004 - 2006, HEAnet Ltd.
+ *
+ * This software is an open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HEAnet Ltd. nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WINDOWS
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <string.h>
+#include <netdb.h>
+#include <errno.h>
+
+#else
+
+#include <sys/types.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <stdlib.h>
+
+#endif
+
+#include "mnc.h"
+
+#ifndef MCAST_JOIN_GROUP
+
+#ifdef IP_ADD_SOURCE_MEMBERSHIP
+int mnc_join_ipv4_ssm(int socket, struct addrinfo * group,
+ struct addrinfo * source, char * iface)
+{
+ struct ip_mreq_source multicast_request;
+
+ if (iface != NULL)
+ {
+ /* See if interface is a literal IPv4 address */
+ if ((multicast_request.imr_interface.s_addr =
+ inet_addr(iface)) == INADDR_NONE)
+ {
+ mnc_warning("Invalid interface address\n");
+ return -1;
+ }
+ }
+ else
+ {
+ /* set the interface to the default */
+ multicast_request.imr_interface.s_addr = htonl(INADDR_ANY);
+ }
+
+ multicast_request.imr_multiaddr.s_addr =
+ ((struct sockaddr_in *)group->ai_addr)->sin_addr.s_addr;
+
+ multicast_request.imr_sourceaddr.s_addr =
+ ((struct sockaddr_in *)source->ai_addr)->sin_addr.s_addr;
+
+ /* Set the socket option */
+ if (setsockopt(socket, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
+ (char *) &multicast_request,
+ sizeof(multicast_request)) != 0)
+ {
+ mnc_warning("Could not join the multicast group: %s\n",
+ strerror(errno));
+
+ return -1;
+ }
+
+ return 0;
+}
+#else
+
+int mnc_join_ipv4_ssm(int socket, struct addrinfo * group,
+ struct addrinfo * source, char * iface)
+{
+ mnc_warning("Sorry, No support for IPv4 source-specific multicast in this build\n");
+
+ return -1;
+}
+#endif
+
+int mnc_join_ipv6_ssm(int socket, struct addrinfo * group,
+ struct addrinfo * source, char * iface)
+{
+ mnc_warning("Sorry, No support for IPv6 source-specific multicast in this build\n");
+
+ return -1;
+}
+#else /* if MCAST_JOIN_GROUP .. */
+
+#define mnc_join_ipv6_asm(a, b, c) mnc_join_ip_asm((a), (b), (c))
+#define mnc_join_ipv4_asm(a, b, c) mnc_join_ip_asm((a), (b), (c))
+
+int mnc_join_ip_asm(int socket, struct addrinfo * group, char * iface)
+{
+ struct group_req multicast_request;
+ int ip_proto;
+
+ if (group->ai_family == AF_INET6)
+ {
+ ip_proto = IPPROTO_IPV6;
+ }
+ else
+ {
+ ip_proto = IPPROTO_IP;
+ }
+
+ if (iface != NULL)
+ {
+ if ((multicast_request.gr_interface = if_nametoindex(iface))
+ == 0)
+ {
+ mnc_warning("Ignoring unknown interface: %s\n", iface);
+ }
+ }
+ else
+ {
+ multicast_request.gr_interface = 0;
+ }
+
+ memcpy(&multicast_request.gr_group, group->ai_addr, group->ai_addrlen);
+
+ /* Set the socket option */
+ if (setsockopt(socket, ip_proto, MCAST_JOIN_GROUP, (char *)
+ &multicast_request, sizeof(multicast_request)) != 0)
+ {
+ mnc_warning("Could not join the multicast group: %s\n",
+ strerror(errno));
+
+ return -1;
+ }
+
+ return 0;
+}
+
+#endif /* MCAST_JOIN_GROUP */
+
+#ifndef MCAST_JOIN_SOURCE_GROUP
+int mnc_join_ipv4_asm(int socket, struct addrinfo * group, char * iface)
+{
+ struct ip_mreq multicast_request;
+
+ if (iface != NULL)
+ {
+ /* See if interface is a literal IPv4 address */
+ if ((multicast_request.imr_interface.s_addr =
+ inet_addr(iface)) == INADDR_NONE)
+ {
+ mnc_warning("Invalid interface address\n");
+ return -1;
+ }
+ }
+ else
+ {
+ /* Set the interface to the default */
+ multicast_request.imr_interface.s_addr = htonl(INADDR_ANY);
+ }
+
+ multicast_request.imr_multiaddr.s_addr =
+ ((struct sockaddr_in *)group->ai_addr)->sin_addr.s_addr;
+
+ /* Set the socket option */
+ if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (char *) &multicast_request,
+ sizeof(multicast_request)) != 0)
+ {
+ mnc_warning("Could not join the multicast group: %s\n",
+ strerror(errno));
+
+ return -1;
+ }
+
+ return 0;
+}
+
+int mnc_join_ipv6_asm(int socket, struct addrinfo * group, char * iface)
+{
+ mnc_warning("Sorry, No support for IPv6 any-source multicast in this build\n");
+
+ return -1;
+}
+#else /* if MCAST_JOIN_SOURCE_GROUP ... */
+
+#define mnc_join_ipv4_ssm(a, b, c, d) mnc_join_ip_ssm((a), (b), (c), (d))
+#define mnc_join_ipv6_ssm(a, b, c, d) mnc_join_ip_ssm((a), (b), (c), (d))
+
+int mnc_join_ip_ssm(int socket, struct addrinfo * group,
+ struct addrinfo * source,
+ char * iface)
+{
+ struct group_source_req multicast_request;
+ int ip_proto;
+
+ if (group->ai_family == AF_INET6)
+ {
+ ip_proto = IPPROTO_IPV6;
+ }
+ else
+ {
+ ip_proto = IPPROTO_IP;
+ }
+
+ if (iface != NULL)
+ {
+ if ((multicast_request.gsr_interface = if_nametoindex(iface))
+ == 0)
+ {
+ mnc_warning("Ignoring unknown interface: %s\n", iface);
+ }
+ }
+ else
+ {
+ multicast_request.gsr_interface = 0;
+ }
+
+ memcpy(&multicast_request.gsr_group, group->ai_addr, group->ai_addrlen);
+ memcpy(&multicast_request.gsr_source, source->ai_addr,
+ source->ai_addrlen);
+
+ /* Set the socket option */
+ if (setsockopt(socket, ip_proto, MCAST_JOIN_SOURCE_GROUP,
+ (char *) &multicast_request,
+ sizeof(multicast_request)) != 0)
+ {
+ mnc_warning("Could not join the multicast group: %s\n",
+ strerror(errno));
+
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* MCAST_JOIN_SOURCE_GROUP */
+
+int multicast_setup_listen(int socket, struct addrinfo * group,
+ struct addrinfo * source, char * iface)
+{
+ size_t rcvbuf;
+
+#ifndef WINDOWS
+ /* bind to the group address before anything */
+ if (bind(socket, group->ai_addr, group->ai_addrlen) != 0)
+ {
+ mnc_warning("Could not bind to group-id\n");
+ return -1;
+ }
+#else
+ if (group->ai_family == AF_INET)
+ {
+ struct sockaddr_in sin;
+
+ sin.sin_family = group->ai_family;
+ sin.sin_port = group->ai_port;
+ sin.sin_addr = INADDR_ANY;
+
+ if (bind(socket, (struct sockaddr *) sin,
+ sizeof(sin)) != 0)
+ {
+ mnc_warning("Could not bind to ::\n");
+ return -1;
+ }
+ }
+ else if (group->ai_family == AF_INET6)
+ {
+ struct sockaddr_in6 sin6;
+
+ sin6.sin6_family = group->ai_family;
+ sin6.sin6_port = group->ai_port;
+ sin6.sin6_addr = in6addr_any;
+
+ if (bind(socket, (struct sockaddr *) sin6,
+ sizeof(sin6)) != 0)
+ {
+ mnc_warning("Could not bind to ::\n");
+ return -1;
+ }
+ }
+#endif
+
+ /* Set a receive buffer size of 64k */
+ rcvbuf = 1 << 15;
+ if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
+ sizeof(rcvbuf)) < 0) {
+ mnc_warning("Could not set receive buffer to 64k\n");
+ }
+
+ if (source != NULL)
+ {
+ if (group->ai_family == AF_INET6)
+ {
+ /* Use whatever IPv6 API is appropriate */
+ return
+ mnc_join_ipv6_ssm(socket, group, source, iface);
+ }
+ else if (group->ai_family == AF_INET)
+ {
+ /* Use the fully portable IPv4 API */
+ return
+ mnc_join_ipv4_ssm(socket, group, source, iface);
+ }
+ else
+ {
+ mnc_warning("Only IPv4 and IPv6 are supported\n");
+ return -1;
+ }
+ }
+ else
+ {
+ if (group->ai_family == AF_INET6)
+ {
+ /* Use the fully portable IPv4 API */
+ return
+ mnc_join_ipv6_asm(socket, group, iface);
+ }
+ else if (group->ai_family == AF_INET)
+ {
+ /* Use the fully portable IPv4 API */
+ return
+ mnc_join_ipv4_asm(socket, group, iface);
+ }
+ else
+ {
+ mnc_warning("Only IPv4 and IPv6 are supported\n");
+ return -1;
+ }
+ }
+
+ /* We should never get here */
+ return -1;
+}
+
+
+int multicast_setup_send(int socket, struct addrinfo * group,
+ struct addrinfo * source)
+{
+ int ttl = 255;
+
+ if (source != NULL)
+ {
+ /* bind to the address before anything */
+ if (bind(socket, source->ai_addr, source->ai_addrlen) != 0)
+ {
+ mnc_warning("Could not bind to source-address\n");
+ return -1;
+ }
+ }
+
+ if (group->ai_family == AF_INET)
+ {
+ if (setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)
+ &ttl, sizeof(ttl)) != 0)
+ {
+ mnc_warning("Could not increase the TTL\n");
+ return -1;
+ }
+ }
+ else if (group->ai_family == AF_INET6)
+ {
+ if (setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+ (char *) &ttl, sizeof(ttl)) != 0)
+ {
+ mnc_warning("Could not increase the hop-count\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/network_cmds/mnc.tproj/mnc_opts.c b/network_cmds/mnc.tproj/mnc_opts.c
new file mode 100644
index 0000000..606746f
--- /dev/null
+++ b/network_cmds/mnc.tproj/mnc_opts.c
@@ -0,0 +1,182 @@
+/*
+ * $Id: mnc_opts.c,v 1.3 2004/09/22 16:02:26 colmmacc Exp $
+ *
+ * mnc_opts.c -- Multicast NetCat
+ *
+ * Colm MacCarthaigh, <colm@apache.org>
+ *
+ * Copyright (c) 2007, Colm MacCarthaigh.
+ * Copyright (c) 2004 - 2006, HEAnet Ltd.
+ *
+ * This software is an open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HEAnet Ltd. nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifndef WINDOWS
+
+/* UNIX-y includes */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#else
+
+/* WINDOWS-y includes */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+
+#include "mnc.h"
+
+/* Display a usage statement */
+void usage(void)
+{
+ fprintf(stderr,
+ "Usage: mnc [-l] [-i interface] [-p port] group-id "
+ "[source-address]\n\n"
+ "-l : listen mode\n"
+ "-i : specify interface to listen\n"
+ "-p : specify port to listen/send on\n\n");
+ exit(1);
+}
+
+struct mnc_configuration * parse_arguments(int argc, char **argv)
+{
+ /* Utility variables */
+ int optind,
+ errorcode;
+ struct addrinfo hints;
+
+ /* Our persisting configuration */
+ static struct mnc_configuration config;
+
+ /* Set some defaults */
+ config.mode = SENDER;
+ config.port = MNC_DEFAULT_PORT;
+ config.iface = NULL;
+ config.source = NULL;
+
+ /* Loop through the arguments */
+ for (optind = 1; optind < (argc - 1); optind++)
+ {
+ if ( (argv[optind][0] == '-') || (argv[optind][0] == '/') )
+ {
+ switch(argv[optind][1])
+ {
+ /* Set listening mode */
+ case 'l': config.mode = LISTENER;
+ break;
+
+ /* Set port */
+ case 'p': config.port = argv[++optind];
+ break;
+
+ /* Set an interface */
+ case 'i': config.iface = argv[++optind];
+ break;
+
+ /* Unrecognised option */
+ default: usage();
+ break;
+ }
+ }
+ else
+ {
+ /* assume we've ran out of options */
+ break;
+ }
+ }
+
+ /* There's a chance we were passed one option */
+ if (optind >= argc || argv[optind][0] == '-')
+ {
+ usage();
+ }
+
+ /* Now make sure we have either exactly 1 or 2 more arguments */
+ if ( (argc - optind) != 1 && (argc - optind) != 2 )
+ {
+ /* We have not been given the right ammount of
+ arguments */
+ usage();
+ }
+
+ /* You can't have an interface without also listening */
+ if (config.mode == SENDER && config.iface != NULL)
+ {
+ mnc_error("You may only specify the interface when in"
+ " listening mode\n");
+ }
+
+ /* Set some hints for getaddrinfo */
+ memset(&hints, 0, sizeof(hints));
+
+ /* We want a UDP socket */
+ hints.ai_socktype = SOCK_DGRAM;
+
+ /* Don't do any name-lookups */
+ hints.ai_flags = AI_NUMERICHOST;
+
+ /* Get the group-id information */
+ if ( (errorcode =
+ getaddrinfo(argv[optind], config.port, &hints, &config.group)) != 0)
+ {
+ mnc_error("Error getting group-id address information: %s\n",
+ gai_strerror(errorcode));
+ }
+
+ /* Move on to next argument */
+ optind++;
+
+ /* Get the source information */
+ if ( (argc - optind) == 1)
+ {
+
+ if ( (errorcode =
+ getaddrinfo(argv[optind], config.port, &hints, &config.source))
+ != 0)
+ {
+ mnc_error("Error getting source-address information: %s\n",
+ gai_strerror(errorcode));
+ }
+
+ /* Confirm that the source and group are in the same Address Family */
+ if ( config.source->ai_family != config.group->ai_family )
+ {
+ mnc_error("Group ID and Source address are not of "
+ "the same type\n");
+ }
+ }
+
+ return &config;
+}