Example #1
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;
}
Example #2
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;
}
Example #3
0
File: ip.c Project: 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;
}