Пример #1
0
/*
 * Broadcast a given packet to all interfaces avaliable
 */
int IPOutgoingBcastAllInterPkt(gpacket_t *pkt, int size, int newflag, int src_prot)
{
	uchar dst_ip[4];
	uchar iface_ip[MAX_MTU][4];
	char tmpbuf[MAX_TMPBUF_LEN];
	gpacket_t *cp_pkt;
	int count, i;
	//set broadcast flag
	pkt->frame.bcast = TRUE;
	//loop through each interface
	if ((count = findAllInterfaceIPs(MTU_tbl, iface_ip)) > 0)
	{
		for (i = 0; i < count; i++)
		{
			//check if neighbour still alive on our neighbours table.
			//if we try to send to a dead neighbour it will crash bc of the broken sockets
			verbose(2, "[IPOutgoingBcastAllInterPkt]:: looking for interface IP : %s \n", IP2Dot(tmpbuf, iface_ip[i]));
			int result = isInterfaceDead(iface_ip[i]); 
			if(result == 0) {
				verbose(2, "[IPOutgoingBcastAllInterPkt]:: preparing bcast for interface IP : %s \n", IP2Dot(tmpbuf, iface_ip[i]));
				//clone pkt
				cp_pkt = duplicatePacket(pkt);
				COPY_IP(dst_ip,iface_ip[i]);
				//set 255 on last byte of destination IP address.
				//Please noticed that this will only work for /24 networks.
				dst_ip[0] = IP_BCAST_PREFIX; 
				verbose(2, "[IPOutgoingBcastAllInterPkt]:: preparing bcast to  : %s \n", IP2Dot(tmpbuf, dst_ip));

				//modify if necessary
				ip_packet_t *ip_pkt = (ip_packet_t *)cp_pkt->data.data;

				if(src_prot == OSPF_PROTOCOL) //specific modifications for OSPF_PROTOCOL
				{
					ospfhdr_t *ospfhdr = (ospfhdr_t *)((uchar *)ip_pkt + ip_pkt->ip_hdr_len*4);
					//set source IP on OSPF header
					if (ospfhdr->type == OSPF_HELLO_MESSAGE) {
						COPY_IP(ospfhdr->ip_src, gHtonl(tmpbuf, iface_ip[i]));
					}
					if (ospfhdr->type == OSPF_LINK_STATUS_UPDATE) {
						ospf_lsa_hdr_t *lsahdr = (ospf_lsa_hdr_t *)((uchar *)ospfhdr + OSPF_HEADER_SIZE);

						if (newflag == 1) {
							// This is a packet originated by me
							//set OSPF header source & link state ID & advertising router on LSA header
							COPY_IP(ospfhdr->ip_src, gHtonl(tmpbuf, iface_ip[i]));
							COPY_IP(lsahdr->link_state_id, gHtonl(tmpbuf, iface_ip[i]));
							COPY_IP(lsahdr->ads_router, gHtonl(tmpbuf, iface_ip[i]));
						}
					}
				}

				//send to outgoing with each dst_ip different
				IPBcastOutgoingPacket(cp_pkt, dst_ip, size, newflag, OSPF_PROTOCOL,i+1, iface_ip[i]);
			}
		}
		return TRUE;
	} 
		
	return FALSE; //if no interfaces available
}
Пример #2
0
void *toTapDev(void *arg)
{
	gpacket_t *inpkt = (gpacket_t *)arg;
	interface_t *iface;
	arp_packet_t *apkt;
	char tmpbuf[MAX_TMPBUF_LEN];
	int pkt_size;

	verbose(2, "[toTapDev]:: entering the function.. ");
	// find the outgoing interface and device...
	if ((iface = findInterface(inpkt->frame.dst_interface)) != NULL)
	{
		/* send IP packet or ARP reply */
		if (inpkt->data.header.prot == htons(ARP_PROTOCOL))
		{
			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));
		}
		pkt_size = findPacketSize(&(inpkt->data));

		verbose(2, "[toTapDev]:: tap_sendto called for interface %d.. ", iface->interface_id);
		tap_sendto(iface->vpl_data, &(inpkt->data), pkt_size);
		free(inpkt);          // finally destroy the memory allocated to the packet..
	} else
		error("[toTapDev]:: ERROR!! Could not find outgoing interface ...");

	// this is just a dummy return -- return value not used.
	return arg;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
0
void *toEthernetDev(void *arg)
{
        gpacket_t *inpkt = (gpacket_t *)arg;
	interface_t *iface;
	arp_packet_t *apkt;
        //ospf_packet_t *ospkt;
	char tmpbuf[MAX_TMPBUF_LEN];
	int pkt_size;

	verbose(2, "[toEthernetDev]:: entering the function.. ");
	// find the outgoing interface and device...
        if ((iface = findInterface(inpkt->frame.dst_interface)) != NULL)
	{
            /* send IP packet, ARP reply, or OSPF packet */
            if (inpkt->data.header.prot == htons(ARP_PROTOCOL)){
			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));
            }
            else if (inpkt->data.header.prot == htons(IP_PROTOCOL))
	    {
                ip_packet_t *ip_pkt = (ip_packet_t *)inpkt->data.data;
                if(ip_pkt->ip_prot == OSPF_PROTOCOL){
                
                }
                //RECHECK determine if you're putting MAC address
                //into the right place
	    }
                pkt_size = findPacketSize(&(inpkt->data));
		verbose(2, "[toEthernetDev]:: vpl_sendto called for interface %d..%d bytes written ", iface->interface_id, pkt_size);
		int x = vpl_sendto(iface->vpl_data, &(inpkt->data), pkt_size);
                free(inpkt);          // finally destroy the memory allocated to the packet..
	} else{
            error("[toEthernetDev]:: ERROR!! Could not find outgoing interface ...");
        }
	// this is just a dummy return -- return value not used.
	return arg;
}
Пример #6
0
void *toEthernetDev(void *arg)
{

	gpacket_t *inpkt = (gpacket_t *)arg;
	interface_t *iface;
	arp_packet_t *apkt;
	char tmpbuf[MAX_TMPBUF_LEN];
	int pkt_size;

	verbose(2, "[toEthernetDev]:: entering the function.. ");
	// find the outgoing interface and device...
	if ((iface = findInterface(inpkt->frame.dst_interface)) != NULL)
	{
		/* send IP packet or ARP reply */
		if (inpkt->data.header.prot == htons(ARP_PROTOCOL))
		{
			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));
		}


		pkt_size = findPacketSize(&(inpkt->data));



		//Printing packet values
/*			printf("\n=========== OUTGOING PACKET VALUES ================\n");
			printf("\n----------HEADER VALUES :");
			printf("\nSource MAC Address: %x : %x : %x : %x : %x : %x", inpkt->data.header.src[0],
					inpkt->data.header.src[1],inpkt->data.header.src[2],
					inpkt->data.header.src[3],inpkt->data.header.src[4],inpkt->data.header.src[5]);
			printf("\nDestination MAC Address: %x : %x : %x : %x : %x : %x", inpkt->data.header.dst[0],
					inpkt->data.header.dst[1],inpkt->data.header.dst[2],
					inpkt->data.header.dst[3],inpkt->data.header.dst[4],inpkt->data.header.dst[5]);

			printf("\nSource IP Address: %d.%d.%d.%d", inpkt->frame.src_ip_addr[0],
					inpkt->frame.src_ip_addr[1],inpkt->frame.src_ip_addr[2],
					inpkt->frame.src_ip_addr[3]);


			printf("\nProtocol is : %d",inpkt->data.header.prot);
			printf("\nDestination Interface is : %d",inpkt->frame.dst_interface);
			printf("\nARP BDST : %d",inpkt->frame.arp_bcast);
			printf("\narp_valid : %d",inpkt->frame.arp_valid);
			printf("\nSource Hardware Address: %d.%d.%d.%d.%d.%d", inpkt->frame.src_hw_addr[0],
					inpkt->frame.src_hw_addr[1],inpkt->frame.src_hw_addr[2],
					inpkt->frame.src_hw_addr[3],inpkt->frame.src_hw_addr[4],inpkt->frame.src_hw_addr[5]);


			printf("\nIngress Port is : %d",inpkt->frame.src_interface);
			printf("\nNXTH IP Destination: %d.%d.%d.%d", inpkt->frame.nxth_ip_addr[0],inpkt->frame.nxth_ip_addr[1],
					inpkt->frame.nxth_ip_addr[2],inpkt->frame.nxth_ip_addr[3]);

			printf("\n --- IP PACKET:");
			ip_packet_t *ip_pkt;
			ip_pkt = (ip_packet_t *) inpkt->data.data;

			printf("\Destination MAC Address: %x : %x : %x : %x : %x : %x", inpkt->data.header.dst[0], inpkt->data.header.dst[1],
					inpkt->data.header.dst[2],
					inpkt->data.header.dst[3],inpkt->data.header.dst[4],inpkt->data.header.dst[5]);
			printf("\Source MAC Address: %x : %x : %x : %x : %x : %x", inpkt->data.header.src[0],
					inpkt->data.header.src[1],inpkt->data.header.src[2],
					inpkt->data.header.src[3],inpkt->data.header.src[4],inpkt->data.header.src[5]);
			printf("\nIP Source: %d.%d.%d.%d", ip_pkt->ip_src[0],ip_pkt->ip_src[1],ip_pkt->ip_src[2],ip_pkt->ip_src[3]);
			printf("\nIP Destination: %d.%d.%d.%d", ip_pkt->ip_dst[0],ip_pkt->ip_dst[1],ip_pkt->ip_dst[2],ip_pkt->ip_dst[3]);
			printf("\nIP Protocol is : %d",ip_pkt->ip_prot);
			printf("\nIP TOS: %d\n",ip_pkt->ip_tos);
			printf("\nip_cksum: %d\n",ip_pkt->ip_cksum);
			printf("\nip_frag_off: %d\n",ip_pkt->ip_frag_off);
			printf("\nip_hdr_len: %d\n",ip_pkt->ip_hdr_len);
			printf("\nip_identifier: %d\n",ip_pkt->ip_identifier);
			printf("\nip_pkt_len: %d\n",ip_pkt->ip_pkt_len);
			printf("\nip_ttl: %d\n",ip_pkt->ip_ttl);
			printf("\nip_version: %d\n",ip_pkt->ip_version);*/



		verbose(2, "[toEthernetDev]:: vpl_sendto called for interface %d..%d bytes written ", iface->interface_id, pkt_size);
		vpl_sendto(iface->vpl_data, &(inpkt->data), pkt_size);

		free(inpkt);          // finally destroy the memory allocated to the packet..
	} else
		error("[toEthernetDev]:: ERROR!! Could not find outgoing interface ...");


	// this is just a dummy return -- return value not used.
	return arg;
}
Пример #7
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;
}
Пример #8
0
/*
 * this function processes the IP packets that are reinjected into the
 * IP layer by ICMP, UDP, and other higher-layers.
 * There can be two scenarios. The packet can be a reply for an original
 * query OR it can be a new one. The processing performed by this function depends
 * on the packet type..
 * IMPORTANT: src_prot is the source protocol number.
 */
int IPOutgoingPacket(gpacket_t *pkt, uchar *dst_ip, int size, int newflag, int src_prot)
{
    ip_packet_t *ip_pkt = (ip_packet_t *)pkt->data.data;
	ushort cksum;
	char tmpbuf[MAX_TMPBUF_LEN];
	uchar iface_ip_addr[4];
	int status;


	ip_pkt->ip_ttl = 64;                        // set TTL to default value
	ip_pkt->ip_cksum = 0;                       // reset the checksum field
	ip_pkt->ip_prot = src_prot;  // set the protocol field


	if (newflag == 0)
	{
		//if broadcast packet we set the address for 255.255.255.255
		if(pkt->frame.bcast == TRUE) 
		{
			//set ip to find route eg. 192.168.2.255
			COPY_IP(ip_pkt->ip_dst, gHtonl(tmpbuf, dst_ip));

			// find the nexthop and interface and fill them in the "meta" frame
			// NOTE: the packet itself is not modified by this lookup!
			if (findRouteEntry(route_tbl, gNtohl(tmpbuf, ip_pkt->ip_dst),
					   pkt->frame.nxth_ip_addr, &(pkt->frame.dst_interface)) == EXIT_FAILURE)
					   return EXIT_FAILURE;

			//find interface IP
			if ((status = findInterfaceIP(MTU_tbl, pkt->frame.dst_interface,
					      iface_ip_addr)) == EXIT_FAILURE) {
				error("[IPOutgoingPacket]:: couldn't find interface ");
				return EXIT_FAILURE;
			}
			// the outgoing packet should have the interface IP as source
			COPY_IP(ip_pkt->ip_src, gHtonl(tmpbuf, iface_ip_addr));

			//set broadcast IP = 255.255.255.255
			uchar bcast_ip[] = IP_BCAST_ADDR;
			COPY_IP(ip_pkt->ip_dst, gHtonl(tmpbuf, bcast_ip));
		} else {
			COPY_IP(ip_pkt->ip_dst, ip_pkt->ip_src);  // set dst to original src
			COPY_IP(ip_pkt->ip_src, gHtonl(tmpbuf, pkt->frame.src_ip_addr));    // set src to me

			// find the nexthop and interface and fill them in the "meta" frame
			// NOTE: the packet itself is not modified by this lookup!
			if (findRouteEntry(route_tbl, gNtohl(tmpbuf, ip_pkt->ip_dst),
				   pkt->frame.nxth_ip_addr, &(pkt->frame.dst_interface)) == EXIT_FAILURE)
				   return EXIT_FAILURE;
		}
	} 
	else if (newflag == 1)
	{
		// non REPLY PACKET -- this is a new packet; set all fields
		ip_pkt->ip_version = 4;
		ip_pkt->ip_hdr_len = 5;
		ip_pkt->ip_tos = 0;
		ip_pkt->ip_identifier = IP_OFFMASK & random();
		RESET_DF_BITS(ip_pkt->ip_frag_off);
		RESET_MF_BITS(ip_pkt->ip_frag_off);
		ip_pkt->ip_frag_off = 0;

		COPY_IP(ip_pkt->ip_dst, gHtonl(tmpbuf, dst_ip));
		ip_pkt->ip_pkt_len = htons(size + ip_pkt->ip_hdr_len * 4);
		//printGPacket(pkt, 3, "IP_ROUTINE"); //for debug
		verbose(2, "[IPOutgoingPacket]:: lookup next hop ");
		// find the nexthop and interface and fill them in the "meta" frame
		// NOTE: the packet itself is not modified by this lookup!
		if (findRouteEntry(route_tbl, gNtohl(tmpbuf, ip_pkt->ip_dst),
				   pkt->frame.nxth_ip_addr, &(pkt->frame.dst_interface)) == EXIT_FAILURE) {
			error("[IPOutgoingPacket]:: couldn't find route entry ");
			return EXIT_FAILURE;
		}

		verbose(2, "[IPOutgoingPacket]:: lookup MTU of nexthop");
		// lookup the IP address of the destination interface..
		if ((status = findInterfaceIP(MTU_tbl, pkt->frame.dst_interface,
					      iface_ip_addr)) == EXIT_FAILURE) {
			error("[IPOutgoingPacket]:: couldn't find interface ");
			return EXIT_FAILURE;
		}
					      
		// the outgoing packet should have the interface IP as source
		COPY_IP(ip_pkt->ip_src, gHtonl(tmpbuf, iface_ip_addr));
		
		//if broadcast packet we set the address for 255.255.255.255
		if(pkt->frame.bcast == TRUE) 
		{
			//set broadcast IP = 
			uchar bcast_ip[] = IP_BCAST_ADDR;
			COPY_IP(ip_pkt->ip_dst, gHtonl(tmpbuf, bcast_ip));
		}
		verbose(2, "[IPOutgoingPacket]:: almost one processing the IP header.");
	} else
	{
		error("[IPOutgoingPacket]:: unknown outgoing packet action.. packet discarded ");
		return EXIT_FAILURE;
	}

	//	compute the new checksum
	cksum = checksum((uchar *)ip_pkt, ip_pkt->ip_hdr_len*2);
	ip_pkt->ip_cksum = htons(cksum);
	pkt->data.header.prot = htons(IP_PROTOCOL);

	//FOR DEBUG
	if(src_prot == OSPF_PROTOCOL) //specific modifications for OSPF_PROTOCOL
	{
		ospfhdr_t *ospfhdr = (ospfhdr_t *)((uchar *)ip_pkt + ip_pkt->ip_hdr_len*4);
		if (ospfhdr->type == OSPF_LINK_STATUS_UPDATE && 
			(COMPARE_IP(ospfhdr->ip_src, gHtonl(tmpbuf, iface_ip_addr))) == 0) {
			printGPacket(pkt, 3, "IP_ROUTINE");
			verbose(2,"[DEBUG] Retransmission of LSA pkt, not broadcasting\n");
			//return EXIT_SUCCESS;
		}
	}
	
	IPSend2Output(pkt);
	verbose(2, "[IPOutgoingPacket]:: IP packet sent to output queue.. ");
	return EXIT_SUCCESS;
}
Пример #9
0
Файл: ip.c Проект: Kbrums/gini
/*
 * this function processes the IP packets that are reinjected into the
 * IP layer by ICMP, UDP, and other higher-layers.
 * There can be two scenarios. The packet can be a reply for an original
 * query OR it can be a new one. The processing performed by this function depends
 * on the packet type..
 * IMPORTANT: src_prot is the source protocol number.
 */
int IPOutgoingPacket(gpacket_t *pkt, uchar *dst_ip, int size, int newflag, int src_prot)
{
        ip_packet_t *ip_pkt = (ip_packet_t *)pkt->data.data;
	ushort cksum;
	char tmpbuf[MAX_TMPBUF_LEN];
	uchar iface_ip_addr[4];
	int status;


	ip_pkt->ip_ttl = 64;                        // set TTL to default value
	ip_pkt->ip_cksum = 0;                       // reset the checksum field
	ip_pkt->ip_prot = src_prot;  // set the protocol field


	if (newflag == 0)
	{
		COPY_IP(ip_pkt->ip_dst, ip_pkt->ip_src); 		    // set dst to original src
		COPY_IP(ip_pkt->ip_src, gHtonl(tmpbuf, pkt->frame.src_ip_addr));    // set src to me

		// find the nexthop and interface and fill them in the "meta" frame
		// NOTE: the packet itself is not modified by this lookup!
		if (findRouteEntry(route_tbl, gNtohl(tmpbuf, ip_pkt->ip_dst),
				   pkt->frame.nxth_ip_addr, &(pkt->frame.dst_interface)) == EXIT_FAILURE)
				   return EXIT_FAILURE;

	} else if (newflag == 1)
	{
		// non REPLY PACKET -- this is a new packet; set all fields
		ip_pkt->ip_version = 4;
		ip_pkt->ip_hdr_len = 5;
		ip_pkt->ip_tos = 0;
		ip_pkt->ip_identifier = IP_OFFMASK & random();
		RESET_DF_BITS(ip_pkt->ip_frag_off);
		RESET_MF_BITS(ip_pkt->ip_frag_off);
		ip_pkt->ip_frag_off = 0;

		COPY_IP(ip_pkt->ip_dst, gHtonl(tmpbuf, dst_ip));
		ip_pkt->ip_pkt_len = htons(size + ip_pkt->ip_hdr_len * 4);

		verbose(2, "[IPOutgoingPacket]:: lookup next hop ");
		// find the nexthop and interface and fill them in the "meta" frame
		// NOTE: the packet itself is not modified by this lookup!
		if (findRouteEntry(route_tbl, gNtohl(tmpbuf, ip_pkt->ip_dst),
				   pkt->frame.nxth_ip_addr, &(pkt->frame.dst_interface)) == EXIT_FAILURE)
				   return EXIT_FAILURE;

		verbose(2, "[IPOutgoingPacket]:: lookup MTU of nexthop");
		// lookup the IP address of the destination interface..
		if ((status = findInterfaceIP(MTU_tbl, pkt->frame.dst_interface,
					      iface_ip_addr)) == EXIT_FAILURE)
					      return EXIT_FAILURE;
		// the outgoing packet should have the interface IP as source
		COPY_IP(ip_pkt->ip_src, gHtonl(tmpbuf, iface_ip_addr));
		verbose(2, "[IPOutgoingPacket]:: almost one processing the IP header.");
	} else
	{
		error("[IPOutgoingPacket]:: unknown outgoing packet action.. packet discarded ");
		return EXIT_FAILURE;
	}

	//	compute the new checksum
	cksum = checksum((uchar *)ip_pkt, ip_pkt->ip_hdr_len*2);
	ip_pkt->ip_cksum = htons(cksum);
	pkt->data.header.prot = htons(IP_PROTOCOL);

	IPSend2Output(pkt);
	verbose(2, "[IPOutgoingPacket]:: IP packet sent to output queue.. ");
	return EXIT_SUCCESS;
}