Ejemplo n.º 1
0
void* fromRawDev(void *arg)
{
    interface_t *iface = (interface_t *) arg;
    uchar bcast_mac[] = MAC_BCAST_ADDR;
    gpacket_t *in_pkt;
    int pktsize;
    char tmpbuf[MAX_TMPBUF_LEN];
    
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);		// die as soon as cancelled
    while (1)
    {
        verbose(2, "[fromRawDev]:: Receiving a packet ...");
        if ((in_pkt = (gpacket_t *)malloc(sizeof(gpacket_t))) == NULL)
        {
            fatal("[fromRawDev]:: unable to allocate memory for packet.. ");
            return NULL;
        }

        bzero(in_pkt, sizeof(gpacket_t));
        pktsize = raw_recvfrom(iface->vpl_data, &(in_pkt->data), sizeof(pkt_data_t));
        pthread_testcancel();
        
        verbose(2, "[fromRawDev]:: Destination MAC is %s ", MAC2Colon(tmpbuf, in_pkt->data.header.dst));
        // check whether the incoming packet is a layer 2 broadcast or
        // meant for this node... otherwise should be thrown..
        // TODO: fix for promiscuous mode packet snooping.
        if ((COMPARE_MAC(in_pkt->data.header.dst, iface->mac_addr) != 0) &&
                (COMPARE_MAC(in_pkt->data.header.dst, bcast_mac) != 0))
        {
            verbose(2, "[fromRawDev]:: Packet[%d] dropped .. not for this router!? ", pktsize);
            free(in_pkt);
            continue;
        }
		
        // copy fields into the message from the packet..
        in_pkt->frame.src_interface = iface->interface_id;
        COPY_MAC(in_pkt->frame.src_hw_addr, iface->mac_addr);
        COPY_IP(in_pkt->frame.src_ip_addr, iface->ip_addr);
	
	
	char buf[20];
	memset(buf, 0, sizeof(buf));
	IP2Dot(buf, in_pkt->frame.src_ip_addr);
//	if(strcmp(buf, "172.31.32.1")==0)
//		printf("FROM RAW IP %s\n", buf);
        // check for filtering.. if the it should be filtered.. then drop
     
	if (filteredPacket(filter, in_pkt))
        {
            verbose(2, "[fromRawDev]:: Packet filtered..!");
            free(in_pkt);
            continue;   // skip the rest of the loop
        }

        verbose(2, "[fromRawDev]:: Packet is sent for enqueuing..");
        enqueuePacket(pcore, in_pkt, sizeof(gpacket_t));
    }
}
Ejemplo n.º 2
0
/*
 * Find an ARP entry matching the supplied IP address in the ARP table
 * ARGUMENTS: uchar *ip_addr: IP address to look up
 *            uchar *mac_addr: returned MAC address corresponding to the IP
 * The MAC is only set when the return status is EXIT_SUCCESS. If error,
 * the MAC address (mac_addr) is undefined.
 */
int ARPFindEntry(uchar *ip_addr, uchar *mac_addr)
{
	int i;
	char tmpbuf[MAX_TMPBUF_LEN];

	for (i = 0; i < MAX_ARP; i++)
	{
		if(ARPtable[i].is_empty == FALSE &&
		   COMPARE_IP(ARPtable[i].ip_addr, ip_addr) == 0)
		{
			// found IP address - copy the MAC address
			COPY_MAC(mac_addr, ARPtable[i].mac_addr);
			verbose(2, "[ARPFindEntry]:: found ARP entry #%d for IP %s", i, IP2Dot(tmpbuf, ip_addr));
			return EXIT_SUCCESS;
		}
	}

	verbose(2, "[ARPFindEntry]:: failed to find ARP entry for IP %s", IP2Dot(tmpbuf, ip_addr));
	return EXIT_FAILURE;
}
Ejemplo n.º 3
0
/*
 * TODO: broadcast not yet implemented.. should be simple to implement.
 * read RFC 1812 and 922 ...
 */
int IPProcessBcastPacket(gpacket_t *in_pkt)
{
	ip_packet_t *ip_pkt = (ip_packet_t *)in_pkt->data.data;
	char tmpbuf[MAX_TMPBUF_LEN];
	verbose(2, "[IPProcessBcastPacket]:: Received broadcast packet from %s ", IP2Dot(tmpbuf, ip_pkt->ip_src));
	if(ip_pkt->ip_prot == OSPF_PROTOCOL){
		OSPFProcessPacket(in_pkt);
		return EXIT_SUCCESS;
	}
	return EXIT_SUCCESS;
}
Ejemplo n.º 4
0
/*
 * add an entry to the ARP table
 * ARGUMENTS: uchar *ip_addr - the IP address (4 bytes)
 *            uchar *mac_addr - the MAC address (6 bytes)
 * RETURNS: Nothing
 */
void ARPAddEntry(uchar *ip_addr, uchar *mac_addr)
{
	int i;
	int empty_slot = MAX_ARP;
	char tmpbuf[MAX_TMPBUF_LEN];

	for (i = 0; i < MAX_ARP; i++)
	{
		if ((ARPtable[i].is_empty == FALSE) &&
		    (COMPARE_IP(ARPtable[i].ip_addr, ip_addr) == 0))
		{
			// update entry
			COPY_IP(ARPtable[i].ip_addr, ip_addr);
			COPY_MAC(ARPtable[i].mac_addr, mac_addr);

			verbose(2, "[ARPAddEntry]:: updated ARP table entry #%d: IP %s = MAC %s", i,
			       IP2Dot(tmpbuf, ip_addr), MAC2Colon(tmpbuf+20, mac_addr));
			return;
		}
		if (ARPtable[i].is_empty == TRUE)
			empty_slot = i;
	}

	if (empty_slot == MAX_ARP)
	{
		// ARP table full.. do the replacement
		// use the FIFO strategy: table replace index is the FIFO pointer
		empty_slot = tbl_replace_indx;
		tbl_replace_indx = (tbl_replace_indx + 1) % MAX_ARP;
	}

	// add new entry or overwrite the replaced entry
	ARPtable[empty_slot].is_empty = FALSE;
	COPY_IP(ARPtable[empty_slot].ip_addr, ip_addr);
	COPY_MAC(ARPtable[empty_slot].mac_addr, mac_addr);

	verbose(2, "[ARPAddEntry]:: updated ARP table entry #%d: IP %s = MAC %s", empty_slot,
	       IP2Dot(tmpbuf, ip_addr), MAC2Colon(tmpbuf+20, mac_addr));

	return;
}
Ejemplo n.º 5
0
void *toRawDev(void *arg)
{
	gpacket_t *inpkt = (gpacket_t *)arg;
	interface_t *iface;
	arp_packet_t *apkt;
	char tmpbuf[MAX_TMPBUF_LEN];
	int pkt_size;

	verbose(1, "[toRawDev]:: entering the function.. ");
	// find the outgoing interface and device...
	if ((iface = findInterface(inpkt->frame.dst_interface)) != NULL)
	{
		char tmp[40];
		memset(tmp, 0, sizeof(tmp));
		IP2Dot(tmp, inpkt->frame.src_ip_addr);
		/* The Amazon network has the prefix 172, so if a packet is sent to the raw interface and it does
		not begin with that prefix, we know that the packet has come from the local gini network instead.
		In this case we want to apply a SNAT, to make the packet seem as if it has come from the cRouter 
		so that Amazon machines will be able to respond (recognize the address). Note that the reverse
		NAT operation is performed in ip.c*/
		/*if(inpkt->data.header.prot != htons(ARP_PROTOCOL) && !(tmp[0] == '1' && tmp[1] == '7' && tmp[2] == '2')) {
			//printf("\n\n TRYING TO PING AMAZON CLOUD\n");				
			//printGPacket(inpkt, 3, "CONNOR PACKET");
			ip_packet_t *ipkt = (ip_packet_t *)(inpkt->data.data);
			ipkt->ip_hdr_len = 5;                                  // no IP header options!!
			icmphdr_t *icmphdr = (icmphdr_t *)((uchar *)ipkt + ipkt->ip_hdr_len*4);
			printf("\n\nICMP ID: %d\n", icmphdr->un.echo.id); 
			The IP address given to the SNAT function is the private ip address of the 
			Amazon instance that is running the cRouter in reverse 
			applySNAT("62.44.31.172", (ip_packet_t*)inpkt->data.data, icmphdr->un.echo.id);
			printNAT();	
		}*/
		/* send IP packet or ARP reply */
		if (inpkt->data.header.prot == htons(ARP_PROTOCOL))
		{
			printf("CONNORS DEBUG arp in toRawDev\n");
			apkt = (arp_packet_t *) inpkt->data.data;
			COPY_MAC(apkt->src_hw_addr, iface->mac_addr);
			COPY_IP(apkt->src_ip_addr, gHtonl(tmpbuf, iface->ip_addr));
		}
		if(inpkt->data.header.prot == htons(ICMP_PROTOCOL)){
			printf("\nICMP Request over raw\n");
		}		
		pkt_size = findPacketSize(&(inpkt->data));
		verbose(2, "[toRawDev]:: raw_sendto called for interface %d.. ", iface->interface_id);
		raw_sendto(iface->vpl_data, &(inpkt->data), pkt_size);
		free(inpkt);          // finally destroy the memory allocated to the packet..
	} else
		error("[toRawDev]:: ERROR!! Could not find outgoing interface ...");

	// this is just a dummy return -- return value not used.
	return arg;
}
Ejemplo n.º 6
0
/*
 * get a packet from the ARP buffer
 * ARGUMENTS: out_pkt - pointer at which packet matching message is to be copied
 *              nexthop - pointer to dest. IP address to search for
 * RETURNS: The function returns EXIT_SUCCESS if packet was found and copied,
 * or EXIT_FAILURE if it was not found.
 */
int ARPGetBuffer(gpacket_t **out_pkt, uchar *nexthop)
{
	int i;
	char tmpbuf[MAX_TMPBUF_LEN];

	// Search for packet in buffer
	for (i = 0; i < MAX_ARP_BUFFERS; i++)
	{
		if (ARPbuffer[i].is_empty == TRUE) continue;
		if (COMPARE_IP(ARPbuffer[i].wait_msg->frame.nxth_ip_addr, nexthop) == 0)
		{
			// match found
			*out_pkt =  ARPbuffer[i].wait_msg;
			ARPbuffer[i].is_empty = TRUE;
			verbose(2, "[ARPGetBuffer]:: found packet matching nexthop %s at entry %d",
			       IP2Dot(tmpbuf, nexthop), i);
			return EXIT_SUCCESS;
		}
	}
	verbose(2, "[ARPGetBuffer]:: no match for nexthop %s", IP2Dot(tmpbuf, nexthop));
	return EXIT_FAILURE;
}
Ejemplo n.º 7
0
/*
 * check whether the IP packet has correct checksum and
 * version number... this router is hard coded for IP version 4!
 * NOTE: we don't send any ICMP error messages to the source - instead
 * we silently drop the packet. It seems (should check carefully) that
 * ICMP does not have a facility to report this kind of condition.
 * May be this condition is not likely to happen???
 */
int IPVerifyPacket(ip_packet_t *ip_pkt)
{
	char tmpbuf[MAX_TMPBUF_LEN];
	int hdr_len = ip_pkt->ip_hdr_len;

	// verify the header checksum
	if (checksum((void *)ip_pkt, hdr_len *2) != 0)
	{
		verbose(2, "[IPVerifyPacket]:: packet from %s failed checksum, packet thrown",
		       IP2Dot(tmpbuf, gNtohl((tmpbuf+20), ip_pkt->ip_src)));
		return EXIT_FAILURE;
	}

	// Check correct IP version
	if (ip_pkt->ip_version != 4)
	{
		verbose(2, "[IPVerifyPacket]:: from %s failed checksum, packet thrown",
		       IP2Dot(tmpbuf, gNtohl((tmpbuf + 20), ip_pkt->ip_src)));
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
Ejemplo n.º 8
0
/*
 * IPCheckPacket4Me: Return TRUE if the packet is meant for me. Otherwise return FALSE.
 * Check against all possible IPs I have to determine whether this packet
 * is meant for me.
 */
int IPCheckPacket4Me(gpacket_t *in_pkt)
{
	ip_packet_t *ip_pkt = (ip_packet_t *)&in_pkt->data.data;
	char tmpbuf[MAX_TMPBUF_LEN];
	int count, i;
	uchar iface_ip[MAX_MTU][4];
	uchar pkt_ip[4];

	COPY_IP(pkt_ip, gNtohl(tmpbuf, ip_pkt->ip_dst));
	verbose(2, "[IPCheckPacket4Me]:: looking for IP %s ", IP2Dot(tmpbuf, pkt_ip));
	if ((count = findAllInterfaceIPs(MTU_tbl, iface_ip)) > 0)
	{
		for (i = 0; i < count; i++)
		{
			if (COMPARE_IP(iface_ip[i], pkt_ip) == 0)
			{
				verbose(2, "[IPCheckPacket4Me]:: found a matching IP.. for %s ", IP2Dot(tmpbuf, pkt_ip));
				return TRUE;
			}
		}
		return FALSE;
	} else
		return FALSE;
}
Ejemplo n.º 9
0
/*
 * print the ARP table
 */
void ARPPrintTable(void)
{
	int i;
	char tmpbuf[MAX_TMPBUF_LEN];

	printf("-----------------------------------------------------------\n");
	printf("      A R P  T A B L E \n");
	printf("-----------------------------------------------------------\n");
	printf("Index\tIP address\tMAC address \n");

	for (i = 0; i < MAX_ARP; i++)
		if (ARPtable[i].is_empty == FALSE)
			printf("%d\t%s\t%s\n", i, IP2Dot(tmpbuf, ARPtable[i].ip_addr), MAC2Colon((tmpbuf+20), ARPtable[i].mac_addr));
	printf("-----------------------------------------------------------\n");
	return;
}
Ejemplo n.º 10
0
Archivo: gnet.c Proyecto: draringi/gini
void printARPCache(void)
{
	int i;
	char tmpbuf[MAX_TMPBUF_LEN];

	printf("\n-----------------------------------------------------------\n");
	printf("      A R P  C A C H E \n");
	printf("-----------------------------------------------------------\n");
	printf("Index\tIP address\tMAC address \n");

	for (i = 0; i < MAX_ARP; i++)
		if (arp_cache[i].is_empty == FALSE)
			printf("%d\t%s\t%s\n", i, IP2Dot(tmpbuf, arp_cache[i].ip_addr),
			       MAC2Colon((tmpbuf+20), arp_cache[i].mac_addr));
	printf("-----------------------------------------------------------\n");
	return;
}
Ejemplo n.º 11
0
/*
 * check for MTU sizes and DF flag..
 * first get the MTU value for the next hop interface.
 * if the current packet size is greater than the next hop MTU, then
 * fragmentation is needed. If the DF is set and fragmentation is
 * needed, an error condition occurs.
 * FRAGS_NONE - no fragmentation;
 * FRAGS_ERROR - fragmentation error;
 * MORE_FRAGS - fragmentation is required.
 * GENERAL_ERROR - mtu not found.
 */
int IPCheck4Fragmentation(gpacket_t *in_pkt)
{
	int link_mtu;
	char tmpbuf[MAX_TMPBUF_LEN];
	ip_packet_t *ip_pkt = (ip_packet_t *)in_pkt->data.data;

	verbose(2, "[IPCheck4Fragmentation]:: .. checking mtu for next hop %s and interface %d ",
		IP2Dot(tmpbuf, in_pkt->frame.nxth_ip_addr), in_pkt->frame.dst_interface);

	if ((link_mtu = findMTU(MTU_tbl, in_pkt->frame.dst_interface)) < 0)
		return GENERAL_ERROR;

	if (link_mtu < ntohs(ip_pkt->ip_pkt_len))                 // need fragmentation
	{
		if (TEST_DF_BITS(ip_pkt->ip_frag_off))    // DF is set: destination unreachable
			return FRAGS_ERROR;
		return MORE_FRAGS;
	} else
		return FRAGS_NONE;
}
Ejemplo n.º 12
0
Archivo: gnet.c Proyecto: draringi/gini
interface_t *GNETMakeTapInterface(char *device, uchar *mac_addr, uchar *nw_addr)
{
	vpl_data_t *vcon;
	interface_t *iface;
	int iface_id;
	char tmpbuf[MAX_TMPBUF_LEN];


	verbose(2, "[GNETMakeTapInterface]:: making Interface for [%s] with MAC %s and IP %s",
		device, MAC2Colon(tmpbuf, mac_addr), IP2Dot((tmpbuf+20), nw_addr));

	iface_id = gAtoi(device);

	if (findInterface(iface_id) != NULL)
	{
		verbose(1, "[GNETMakeTapInterface]:: device %s already defined.. ", device);
		return NULL;
	}
	else
	{
		// setup the interface.. with default MTU of 1500 we cannot set it at this time.
		iface = newInterfaceStructure(device, device, mac_addr, nw_addr, 1500);

		/*
		 * try connection (as client). only option here...
		 */
		verbose(2, "[GNETMakeTapInterface]:: trying to connect to %s..", device);
		if ((vcon = tap_connect(device)) == NULL)
		{
			verbose(1, "[GNETMakeTapInterface]:: unable to connect to %s", device);
			return NULL;
		}

		// fill in the rest of the interface
		iface->iface_fd = vcon->data;
		iface->vpl_data = vcon;

		upThisInterface(iface);
		return iface;
	}
}
Ejemplo n.º 13
0
/*
 * flush all packets from buffer matching the nexthop
 * for which we now have an ARP entry
 */
void ARPFlushBuffer(char *next_hop, char *mac_addr)
{
	gpacket_t *bfrd_msg;
	char tmpbuf[MAX_TMPBUF_LEN];

	verbose(2, "[ARPFlushBuffer]:: Entering the function.. ");
	while (ARPGetBuffer(&bfrd_msg, next_hop) == EXIT_SUCCESS)
	{
		// a message is already buffered.. send it out..
		// TODO: include QoS routines.. for now they are removed!

		// send to gnetAdapter
		// no need to set dst_int_num -- why?

		verbose(2, "[ARPFlushBuffer]:: flushing the entry with next_hop %s ", IP2Dot(tmpbuf, next_hop));
		COPY_MAC(bfrd_msg->data.header.dst, mac_addr);
		ARPSend2Output(bfrd_msg);
	}

	return;
}
Ejemplo n.º 14
0
/*
 * send an ARP request to eventually process message,
 * a copy of which is now in the buffer
 */
void ARPSendRequest(gpacket_t *pkt)
{
	arp_packet_t *apkt = (arp_packet_t *) pkt->data.data;
	uchar bcast_addr[6];
	char tmpbuf[MAX_TMPBUF_LEN];

	memset(bcast_addr, 0xFF, 6);

	/*
	 * Create ARP REQUEST packet
	 * ether header will be set in GNET_ADAPTER
	 * arp header
	 */
	apkt->hw_addr_type = htons(ETHERNET_PROTOCOL);      // set hw type
	apkt->arp_prot = htons(IP_PROTOCOL);                // set prtotocol address format

	apkt->hw_addr_len = 6;                              // address length
	apkt->arp_prot_len = 4;                             // protocol address length
	apkt->arp_opcode = htons(ARP_REQUEST);              // set ARP request opcode

	// source hw addr will be set in GNET_ADAPTER
	// source ip addr will be set in GNET_ADAPTER
	COPY_MAC(apkt->dst_hw_addr, bcast_addr);            // target hw addr

	COPY_IP(apkt->dst_ip_addr, gHtonl((uchar *)tmpbuf, pkt->frame.nxth_ip_addr));    // target ip addr

	// send the ARP request packet
	verbose(2, "[sendARPRequest]:: sending ARP request for %s",
		IP2Dot(tmpbuf, pkt->frame.nxth_ip_addr));

	// prepare sending.. to GNET adapter..

	COPY_MAC(pkt->data.header.dst, bcast_addr);
	pkt->data.header.prot = htons(ARP_PROTOCOL);
	// actually send the message to the other module..
	ARPSend2Output(pkt);

	return;
}
Ejemplo n.º 15
0
Archivo: gnet.c Proyecto: draringi/gini
/*
 * ARGUMENTS: device:  e.g. tun2
 * 			  mac_addr: hardware address of the interface
 * 			  nw_addr: network address of the interface (IPv4 by default)
 * 			  dst_ip: physical IP address of destination mesh station on the MBSS
 *				  dst_port: interface number of the destination interface on the destination yRouter
 * RETURNS: a pointer to the interface on success and NULL on failure
 */
interface_t *GNETMakeTunInterface(char *device, uchar *mac_addr, uchar *nw_addr,
                                  uchar* dst_ip, short int dst_port)
{
    vpl_data_t *vcon;
    interface_t *iface;
    int iface_id;
    char tmpbuf[MAX_TMPBUF_LEN];

    verbose(2, "[GNETMakeTunInterface]:: making Interface for [%s] with MAC %s and IP %s",
	device, MAC2Colon(tmpbuf, mac_addr), IP2Dot((tmpbuf+20), nw_addr));

    iface_id = gAtoi(device);
        
    if (findInterface(iface_id) != NULL)
    {
	verbose(1, "[GNETMakeTunInterface]:: device %s already defined.. ", device);
	return NULL;
    }
    
    // setup the interface..
    iface = newInterfaceStructure(device, device,
                                  mac_addr, nw_addr, MAX_MTU);
    
    verbose(2, "[GNETMakeTunInterface]:: trying to connect to %s..", device);
    
    vcon = tun_connect((short int)(BASEPORTNUM+iface_id+gAtoi(rconfig.router_name)*100), NULL, (short int)(BASEPORTNUM+dst_port+gAtoi(rconfig.router_name)*100), dst_ip); 
    
    if(vcon == NULL)
    {
        verbose(1, "[GNETMakeTunInterface]:: unable to connect to %s", device);
        return NULL;
    }

    iface->iface_fd = vcon->data;
    iface->vpl_data = vcon;
    
    upThisInterface(iface);
    return iface;
}
Ejemplo n.º 16
0
int create_raw_interface(unsigned char *nw_addr)
{
    int pid, status;                                             
    int error;                                        
    char* argv[4];                                               
                                                                 
    // Get executable path                                       
    argv[0] = malloc(strlen(rconfig.gini_home) + strlen("/iface.sh") + 5);
    strcpy(argv[0], rconfig.gini_home);                                  
    strcat(argv[0], "/iface.sh");                                                              
                                                                 
    // Get topology number in ascii                              
    argv[1] = malloc(4);                                         
    sprintf(argv[1], "%d", rconfig.top_num);                             
                                                                 
    // Get IP address in ascii                                   
    argv[2] = malloc(20);                                        
    IP2Dot(argv[2], nw_addr);                                                          
                                                                 
    argv[3] = NULL;                      
    
    pid = fork();                                                                
    if(pid == 0) {                       
        execvp(argv[0], argv);               
        error = -1;                      
        exit(-1);                        
    } else {                             
        waitpid(pid, &status, 0);        
        if(WEXITSTATUS(status) == 1) {   
            error = -1;                          
        }                                        
    }                                                 
    
    free(argv[0]);
    free(argv[1]); 
    free(argv[2]);   
    
    return error;   
}
Ejemplo n.º 17
0
int IPCheck4Errors(gpacket_t *in_pkt)
{
	char tmpbuf[MAX_TMPBUF_LEN];
	ip_packet_t *ip_pkt = (ip_packet_t *)in_pkt->data.data;

	// check for valid version and checksum.. silently drop the packet if not.
	if (IPVerifyPacket(ip_pkt) == EXIT_FAILURE)
		return EXIT_FAILURE;

	// Decrement TTL, if TTL <= 0, send to ICMP module with TTL-expired command
	// return EXIT_FAILURE
	if (--ip_pkt->ip_ttl <= 0)
	{
		verbose(2, "[processIPErrors]:: TTL expired on packet from %s",
		       IP2Dot(tmpbuf, gNtohl((tmpbuf+20), ip_pkt->ip_src)));

		ICMPProcessTTLExpired(in_pkt);
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
Ejemplo n.º 18
0
/*
 * check for redirection condition. This function always returns
 * success. That is no matter whether redirection was sent or not
 * it returns success!
 */
int IPCheck4Redirection(gpacket_t *in_pkt)
{
	char tmpbuf[MAX_TMPBUF_LEN];
	gpacket_t *cp_pkt;
	ip_packet_t *ip_pkt = (ip_packet_t *)in_pkt->data.data;

	// check for redirect condition and send an ICMP back... let the current packet
	// go as well (check the specification??)
	if (isInSameNetwork(gNtohl(tmpbuf, ip_pkt->ip_src), in_pkt->frame.nxth_ip_addr) == EXIT_SUCCESS)
	{
		verbose(2, "[processIPErrors]:: redirect message sent on packet from %s",
		       IP2Dot(tmpbuf, gNtohl((tmpbuf+20), ip_pkt->ip_src)));

		cp_pkt = duplicatePacket(in_pkt);

		ICMPProcessRedirect(cp_pkt, cp_pkt->frame.nxth_ip_addr);
	}

	// IP packet is verified to be good. This packet should be
	// further processed to carry out forwarding.
	return EXIT_SUCCESS;
}
Ejemplo n.º 19
0
Archivo: gnet.c Proyecto: draringi/gini
interface_t *GNETMakeEthInterface(char *vsock_name, char *device,
			   uchar *mac_addr, uchar *nw_addr, int iface_mtu, int cforce)
{
	vpl_data_t *vcon;
	interface_t *iface;
	int iface_id, thread_stat;
	char tmpbuf[MAX_TMPBUF_LEN];
	vplinfo_t *vi;
	pthread_t threadid;


	verbose(2, "[GNETMakeEthInterface]:: making Interface for [%s] with MAC %s and IP %s",
		device, MAC2Colon(tmpbuf, mac_addr), IP2Dot((tmpbuf+20), nw_addr));

	iface_id = gAtoi(device);
	
	if (findInterface(iface_id) != NULL)
	{
		verbose(1, "[GNETMakeEthInterface]:: device %s already defined.. ", device);
		return NULL;
	}
	else
	{
		// setup the interface..
		iface = newInterfaceStructure(vsock_name, device,
					      mac_addr, nw_addr, iface_mtu);

		/*
		 * try connection (as client). if it fails and force client flag
		 * is set, then return NULL. Otherwise, try server connection,
		 * if this fails, print error and return NULL
		 */

		verbose(2, "[GNETMakeEthInterface]:: trying to connect to %s..", vsock_name);
		if ((vcon = vpl_connect(vsock_name)) == NULL)
		{
			verbose(2, "[GNETMakeEthInterface]:: connecting as server.. ");
			// if client mode is forced.. fail here.. cannot do much!
			if (cforce)
			{
				verbose(1, "[GNETMakeEthInterface]:: unable to make network connection...");
				return NULL;
			}
			// try making a server connection...
			// now that the client connection has failed

			if ((vcon = vpl_create_server(vsock_name)) == NULL)
			{
				verbose(1, "[GNETMakeEthInterface]:: unable to make server connection.. ");
				return NULL;
			}

			vi = (vplinfo_t *)malloc(sizeof(vplinfo_t));
			iface->mode = IFACE_SERVER_MODE;
			vi->vdata = vcon;
			vi->iface = iface;
			thread_stat = pthread_create(&(iface->sdwthread), NULL,
						     (void *)delayedServerCall, (void *)vi);
			if (thread_stat != 0)
				return NULL;

			// return for now.. the thread spawned above will change the
			// interface state when the remote node makes the connection.
			return iface;
		}

		verbose(2, "[GNETMakeEthInterface]:: VPL connection made as client ");

		// fill in the rest of the interface
		iface->iface_fd = vcon->data;
		iface->vpl_data = vcon;

		upThisInterface(iface);
		return iface;
	}
}
Ejemplo n.º 20
0
/*
 * process an IP packet destined to someone else...
 * ARGUMENT: in_pkt - pointer to incoming packet
 *
 * Error processing: Check for conditions that generate ICMP packets.
 * For example, TTL expired, redirect, mulformed packets, ...
 * DF set and fragment,.. etc.
 *
 * Fragment processing: Check whether fragment is necessary .. condition already checked.
 *
 * Forward packet and fragments (could be multicasting)
 */
int IPProcessForwardingPacket(gpacket_t *in_pkt)
{
	gpacket_t *pkt_frags[MAX_FRAGMENTS];
	ip_packet_t *ip_pkt = (ip_packet_t *)in_pkt->data.data;
	int num_frags, i, need_frag;
	char tmpbuf[MAX_TMPBUF_LEN];

	verbose(2, "[IPProcessForwardingPacket]:: checking for any IP errors..");
	// all the validation and ICMP generation, processing is
	// done in this function...
	if (IPCheck4Errors(in_pkt) == EXIT_FAILURE)
		return EXIT_FAILURE;

	// find the route... if it does not exist, should we send a
	// ICMP network/host unreachable message -- CHECK??
	if (findRouteEntry(route_tbl, gNtohl(tmpbuf, ip_pkt->ip_dst),
			   in_pkt->frame.nxth_ip_addr,
			   &(in_pkt->frame.dst_interface)) == EXIT_FAILURE)
		return EXIT_FAILURE;

	// check for redirection?? -- the output interface is already found
	// by the previous command.. if needed the following routine sends the
	// redirects but the packet is sent to destination..
	// TODO: Check the RFC for conformance??
	IPCheck4Redirection(in_pkt);

	// check for fragmentation -- this should return three conditions:
	// FRAGS_NONE, FRAGS_ERROR, MORE_FRAGS
	need_frag = IPCheck4Fragmentation(in_pkt);

	switch (need_frag)
	{
	case FRAGS_NONE:
		verbose(2, "[IPProcessForwardingPacket]:: sending packet to GNET..");
		// compute the checksum before sending out.. the fragmentation routine does this inside it.
		ip_pkt->ip_cksum = 0;
		ip_pkt->ip_cksum = htons(checksum((uchar *)ip_pkt, ip_pkt->ip_hdr_len *2));
		if (IPSend2Output(in_pkt) == EXIT_FAILURE)
		{
			verbose(1, "[IPProcessForwardingPacket]:: WARNING: IPProcessForwardingPacket(): Could not forward packets ");
			return EXIT_FAILURE;
		}
		break;

	case FRAGS_ERROR:
		verbose(2, "[IPProcessForwardingPacket]:: unreachable on packet from %s",
			IP2Dot(tmpbuf, gNtohl((tmpbuf+20), ip_pkt->ip_src)));
		ICMPProcessFragNeeded(in_pkt);
		break;

	case MORE_FRAGS:
		// fragment processing...
		num_frags = fragmentIPPacket(in_pkt, pkt_frags);

		verbose(2, "[IPProcessForwardingPacket]:: IP packet needs fragmentation");
		// forward each fragment
		for (i = 0; i < num_frags; i++)
		{
			if (IPSend2Output(pkt_frags[i]) == EXIT_FAILURE)
			{
				verbose(1, "[IPProcessForwardingPacket]:: processForwardIPPacket(): Could not forward packets ");
				return EXIT_FAILURE;
			}
		}
		deallocateFragments(pkt_frags, num_frags);
		break;
	default:
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}
Ejemplo n.º 21
0
/*
 * ARPProcess: Process a received ARP packet... from remote nodes. If it is
 * a reply for a ARP request sent from the local node, use it
 * to update the local ARP cache. Flush (dequeue, process, and send) any packets
 * that are buffered for ARP processing that match the ARP reply.

 * If it a request, send a reply.. no need to record any state here.
 */
void ARPProcess(gpacket_t *pkt)
{
	char tmpbuf[MAX_TMPBUF_LEN];

	arp_packet_t *apkt = (arp_packet_t *) pkt->data.data;

	// check packet is ethernet and addresses of IP type.. otherwise throw away
	if ((ntohs(apkt->hw_addr_type) != ETHERNET_PROTOCOL) || (ntohs(apkt->arp_prot) != IP_PROTOCOL))
	{
		verbose(2, "[ARPProcess]:: unknown hwtype or protocol, dropping ARP packet");
		return;
	}


	verbose(2, "[ARPProcess]:: adding sender of received packet to ARP table");
	ARPAddEntry(gNtohl((uchar *)tmpbuf, apkt->src_ip_addr), apkt->src_hw_addr);

	// Check it's actually destined to us,if not throw packet
	if (COMPARE_IP(apkt->dst_ip_addr, gHtonl((uchar *)tmpbuf, pkt->frame.src_ip_addr)) != 0)
	{
		verbose(2, "[APRProcess]:: packet has a frame source (after ntohl) %s ...",
		       IP2Dot(tmpbuf, gNtohl((uchar *)tmpbuf, pkt->frame.src_ip_addr)));

		verbose(2, "[APRProcess]:: packet destined for %s, dropping",
		       IP2Dot(tmpbuf, gNtohl((uchar *)tmpbuf, apkt->dst_ip_addr)));
		return;
	}

	// We have a valid ARP packet, lets process it now.
	// If it's a REQUEST, send a reply back
	if (ntohs(apkt->arp_opcode) == ARP_REQUEST)
	{
		apkt->arp_opcode = htons(ARP_REPLY);
		COPY_MAC(apkt->src_hw_addr, pkt->frame.src_hw_addr);
		COPY_MAC(apkt->dst_hw_addr, pkt->data.header.src);
		COPY_IP(apkt->dst_ip_addr, apkt->src_ip_addr);
		COPY_IP(apkt->src_ip_addr, gHtonl((uchar *)tmpbuf, pkt->frame.src_ip_addr));

		verbose(2, "[ARPProcess]:: packet was ARP REQUEST, sending ARP REPLY packet");

		// prepare for sending. Set some parameters that is going to be used
		// by the GNET adapter...

		pkt->frame.dst_interface = pkt->frame.src_interface;

		COPY_MAC(pkt->data.header.dst, pkt->data.header.src);
		COPY_MAC(pkt->data.header.src,  pkt->frame.src_hw_addr);
		COPY_IP(pkt->frame.nxth_ip_addr, gNtohl((uchar *)tmpbuf, apkt->dst_ip_addr));
		pkt->frame.arp_valid = TRUE;

		pkt->data.header.prot = htons(ARP_PROTOCOL);

		ARPSend2Output(pkt);
	}
	else if (ntohs(apkt->arp_opcode) == ARP_REPLY)
	{
		// Flush buffer of any packets waiting for the incoming ARP..
		verbose(2, "[ARPProcess]:: packet was ARP REPLY... ");
		ARPFlushBuffer(gNtohl((uchar *)tmpbuf, apkt->src_ip_addr), apkt->src_hw_addr);
		verbose(2, "[ARPProcess]:: flushed the ARP buffer ... ");
	}
	else
		verbose(2, "[ARPProcess]:: unknown ARP type");

	return;
}