Pre-ci test passed git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4000 818b1a75-f10b-46b9-bf7c-635c3b92a50f
638 lines
19 KiB
C
638 lines
19 KiB
C
/*******************************/
|
|
/* reflector-forwarding-v4m by */
|
|
/*******************************/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <strings.h>
|
|
#include <netdb.h>
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
#include <sys/unistd.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
#include <sys/signal.h>
|
|
#include <sys/param.h>
|
|
#include <errno.h>
|
|
#include <arpa/inet.h>
|
|
#include <pthread.h>
|
|
#include <syslog.h>
|
|
/* To get ifreq */
|
|
#include <arpa/inet.h>
|
|
#include <sys/socket.h>
|
|
#include <net/if.h>
|
|
#include <sys/ioctl.h>
|
|
#include <limits.h>
|
|
|
|
#include <netinet/in_systm.h>
|
|
#include <netinet/in.h>
|
|
#include <netinet/ip.h>
|
|
#include <netinet/udp.h>
|
|
|
|
#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
|
|
#define MSGBUF_SIZE 32768
|
|
#define IFNAMSIZE 11
|
|
#define INLINE inline __attribute__((always_inline))
|
|
struct ipaddr_str
|
|
{
|
|
char buf[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
|
|
};
|
|
int IP_VERSION;
|
|
static INLINE const char *ip4_to_string(struct ipaddr_str * const buf, const struct in_addr addr4) { return inet_ntop(AF_INET, &addr4, buf->buf, sizeof(buf->buf)); }
|
|
static INLINE const char *ip6_to_string(struct ipaddr_str * const buf, const struct in6_addr * const addr6) { return inet_ntop(AF_INET6, addr6, buf->buf, sizeof(buf->buf)); }
|
|
static INLINE const char *sockaddr4_to_string(struct ipaddr_str * const buf, const struct sockaddr * const addr) { const struct sockaddr_in * const addr4 = (const struct sockaddr_in *)addr; return ip4_to_string(buf, addr4->sin_addr); }
|
|
int programshutdown (void);
|
|
|
|
#define NUM_THREADS 200
|
|
struct thread_data{
|
|
int thread_id;
|
|
char interface1[11];
|
|
char multicast_addr1[41];
|
|
char interface2[11];
|
|
char multicast_addr2[41];
|
|
int ttl1;
|
|
int ttl2;
|
|
int port1;
|
|
int port2;
|
|
};
|
|
|
|
struct thread_data thread_data_array[NUM_THREADS];
|
|
/*******************************************************************
|
|
*From net-tools lib/interface.c
|
|
*
|
|
*******************************************************************/
|
|
int
|
|
get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
|
|
{
|
|
char addr6[40], devname[IFNAMSIZE];
|
|
char addr6p[8][5];
|
|
int plen, scope, dad_status, if_idx;
|
|
FILE *f;
|
|
struct sockaddr_in6 tmp_sockaddr6;
|
|
|
|
if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL)
|
|
{
|
|
while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
|
|
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
|
|
addr6p[4], addr6p[5], addr6p[6], addr6p[7],
|
|
&if_idx, &plen, &scope, &dad_status, devname) != EOF)
|
|
{
|
|
if (!strcmp(devname, ifname))
|
|
{
|
|
sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
|
|
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
|
|
addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
|
|
printf( "\t inet6 addr: %s\n", addr6);
|
|
printf("\t Scope: %d\n", scope);
|
|
if(scope == scope_in)
|
|
{
|
|
printf( "\tFound GLOBAL addr: %s:%s:%s:%s:%s:%s:%s:%s\n",
|
|
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
|
|
addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
|
|
inet_pton(AF_INET6,addr6,&tmp_sockaddr6);
|
|
memcpy(&saddr6->sin6_addr, &tmp_sockaddr6, sizeof(struct in6_addr));
|
|
fclose(f);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
fclose(f);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************/
|
|
/* Threaded routine */
|
|
/*****************************************************/
|
|
void *Reflector(void *threadarg)
|
|
{
|
|
int ioctl_s;
|
|
struct thread_data *my_data;
|
|
my_data = (struct thread_data *)threadarg;
|
|
struct in_addr multicastaddress_in; //IPv4 multicast address from command line
|
|
struct in_addr multicastaddress_out;
|
|
struct sockaddr_in6 tmp_saddr6;
|
|
struct ifreq ifr;
|
|
struct ipaddr_str buf;
|
|
int mcdataport4; //IPv4 multicast port 1
|
|
int mcdataport; //IPv4 multicast port 2
|
|
|
|
/*define variables*/
|
|
|
|
int mcdatarecvfd4; //multicast data receive socket side 1
|
|
int mcdatarecvfd; //multicast data receive socket side 2
|
|
|
|
|
|
int sendfd4; //local send socket IPv4 side 1
|
|
int sendfd; //local send socket IPv4 side 2
|
|
|
|
int ttl1; //time to live IPv4 side 1
|
|
int ttl2; //time to live IPv4 side 2
|
|
struct sockaddr_in mcdataaddr4; //reception IPv4 sockaddr
|
|
struct sockaddr_in mcdataaddr; //reception IPv44 sockaddr
|
|
|
|
|
|
char myhostnameipaddress4[20]; // IPv4 reflector's address string
|
|
char myhostnameipaddress[20]; // IPv44 reflector's address string
|
|
char addressstring4[20]; // IPv4 address string
|
|
char addressstring[20]; // IPv44 address string
|
|
|
|
struct sockaddr_in localsendaddr4; //IPv4 address of outgoing packets interface 1
|
|
struct sockaddr_in localsendaddr; //IPv4 address of outgoing packets interface 2
|
|
|
|
struct sockaddr_in sourceaddr4; //IPv4 address of incoming packets interface 1
|
|
struct sockaddr_in sourceaddr; //IPv4 address of incoming packets interface 2
|
|
|
|
struct ip_mreq mcdatareq4; //IPv4 join group structure
|
|
struct ip_mreq mcdatareq; //IPv44 join group structure
|
|
|
|
|
|
int mcdataaddrlen; //IPv4 multicast address length
|
|
unsigned int sourceaddrlen; //IPv4 source address length
|
|
|
|
char mcdatarecvbuf4[MSGBUF_SIZE]; //IPv4 multicast receive buffer
|
|
char mcdatarecvbuf[MSGBUF_SIZE]; //IPv44 multicast receive buffer
|
|
|
|
|
|
|
|
fd_set readfds; // file descriptors set
|
|
int maxfds; // max number of file descriptors
|
|
int nfds;
|
|
int nr; // number of bytes read with recvfrom
|
|
int ns; // number of bytes sent with sendto
|
|
int chksrc; // asserts if source address is not the reflector's one
|
|
int debugon=1;
|
|
int n2;
|
|
char inputbuf[32];
|
|
|
|
/* IPv4 multicast address */
|
|
if((inet_pton(AF_INET,my_data->multicast_addr1,&multicastaddress_in.s_addr))!=1){
|
|
printf("bad multicast IPv4 address format\n");
|
|
exit (1);
|
|
}
|
|
//printf("multicastaddress side 1 v4 =%s\n",my_data->multicast_addr1);
|
|
/* IPv4 multicast address */
|
|
if((inet_pton(AF_INET,my_data->multicast_addr2,&multicastaddress_out.s_addr))!=1){
|
|
printf("bad multicast IPv4 address format\n");
|
|
exit (1);
|
|
}
|
|
//printf("multicastaddress side 2 v4 =%s\n",my_data->multicast_addr2);
|
|
|
|
|
|
/* IPv4 multicast ports */
|
|
|
|
mcdataport4 = my_data->port1;
|
|
mcdataport = my_data->port2;
|
|
|
|
|
|
/* Time to live for IPv4 multicast */
|
|
ttl1 = my_data->ttl1;
|
|
|
|
/* Time to live for IPv4 multicast */
|
|
ttl2 = my_data->ttl2;
|
|
|
|
IP_VERSION=4;
|
|
if (IP_VERSION==4 )//
|
|
{
|
|
ioctl_s = socket(AF_INET, SOCK_DGRAM, 0);
|
|
if (ioctl_s < 0)
|
|
{
|
|
syslog(LOG_ERR, "ioctl socket: %m");
|
|
exit (0);
|
|
}
|
|
/* INTERFACE 1 */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_name, my_data->interface1, IFNAMSIZE);
|
|
/* Check interface address (IPv4) */
|
|
if(ioctl(ioctl_s, SIOCGIFADDR, &ifr) < 0)
|
|
{
|
|
printf( "\tCould not get address of interface 1 - removing it\n");
|
|
exit(0);
|
|
}
|
|
sockaddr4_to_string(&myhostnameipaddress4, &ifr.ifr_addr);
|
|
|
|
/* INTERFACE 2 */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_name, my_data->interface2, IFNAMSIZE);
|
|
/* Check interface address (IPv4) */
|
|
if(ioctl(ioctl_s, SIOCGIFADDR, &ifr) < 0)
|
|
{
|
|
printf( "\tCould not get address of interface 2 - removing it\n");
|
|
exit(0);
|
|
}
|
|
|
|
sockaddr4_to_string(&myhostnameipaddress, &ifr.ifr_addr);
|
|
}
|
|
else
|
|
{
|
|
/* Global address mode */
|
|
int ipv6_addrtype = 0; /* global */
|
|
/* Get IPV6 GLOBAL interface address */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_name, my_data->interface2, IFNAMSIZE);
|
|
if(get_ipv6_address(ifr.ifr_name, &tmp_saddr6, ipv6_addrtype ) <= 0)
|
|
{
|
|
printf( "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
|
|
}
|
|
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_name, my_data->interface2, IFNAMSIZE);
|
|
// printf("\n Adding interface : %s \n", my_data->interface2);
|
|
/* Get IPV6 GLOBAL interface address */
|
|
if(get_ipv6_address(ifr.ifr_name, &tmp_saddr6, ipv6_addrtype ) <= 0)
|
|
{
|
|
printf( "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
|
|
}
|
|
}
|
|
/* Structures initialization */
|
|
|
|
/*enter the address/port data into the mcdataaddr structure for IPv4*/
|
|
bzero((char *) &mcdataaddr4, sizeof(mcdataaddr4));
|
|
mcdataaddr4.sin_family=AF_INET;
|
|
mcdataaddr4.sin_addr.s_addr = multicastaddress_in.s_addr;
|
|
mcdataaddr4.sin_port = htons(mcdataport4);
|
|
|
|
/*enter the address/port data into the mcdataaddr structure for IPv4*/
|
|
bzero((char *) &mcdataaddr, sizeof(mcdataaddr));
|
|
mcdataaddr.sin_family=AF_INET;
|
|
mcdataaddr.sin_addr.s_addr = multicastaddress_out.s_addr;
|
|
mcdataaddr.sin_port = htons(mcdataport);
|
|
|
|
|
|
/*enter the address/port data into the localsendaddr structure for IPv4*/
|
|
bzero((char *) &localsendaddr4, sizeof(localsendaddr4));
|
|
localsendaddr4.sin_family=AF_INET;
|
|
inet_pton(AF_INET, myhostnameipaddress4 , &localsendaddr4.sin_addr.s_addr);
|
|
localsendaddr4.sin_port = htons(0);
|
|
//LL
|
|
// inet_ntop(AF_INET, &localsendaddr4.sin_addr.s_addr,addressstring ,sizeof(addressstring));
|
|
// printf("threaded function local sender addr side 1=%s \t",addressstring);
|
|
|
|
/*enter the address/port data into the localsendaddr structure for IPv4*/
|
|
bzero((char *) &localsendaddr, sizeof(localsendaddr));
|
|
localsendaddr.sin_family=AF_INET;
|
|
inet_pton(AF_INET, myhostnameipaddress , &localsendaddr.sin_addr.s_addr);
|
|
localsendaddr.sin_port = htons(0);
|
|
//LL
|
|
// inet_ntop(AF_INET, &localsendaddr.sin_addr.s_addr,addressstring ,sizeof(addressstring));
|
|
// printf("threaded function local sender addr side 2=%s\n", addressstring);
|
|
|
|
/*enter the address/port data into the mcdatareq structure for IPv4*/
|
|
bzero((char *) &mcdatareq4, sizeof(mcdatareq4));
|
|
// mcdatareq4.imr_interface.s_addr=htonl(INADDR_ANY); < force to add a multicast route
|
|
inet_pton(AF_INET, myhostnameipaddress4 ,&mcdatareq4.imr_interface.s_addr );
|
|
mcdatareq4.imr_multiaddr.s_addr=multicastaddress_in.s_addr;
|
|
// inet_pton(AF_INET, myhostnameipaddress4 , &mcdatareq4.imr_interface.s_addr);
|
|
|
|
|
|
|
|
/*enter the address/port data into the mcdatareq structure for IPv4*/
|
|
bzero((char *) &mcdatareq, sizeof(mcdatareq));
|
|
inet_pton(AF_INET, myhostnameipaddress ,&mcdatareq.imr_interface.s_addr );
|
|
// mcdatareq.imr_interface.s_addr=htonl(INADDR_ANY);
|
|
mcdatareq.imr_multiaddr.s_addr=multicastaddress_out.s_addr;
|
|
|
|
/*get the sendfd socket linked to the first address of the current host */
|
|
if ((sendfd4 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
|
perror("can't open sendfd socket!");
|
|
exit (1);
|
|
}
|
|
|
|
if (bind(sendfd4, (struct sockaddr *) &localsendaddr4, \
|
|
sizeof(localsendaddr4)) < 0) {
|
|
|
|
perror("can't bind localsendaddr v4 to socket!");
|
|
exit(1);
|
|
}
|
|
/*get the sendfd socket linked to the first address of the current host*/
|
|
if ((sendfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
|
perror("can't open sendfd socket!");
|
|
exit (1);
|
|
}
|
|
|
|
if (bind(sendfd, (struct sockaddr *) &localsendaddr, \
|
|
sizeof(localsendaddr)) < 0) {
|
|
perror("can't bind localsendaddr v4 side 2 to socket!");
|
|
exit(1);
|
|
}
|
|
|
|
if ((mcdatarecvfd4 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
|
perror("can't open mcdatarecvfd4 socket!");
|
|
exit(1);
|
|
}
|
|
|
|
/*allow multiple processes per host to read from IPv4 sockets side 2*/
|
|
if (setsockopt(mcdatarecvfd4, SOL_SOCKET, SO_REUSEADDR, &mcdataaddr4, sizeof(mcdataaddr4)) < 0) {
|
|
perror("SO_REUSEADDR setsockopt v4\n");
|
|
}
|
|
|
|
if (bind(mcdatarecvfd4, (struct sockaddr *) &mcdataaddr4, \
|
|
sizeof(mcdataaddr4)) < 0) {
|
|
inet_ntop(AF_INET, &mcdataaddr4.sin_addr.s_addr,addressstring ,sizeof(addressstring));
|
|
printf("with address of bind %s\n", addressstring);
|
|
perror("can't bind mcdataaddr v4 to socket!");
|
|
exit(1);
|
|
}
|
|
|
|
|
|
if (multicastaddress_out.s_addr!=multicastaddress_in.s_addr)
|
|
{
|
|
//multicast data receive socket side 2
|
|
/*get a mcdatarecvfd socket, bind to address for IPv4*/
|
|
if ((mcdatarecvfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
|
perror("can't open mcdatarecvfd4 socket!");
|
|
exit(1);
|
|
}
|
|
/*allow multiple processes per host to read from IPv4 sockets side 2*/
|
|
if (setsockopt(mcdatarecvfd, SOL_SOCKET, SO_REUSEADDR, &mcdataaddr, sizeof(mcdataaddr)) < 0) {
|
|
perror("SO_REUSEADDR setsockopt v4\n");
|
|
}
|
|
|
|
if (bind(mcdatarecvfd, (struct sockaddr *) &mcdataaddr, \
|
|
sizeof(mcdataaddr)) < 0) {
|
|
perror("can't bind mcdataaddr v4 side 2 to socket!");
|
|
exit(1);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
mcdatarecvfd= mcdatarecvfd4;
|
|
}
|
|
|
|
/*set socket options to join multicast group in IPv4*/
|
|
if (setsockopt(mcdatarecvfd4, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcdatareq4,\
|
|
sizeof(mcdatareq4)) < 0) {
|
|
perror("can't set socket options to join multicast group data v4 side 1!");
|
|
exit(1);
|
|
}
|
|
|
|
|
|
/*set socket options to join multicast group in IPv4*/
|
|
if (setsockopt(mcdatarecvfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcdatareq,\
|
|
sizeof(mcdatareq)) < 0) {
|
|
perror("can't set socket options to join multicast group data v4 side 2!");
|
|
exit(1);
|
|
}
|
|
|
|
/*now set multicast socket TTL option for IPv4*/
|
|
if (setsockopt(sendfd4, IPPROTO_IP, IP_MULTICAST_TTL, \
|
|
&ttl1, sizeof(ttl1)) < 0)
|
|
perror("can't set multicast ttl v4 socket option!");
|
|
|
|
/*now set multicast socket TTL option for IPv4*/
|
|
if (setsockopt(sendfd, IPPROTO_IP, IP_MULTICAST_TTL, \
|
|
&ttl2, sizeof(ttl2)) < 0)
|
|
perror("can't set multicast ttl v4 socket option!");
|
|
|
|
|
|
/*define the sizes of the address structures*/
|
|
mcdataaddrlen=sizeof(mcdataaddr4);
|
|
sourceaddrlen=sizeof(sourceaddr4);
|
|
|
|
/*start infinite while loop*/
|
|
/*and check for activity on sockets*/
|
|
|
|
/*set up the select sytem call parameters*/
|
|
/*zero out the readfds and writefds lists, then add*/
|
|
/*the file descriptors of interest*/
|
|
while(1) {
|
|
|
|
FD_ZERO(&readfds);
|
|
FD_SET(mcdatarecvfd4, &readfds);
|
|
FD_SET(mcdatarecvfd, &readfds);
|
|
|
|
if (debugon >= 1) {
|
|
FD_SET(0, &readfds);
|
|
}
|
|
|
|
maxfds = mcdatarecvfd4 + 5;
|
|
/*check for activity*/
|
|
nfds = select(maxfds, &readfds, NULL, NULL, NULL);
|
|
|
|
/*if specified on the command line, check for input on stdin*/
|
|
if (debugon >= 1) {
|
|
if (FD_ISSET(0, &readfds)) {
|
|
n2 = read(0,inputbuf, sizeof(inputbuf));
|
|
inputbuf[n2>0? n2-1: 0] = '\0';
|
|
if (!strcmp(inputbuf,"q")) {
|
|
programshutdown();
|
|
}
|
|
}
|
|
fflush(stdout);
|
|
}
|
|
|
|
|
|
/*1:receive from IPv4, send on IPv44 - data*/
|
|
if (FD_ISSET(mcdatarecvfd4, &readfds)) {
|
|
nr = recvfrom(mcdatarecvfd4, mcdatarecvbuf4, MSGBUF_SIZE, 0, (struct sockaddr *) \
|
|
&sourceaddr4, &sourceaddrlen);
|
|
if (debugon >= 2){
|
|
inet_ntop(AF_INET, &sourceaddr4.sin_addr.s_addr, addressstring4 , sizeof(addressstring4));
|
|
printf("\nreading from mcdatarecvfd4, got data from %s\n", addressstring4);
|
|
}
|
|
|
|
if (sourceaddr4.sin_addr.s_addr == localsendaddr4.sin_addr.s_addr){
|
|
chksrc = 0;
|
|
if (debugon >= 2)
|
|
printf("don't retransmit multicastv4 sourced from gateway machine\n");
|
|
} else {
|
|
chksrc = 1;
|
|
if (debugon >= 2)
|
|
printf("retransmit to multicast address\n");
|
|
}
|
|
|
|
if (chksrc) {
|
|
if (nr < 0)
|
|
printf ("mcdatarecvfd4:recvfrom over multicast v4 address error!(1)\n");
|
|
|
|
/*now send to IPv4*/
|
|
if (multicastaddress_out.s_addr != INADDR_ANY) {
|
|
if (debugon >= 2) {
|
|
inet_ntop(AF_INET, &mcdataaddr.sin_addr.s_addr,addressstring4 ,sizeof(addressstring4));
|
|
printf("sending to %s\n", addressstring4);
|
|
}
|
|
|
|
ns = sendto(sendfd, mcdatarecvbuf4, nr, 0, (struct sockaddr *)&mcdataaddr, \
|
|
sizeof(mcdataaddr));
|
|
} else {
|
|
if (debugon >= 2) printf("not resending to ORIGINATOR! or array entry = 0\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*2:receive from IPv4 side 2, send on IPv44 side 1 - data*/
|
|
if (FD_ISSET(mcdatarecvfd, &readfds)) {
|
|
nr = recvfrom(mcdatarecvfd, mcdatarecvbuf, MSGBUF_SIZE, 0, (struct sockaddr *) \
|
|
&sourceaddr, &sourceaddrlen);
|
|
if (debugon >= 2){
|
|
inet_ntop(AF_INET, &sourceaddr.sin_addr.s_addr, addressstring , sizeof(addressstring));
|
|
printf("\nreading from mcdatarecvfd side 2, got data from %s\n", addressstring);
|
|
}
|
|
|
|
if (sourceaddr.sin_addr.s_addr == localsendaddr.sin_addr.s_addr){
|
|
chksrc = 0;
|
|
if (debugon >= 2)
|
|
printf("don't retransmit multicastv4 sourced from gateway machine\n");
|
|
} else {
|
|
chksrc = 1;
|
|
if (debugon >= 2)
|
|
printf("retransmit to multicast address side 1\n");
|
|
}
|
|
|
|
if (chksrc) {
|
|
if (nr < 0)
|
|
printf ("mcdatarecvfd:recvfrom over multicast v4 address error!(1)\n");
|
|
|
|
/*now send to IPv4*/
|
|
if (multicastaddress_in.s_addr != INADDR_ANY) {
|
|
if (debugon >= 2) {
|
|
inet_ntop(AF_INET, &mcdataaddr4.sin_addr.s_addr,addressstring ,sizeof(addressstring));
|
|
printf("sending to %s\n", addressstring);
|
|
}
|
|
ns = sendto(sendfd4, mcdatarecvbuf, nr, 0, (struct sockaddr *)&mcdataaddr4, \
|
|
sizeof(mcdataaddr4));
|
|
} else {
|
|
if (debugon >= 2) printf("not resending to ORIGINATOR! or array entry = 0\n");
|
|
}
|
|
}
|
|
}
|
|
} //end of while loop
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************/
|
|
int
|
|
main (argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
char interface1[11], interface2[11];
|
|
int ttl1; //time to live side1
|
|
int ttl2; //time to live side 2
|
|
struct couple
|
|
{
|
|
char multicast_addr1[41]; /* address multicast for the group side 1 */
|
|
char multicast_addr2[41]; /* address multicast for the group side 2 */
|
|
};
|
|
int nb_port_range;
|
|
int nb_multicast_couple;
|
|
int ip_version, ip_version2;
|
|
int displayon=0;
|
|
struct couple *multi_group;
|
|
|
|
int i,j, k, rc,port;
|
|
pthread_t threads[NUM_THREADS];
|
|
struct port_range
|
|
{
|
|
int port_begin;
|
|
int port_end;
|
|
};
|
|
struct port_range *prt_range;
|
|
if (argc < 12) {
|
|
fprintf (stderr, "Error in the syntax\n");
|
|
exit(1);
|
|
}
|
|
|
|
strcpy(interface1,argv[1]);
|
|
strcpy(interface2,argv[2]);
|
|
ip_version= atoi(argv[3]);
|
|
ip_version2=atoi(argv[4]);
|
|
/* Time to live for IPv4 multicast */
|
|
ttl1 = atoi(argv[5]);
|
|
|
|
|
|
/* Time to live for IPv4 multicast */
|
|
ttl2 = atoi(argv[6]);
|
|
nb_multicast_couple=atoi(argv[7]);
|
|
|
|
if (nb_multicast_couple !=0)
|
|
{
|
|
if ((multi_group=(struct couple *)malloc(nb_multicast_couple*sizeof(struct couple)))==NULL)
|
|
{
|
|
printf("Memory problem to allocate struct couple !\n") ;
|
|
exit (1);
|
|
}
|
|
for (i=0; i <nb_multicast_couple; i++)
|
|
{
|
|
|
|
strcpy(multi_group[i].multicast_addr1,argv[8+2*i]);
|
|
strcpy(multi_group[i].multicast_addr2,argv[8+2*i +1]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
exit(0);
|
|
}
|
|
|
|
nb_port_range=atoi(argv[8 + nb_multicast_couple*2]);
|
|
if (nb_port_range !=0)
|
|
{
|
|
|
|
|
|
if ((prt_range=(struct port_range *)malloc(nb_port_range*sizeof(struct port_range)))==NULL)
|
|
{
|
|
printf("Memory problem to allocate struct port !\n") ;
|
|
exit (1);
|
|
}
|
|
for (i=0; i <nb_port_range; i++)
|
|
{
|
|
|
|
prt_range[i].port_begin= atoi(argv[8+1 + nb_multicast_couple*2+2*i]);
|
|
prt_range[i].port_end = atoi(argv[8+1 + nb_multicast_couple*2+2*i +1]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
exit(0);
|
|
}
|
|
k=0;
|
|
printf( "Multicast state : for interface %s and interface %s for %d multicast group(s) on %d port range(s) \n", interface1, interface2, nb_multicast_couple, nb_port_range);
|
|
for (i=0; i <nb_multicast_couple; i++)
|
|
{
|
|
|
|
for(j=0; j <nb_port_range; j++)
|
|
{
|
|
|
|
for (port= prt_range[j].port_begin; port <=prt_range[j].port_end; port++)
|
|
{
|
|
strcpy (thread_data_array[k].interface1, interface1);
|
|
strcpy (thread_data_array[k].interface2, interface2);
|
|
thread_data_array[k].ttl1=ttl1;
|
|
thread_data_array[k].ttl2=ttl2;
|
|
strcpy (thread_data_array[k].multicast_addr1, multi_group[i].multicast_addr1);
|
|
strcpy (thread_data_array[k].multicast_addr2, multi_group[i].multicast_addr2);
|
|
thread_data_array[k].thread_id=k;
|
|
thread_data_array[k].port1=port;
|
|
thread_data_array[k].port2=port;
|
|
|
|
if (displayon >= 1) printf("Creating thread %d for group %d for port %d\n", k,i ,port);
|
|
rc=pthread_create(&threads[k], NULL, Reflector, (void *)&thread_data_array[k]);
|
|
if (rc)
|
|
{
|
|
printf("Error; return code from pthreade_create() is %d\n", rc);
|
|
exit(-1);
|
|
}
|
|
k=k+1;
|
|
if (k> NUM_THREADS)
|
|
{
|
|
printf("Number of created threads over the fixed limited!" );
|
|
exit(-1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pthread_exit(NULL);
|
|
}
|
|
|
|
int programshutdown () {
|
|
exit (1);
|
|
}
|
|
|