1/* 2 PIM for Quagga 3 Copyright (C) 2008 Everton da Silva Marques 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; see the file COPYING; if not, write to the 17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 18 MA 02110-1301 USA 19 20 $QuaggaId: $Format:%an, %ai, %h$ $ 21*/ 22 23#include <stdlib.h> 24#include <stdio.h> 25#include <errno.h> 26#include <string.h> 27#include <unistd.h> 28#include <sys/types.h> 29#include <sys/socket.h> 30#include <net/if.h> 31#include <arpa/inet.h> 32 33#include "pim_igmp_join.h" 34 35const char *prog_name = 0; 36 37static int iface_solve_index(const char *ifname) 38{ 39 struct if_nameindex *ini; 40 int ifindex = -1; 41 int i; 42 43 if (!ifname) 44 return -1; 45 46 ini = if_nameindex(); 47 if (!ini) { 48 int err = errno; 49 fprintf(stderr, 50 "%s: interface=%s: failure solving index: errno=%d: %s\n", 51 prog_name, ifname, err, strerror(err)); 52 errno = err; 53 return -1; 54 } 55 56 for (i = 0; ini[i].if_index; ++i) { 57#if 0 58 fprintf(stderr, 59 "%s: interface=%s matching against local ifname=%s ifindex=%d\n", 60 prog_name, ifname, ini[i].if_name, ini[i].if_index); 61#endif 62 if (!strcmp(ini[i].if_name, ifname)) { 63 ifindex = ini[i].if_index; 64 break; 65 } 66 } 67 68 if_freenameindex(ini); 69 70 return ifindex; 71} 72 73int main(int argc, const char *argv[]) 74{ 75 struct in_addr group_addr; 76 struct in_addr source_addr; 77 const char *ifname; 78 const char *group; 79 const char *source; 80 int ifindex; 81 int result; 82 int fd; 83 84 prog_name = argv[0]; 85 86 fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 87 if (fd < 0) { 88 fprintf(stderr, 89 "%s: could not create socket: socket(): errno=%d: %s\n", 90 prog_name, errno, strerror(errno)); 91 exit(1); 92 } 93 94 if (argc != 4) { 95 fprintf(stderr, 96 "usage: %s interface group source\n" 97 "example: %s eth0 232.1.1.1 1.1.1.1\n", 98 prog_name, prog_name); 99 exit(1); 100 } 101 102 ifname = argv[1]; 103 group = argv[2]; 104 source = argv[3]; 105 106 ifindex = iface_solve_index(ifname); 107 if (ifindex < 0) { 108 fprintf(stderr, "%s: could not find interface: %s\n", 109 prog_name, ifname); 110 exit(1); 111 } 112 113 result = inet_pton(AF_INET, group, &group_addr); 114 if (result <= 0) { 115 fprintf(stderr, "%s: bad group address: %s\n", 116 prog_name, group); 117 exit(1); 118 } 119 120 result = inet_pton(AF_INET, source, &source_addr); 121 if (result <= 0) { 122 fprintf(stderr, "%s: bad source address: %s\n", 123 prog_name, source); 124 exit(1); 125 } 126 127 result = pim_igmp_join_source(fd, ifindex, group_addr, source_addr); 128 if (result) { 129 fprintf(stderr, 130 "%s: setsockopt(fd=%d) failure for IGMP group %s source %s ifindex %d on interface %s: errno=%d: %s\n", 131 prog_name, fd, group, source, ifindex, ifname, 132 errno, strerror(errno)); 133 exit(1); 134 } 135 136 printf("%s: joined channel (S,G)=(%s,%s) on interface %s\n", 137 prog_name, source, group, ifname); 138 139 printf("%s: waiting...\n", prog_name); 140 141 getchar(); 142 143 close(fd); 144 145 printf("%s: left channel (S,G)=(%s,%s) on interface %s\n", 146 prog_name, source, group, ifname); 147 148 exit(0); 149} 150