예제 #1
0
파일: ip.c 프로젝트: jshamash/grouter
/*
 * IPIncomingPacket: Process incoming IP packet.
 * The IP packet can be destined to the local router (for example route updates).
 * Or it could be a packet meant for forwarding: either unicast or multicast/broadcast.
 * This is a wrapper routine that calls the appropriate subroutine to take
 * the appropriate function.
 */
void IPIncomingPacket(gpacket_t *in_pkt)
{
	char tmpbuf[MAX_TMPBUF_LEN];
	// get a pointer to the IP packet
        ip_packet_t *ip_pkt = (ip_packet_t *)&in_pkt->data.data;
	uchar bcast_ip[] = IP_BCAST_ADDR;

	// Is this IP packet for me??
	if (IPCheckPacket4Me(in_pkt))
	{
		verbose(2, "[IPIncomingPacket]:: got IP packet destined to this router");
		IPProcessMyPacket(in_pkt);
	} else if (COMPARE_IP(gNtohl(tmpbuf, ip_pkt->ip_dst), bcast_ip) == 0)
	{
		// TODO: rudimentary 'broadcast IP address' check
		verbose(2, "[IPIncomingPacket]:: not repeat broadcast (final destination %s), packet thrown",
		       IP2Dot(tmpbuf, gNtohl((tmpbuf+20), ip_pkt->ip_dst)));
		IPProcessBcastPacket(in_pkt);
	} else
	{
		// Destinated to someone else
		verbose(2, "[IPIncomingPacket]:: got IP packet destined to someone else");
		IPProcessForwardingPacket(in_pkt);
	}
}
예제 #2
0
파일: message.c 프로젝트: Kbrums/gini
int printIPPacket(gpacket_t *msg)
{
	ip_packet_t *ip_pkt;
	char tmpbuf[MAX_TMPBUF_LEN];
	int tos;

	ip_pkt = (ip_packet_t *)msg->data.data;
	printf("IP: ----- IP Header -----\n");
	printf("IP: Version        : %d\n", ip_pkt->ip_version);
	printf("IP: Header Length  : %d Bytes\n", ip_pkt->ip_hdr_len*4);
	printf("IP: Total Length   : %d Bytes\n", ntohs(ip_pkt->ip_pkt_len));
	printf("IP: Type of Service: 0x%02X\n", ip_pkt->ip_tos);
	printf("IP:      xxx. .... = 0x%02X (Precedence)\n", IPTOS_PREC(ip_pkt->ip_tos));
	tos = IPTOS_TOS(ip_pkt->ip_tos);
	if (tos ==  IPTOS_LOWDELAY)
		printf("IP:      ...1 .... = Minimize Delay\n");
	else
		printf("IP:      ...0 .... = Normal Delay\n");
	if (tos == IPTOS_THROUGHPUT)
		printf("IP:      .... 1... = Maximize Throughput\n");
	else
		printf("IP:      .... 0... = Normal Throughput\n");
	if (tos == IPTOS_RELIABILITY)
		printf("IP:      .... .1.. = Maximize Reliability\n");
	else
		printf("IP:      .... .0.. = Normal Reliability\n");
	if (tos == IPTOS_MINCOST)
		printf("IP:      .... ..1. = Minimize Cost\n");
	else
		printf("IP:      .... ..0. = Normal Cost\n");
	printf("IP: Identification : %d\n", ntohs(ip_pkt->ip_identifier));
	printf("IP: Flags          : 0x%02X\n", ((ntohs(ip_pkt->ip_frag_off) & ~IP_OFFMASK)>>13));
	if ((ntohs(ip_pkt->ip_frag_off) & IP_DF) == IP_DF)
		printf("IP:      .1.. .... = do not fragment\n");
	else
		printf("IP:      .0.. .... = can fragment\n");
	if ((ntohs(ip_pkt->ip_frag_off) & IP_MF) == IP_MF)
		printf("IP:      ..1. .... = more fragment\n");
	else
		printf("IP:      ..0. .... = last fragment\n");
	printf("IP: Fragment Offset: %d Bytes\n", (ntohs(ip_pkt->ip_frag_off) & IP_OFFMASK));
	printf("IP: Time to Live   : %d sec/hops\n", ip_pkt->ip_ttl);

	printf("IP: Protocol       : %d", ip_pkt->ip_prot);
	printf("IP: Checksum       : 0x%X\n", ntohs(ip_pkt->ip_cksum));
	printf("IP: Source         : %s", IP2Dot(tmpbuf, gNtohl((tmpbuf+20), ip_pkt->ip_src)));
	printf("IP: Destination    : %s", IP2Dot(tmpbuf, gNtohl((tmpbuf+20), ip_pkt->ip_dst)));

	return ip_pkt->ip_prot;
}
예제 #3
0
파일: message.c 프로젝트: Kbrums/gini
void printARPPacket(gpacket_t *msg)
{
	arp_packet_t *apkt;
	char tmpbuf[MAX_TMPBUF_LEN];

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

	printf(" ARP hardware addr type %x \n", ntohs(apkt->hw_addr_type));
	printf(" ARP protocol %x \n", ntohs(apkt->arp_prot));
	printf(" ARP hardware addr len %d \n", apkt->hw_addr_len);
	printf(" ARP protocol len %d \n", apkt->arp_prot_len);
	printf(" ARP opcode %x \n", ntohs(apkt->arp_opcode));
	printf(" ARP src hw addr %s \n", MAC2Colon(tmpbuf, apkt->src_hw_addr));
	printf(" ARP src ip addr %s \n", IP2Dot(tmpbuf, gNtohl((uchar *)tmpbuf, apkt->src_ip_addr)));
	printf(" ARP dst hw addr %s \n", MAC2Colon(tmpbuf, apkt->dst_hw_addr));
	printf(" ARP dst ip addr %s \n", IP2Dot(tmpbuf, gNtohl((uchar *)tmpbuf, apkt->dst_ip_addr)));
}
예제 #4
0
파일: ip.c 프로젝트: jshamash/grouter
/*
 * 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;
}
예제 #5
0
파일: ip.c 프로젝트: jshamash/grouter
/*
 * 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;
}
예제 #6
0
파일: ip.c 프로젝트: jshamash/grouter
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;
}
예제 #7
0
파일: ip.c 프로젝트: jshamash/grouter
/*
 * 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;
}
예제 #8
0
파일: arp.c 프로젝트: bernardkaminski/gini
/*
 * 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;
}
예제 #9
0
파일: ip.c 프로젝트: jshamash/grouter
/*
 * 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;
}
예제 #10
0
파일: ip.c 프로젝트: jshamash/grouter
/*
 * 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;
}
예제 #11
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;
}