diff options
author | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
---|---|---|
committer | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
commit | 5fd83771641d15c418f747bd343ba6738d3875f7 (patch) | |
tree | 5abf0f78f680d9837dbd93d4d4c3933bb7509599 /network_cmds/mnc.tproj | |
download | apple_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/LICENCE | 37 | ||||
-rw-r--r-- | network_cmds/mnc.tproj/README | 63 | ||||
-rw-r--r-- | network_cmds/mnc.tproj/mnc.1 | 101 | ||||
-rw-r--r-- | network_cmds/mnc.tproj/mnc.h | 92 | ||||
-rw-r--r-- | network_cmds/mnc.tproj/mnc_error.c | 95 | ||||
-rw-r--r-- | network_cmds/mnc.tproj/mnc_main.c | 131 | ||||
-rw-r--r-- | network_cmds/mnc.tproj/mnc_multicast.c | 404 | ||||
-rw-r--r-- | network_cmds/mnc.tproj/mnc_opts.c | 182 |
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; +} |