Differences between current version and revision by previous author of SSM.
Other diffs: Previous Major Revision, Previous Revision, or view the Annotated Edit History
Newer page: | version 3 | Last edited on Thursday, February 24, 2005 6:18:57 am | by AristotlePagaltzis | |
Older page: | version 2 | Last edited on Friday, February 18, 2005 8:57:23 am | by JohnMcPherson | Revert |
@@ -1,155 +1 @@
-[Acronym] for __S__ource __S__pecific __M__ulticast
.
-
-This is a relatively new form of multicast where only one person the group can transmit. Since the source address of the transmission is known in advance, a lot of the overhead with multicast (RP's etc) is no longer necessary. To run a network with SSM, all you need to enable is PIM-SM.
-
-Anyway, here are some very trivial examples uncluttered by anything like error handling (grin!). Many Distributions don't have the required header files yet, so included in #ifndef's is the required information. This certainly works under Linux 2.6, but it's possible this is not supported in Linux 2.4. This works on AMD64 gentoo and 32bit debian.
-
-The examples join the SSM group (ip-of-sender,232.1.1.1). In a real application you should randomly selected the 232.../8 address to avoid conflicts.
-
-Sender:
-<verbatim>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-
-/* Not everyone has the headers for this so improvise */
-#ifndef MCAST_JOIN_SOURCE_GROUP
-#define MCAST_JOIN_SOURCE_GROUP 46
-
-struct group_source_req
-{
- /* Interface index. */
- uint32_t gsr_interface;
-
- /* Group address. */
- struct sockaddr_storage gsr_group;
-
- /* Source address. */
- struct sockaddr_storage gsr_source;
-};
-#endif
-
-int main(int argc, char *argv[])
-{
- struct group_source_req group_source_req;
- struct sockaddr_in *group;
- struct sockaddr_in *source;
- int fd = socket(AF_INET,SOCK_DGRAM,getprotobyname("udp")->p_proto);
- socklen_t socklen = sizeof(struct sockaddr_storage);
- struct sockaddr_in bindaddr;
- u_char loop = 1;
-
- /* First bind to the port */
- bindaddr.sin_family = AF_INET;
- bindaddr.sin_port = htons(9990);
- bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-
- bind(fd,(struct sockaddr*)&bindaddr,sizeof(bindaddr));
- /* Now set up the SSM request */
- group_source_req.gsr_interface = ; /* "any" interface */
- group=(struct sockaddr_in*)&group_source_req.gsr_group;
- source=(struct sockaddr_in*)&group_source_req.gsr_source;
-
- group->sin_family = AF_INET;
- inet_aton("232.1.1.1",&group->sin_addr);
- group->sin_port = ; /* Ignored */
-
- /* Set the source to the name of the socket we created above */
- getsockname(fd,(struct sockaddr *)source, &socklen);
-
- setsockopt(fd,SOL_IP,MCAST_JOIN_SOURCE_GROUP, &group_source_req,
- sizeof(group_source_req));
-
- /* Enable reception of our own multicast */
- loop = 1;
- setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
- /* Set the TTL on packets to 250 */
- loop=250;
- setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &loop, sizeof(loop));
- /* Now we care about the port we send to */
- group->sin_port = htons(9991);
-
- /* Now send packets */
- while(1) {
- sendto(fd,"Hello World",strlen("Hello World"),,
- (struct sockaddr*)group,sizeof(struct sockaddr_in));
- sleep(1);
- }
- return ;
-}
-</verbatim>
-
-And a reciever follows. Use it ./ssm-rec ip.address.of.sender
-
-<verbatim>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <unistd.h>
-
-/* Not everyone has the headers for this, so improvise */
-#ifndef MCAST_JOIN_SOURCE_GROUP
-#define MCAST_JOIN_SOURCE_GROUP 46
-
-struct group_source_req
-{
- /* Interface index. */
- uint32_t gsr_interface;
-
- /* Group address. */
- struct sockaddr_storage gsr_group;
-
- /* Source address. */
- struct sockaddr_storage gsr_source;
-};
-#endif
-
-int main(int argc, char *argv[])
-{
- struct group_source_req group_source_req;
- struct sockaddr_in *group;
- struct sockaddr_in *source;
- int fd = socket(AF_INET,SOCK_DGRAM,getprotobyname("udp")->p_proto);
- struct sockaddr_in bindaddr;
-
- /* Setup the socket to listen on */
- bindaddr.sin_family = AF_INET;
- bindaddr.sin_port = htons(9991);
- bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- bind(fd,(struct sockaddr*)&bindaddr,sizeof(bindaddr));
-
- /* Set up the connection to the group */
- group_source_req.gsr_interface = ;
- group=(struct sockaddr_in*)&group_source_req.gsr_group;
- source=(struct sockaddr_in*)&group_source_req.gsr_source;
- /* Group is 232.1.1.1 */
- group->sin_family = AF_INET;
- inet_aton("232.1.1.1",&group->sin_addr);
- group->sin_port = ;
-
- /* Source is 10.1.20.9 */
- source->sin_family = AF_INET;
- inet_aton(argv[1],&source->sin_addr);
- source->sin_port = ;
-
- setsockopt(fd,SOL_IP,MCAST_JOIN_SOURCE_GROUP, &group_source_req,
- sizeof(group_source_req));
-
- while(1) {
- char buffer[65536];
- int ret=recv(fd,(char*)buffer,sizeof(buffer),);
- write(1,buffer,ret);
- }
- return ;
-}
-</verbatim>
-
-I had one major problem while trying to debug this. My mistake was that the reciever wasn't binding to INADDR_ANY for the listening socket, but instead to an IP address on the machine causing all the multicast packets to be ignored. Ooops.
-----
-CategoryProgramming CategoryNetworking
+[Acronym] for SourceSpecificMulticast
.