forw_requests.c 4.4 KB
Newer Older
Kristin Wright's avatar
Kristin Wright committed
1 2
/* 
 * Copyright (c) 2000 The University of Utah and the Flux Group.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 
 * {{{EMULAB-LICENSE
 * 
 * This file is part of the Emulab network testbed software.
 * 
 * This file is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 * 
 * This file is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this file.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * }}}
Kristin Wright's avatar
Kristin Wright committed
22 23 24 25 26 27 28 29
 *
 * ---------------------------
 *
 * Filename: forw_requests.c
 *   -- Author: Kristin Wright <kwright@cs.utah.edu> 
 *
 * ---------------------------
 *
Mike Hibler's avatar
Mike Hibler committed
30
 * $Id: forw_requests.c,v 1.12 2004-06-17 18:17:01 mike Exp $
Kristin Wright's avatar
Kristin Wright committed
31 32
 */

33 34
#include <math.h>

Kristin Wright's avatar
Kristin Wright committed
35 36 37 38 39 40 41 42
#include "discvr.h"
#include "packet.h"
#include "util.h"

/*
 * Send a request on to each interface 
 */
char recvbuf[BUFSIZ];
43
extern u_char myNodeID[ETHADDRSIZ];
44 45
extern u_char parent_nodeIF[ETHADDRSIZ];

46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
static double start = 0.0;

double
tod(void)
{
        double s;
	struct timeval tv;

	gettimeofday(&tv, 0);
	s = tv.tv_sec;
	s += (1e-6 * tv.tv_usec);
	return (s - start);
}


61 62 63 64 65 66 67 68 69 70 71 72
struct ifi_info *
get_ifi_struct(int sock, struct ifi_info * ifihead)
{
	struct ifi_info * ifi=NULL;

	for (ifi = ifihead; ifi != NULL; ifi = ifi->ifi_next) 
	{
		if(ifi->sock == sock) return ifi;	
	}
	return NULL;
}

73
/*
74 75 76 77 78 79 80 81
void
addMyID(char* mesg, int size)
{
	struct topd_nbor *p;
	p = (struct topd_nbor *) (mesg + sizeof(topd_inqid_t));

	memcpy(p->tdnbor_dnode,myNodeID,ETHADDRSIZ);
}
82
*/
83 84


85 86 87
int *
forward_request(struct ifi_info *ifihead, const struct in_pktinfo *pktinfo, 
		 const char *mesg, int mesglen, int *ptrSockNum) 
Kristin Wright's avatar
Kristin Wright committed
88 89
{
	int                     s, n;
90
    const int               on = 1;
Kristin Wright's avatar
Kristin Wright committed
91
	char                    ifname[IFNAMSIZ];
92
	struct sockaddr_in      sin,tempAddr;
93
	struct ifi_info         *ifi;
94 95
	int 			*sock_list=NULL, *temp_sock_list=NULL;
	struct topd_inqid *temp_mesg;
96
	int t_int=0,i=0;
97 98 99 100

	bzero(&tempAddr, sizeof(tempAddr));
	tempAddr.sin_family      = AF_INET;
	tempAddr.sin_addr.s_addr = htonl(INADDR_ANY);
101
	tempAddr.sin_port        = htons(0);
Kristin Wright's avatar
Kristin Wright committed
102
	
103 104
	temp_mesg = (struct topd_inqid *)mesg;
	t_int = ntohs(temp_mesg->tdi_ttl);
105
    t_int=t_int-1;
106 107
	temp_mesg->tdi_ttl = htons(t_int);

108 109 110 111 112 113
	(*ptrSockNum) = 0;
	for (ifi = ifihead; ifi != NULL; ifi = ifi->ifi_next) 
	{
		// Skip all the interfaces which are not useful
		if( (ifi->ifi_flags & !IFF_UP) || (ifi->ifi_flags & IFF_LOOPBACK) ||
		    (strcmp(ifi->ifi_name, if_indextoname(pktinfo->ipi_ifindex, ifname)) == 0) ||
114 115 116 117
			/*(strcmp(ifi->ifi_name,"fxp4")==0)*/
			(strncmp(inet_ntoa(((struct sockaddr_in *)(ifi->ifi_addr))->sin_addr),"155.101.132",11)==0)
			)

118 119 120
		{
			continue;
		}
121

122 123
		memcpy(temp_mesg->tdi_p_nodeIF,ifi->ifi_haddr,ETHADDRSIZ);
		//memcpy(&(temp_mesg->tdi_p_nodeIF),&myNodeID,ETHADDRSIZ);
124 125

		printf("Forwarding the query to interface: \"%s\"\n",ifi->ifi_name);
126
		temp_sock_list = sock_list;
127 128
		sock_list = (int *)malloc(sizeof(int)*((*ptrSockNum)+1));
		for(i=0;i<(*ptrSockNum);i++)
129
		{
130
			//printf("copying: %d\n",temp_sock_list[i]);
131 132 133
			sock_list[i] = temp_sock_list[i];
		}
		free(temp_sock_list);
134 135 136 137 138
	    sock_list[(*ptrSockNum)] = s = socket(AF_INET, SOCK_DGRAM, 0);
		(*ptrSockNum)++;
	    if (s == -1) 
		{
			perror("Unable to get socket");
Kristin Wright's avatar
Kristin Wright committed
139 140
			exit(1);
		}
141
		if(bind(s, (struct sockaddr *) &tempAddr, sizeof(tempAddr))<0)
142 143 144
	    {
        	perror("Problem in bind call");
       	} 
145
		ifi->sock = s;
146 147 148 149
		if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) != 0) 
		{
	        perror("setsockopt died.");
			// Do something intelligent. -lkw 
Kristin Wright's avatar
Kristin Wright committed
150 151 152 153 154
		} 
		bzero(&sin, sizeof(sin));
		sin.sin_len = htons(sizeof sin);
		sin.sin_family = PF_INET;
		sin.sin_port = htons(SERV_PORT);
155 156 157
		sin.sin_addr = ((struct sockaddr_in *)(ifi->ifi_brdaddr))->sin_addr;
        printf("The dest. address: %s\n", inet_ntoa(sin.sin_addr));
		printf("Forwarding the enquiry: ");
158
		print_tdinq(mesg);
Kristin Wright's avatar
Kristin Wright committed
159 160
		n = sendto(s, mesg, mesglen, 0, 
			   (struct sockaddr *)&sin, sizeof(struct sockaddr_in));
161 162 163
		if (n != mesglen) 
		{
	        perror("Didn't send all of packet");
Kristin Wright's avatar
Kristin Wright committed
164 165
			exit(1);
		} 
166
	}
Kristin Wright's avatar
Kristin Wright committed
167

168
	return sock_list;
Kristin Wright's avatar
Kristin Wright committed
169

170
	//************************************************************************/
Kristin Wright's avatar
Kristin Wright committed
171
}