Esempio n. 1
0
/*
 * Checks if two IP addresses are on the same network
 * returns: EXIT_FAILURE if not and EXIT_SUCCESS if they are
 */
int isInSameNetwork(uchar *ip_addr1, uchar *ip_addr2)
{
	char tmpbuf[MAX_TMPBUF_LEN];
	int i, j;
	uchar net1[4], net2[4];

	for (i = 0; i < MAX_ROUTES; i++)
	{
		if (route_tbl[i].is_empty == TRUE) continue;
		// TODO: Could there be a bug here? What about default routes with 0.0.0.0??
		for (j = 0; j < 4; j++)
		{
			net1[j] = ip_addr1[j] & route_tbl[i].netmask[j];
			net2[j] = ip_addr2[j] & route_tbl[i].netmask[j];
		}
		if (COMPARE_IP(net1, net2) == 0)
		{
			verbose(2, "[isInSameNetwork]:: IPs %s and %s are on the same network %s",
			       IP2Dot(tmpbuf, ip_addr1), IP2Dot((tmpbuf+20), ip_addr2), IP2Dot((tmpbuf+40), route_tbl[i].network));

			return EXIT_SUCCESS;
		}
	}

	verbose(2, "[isInSameNetwork]:: IPs %s and %s are not on the same network",
	       IP2Dot(tmpbuf, ip_addr1), IP2Dot((tmpbuf+20), ip_addr2));

	return EXIT_FAILURE;
}
Esempio n. 2
0
/*
 * 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);
	}
}
Esempio n. 3
0
/* Returns 1 if one of the interfaces has the given IP */
int hasInterface(uchar *ip) {
	uchar interfaces[MAX_INTERFACES][4];
	int numInterfaces = getInterfaces(interfaces);
	int i;
	for (i = 0; i < numInterfaces; i++) {
		if (!COMPARE_IP(interfaces[i], ip)) return 1;
	}
	return 0;
}
Esempio n. 4
0
File: gnet.c Progetto: draringi/gini
/*
 * lookup the given ip_addr in the ARP cache.
 * copy the MAC address in mac_addr and return TRUE
 * otherwise return FALSE -- mac_addr is undefined in this case.
 */
int lookupARPCache(uchar *ip_addr, uchar *mac_addr)
{
	int key;

	key = getARPCacheKey(ip_addr);
	if ((arp_cache[key].is_empty == FALSE) &&
	    (COMPARE_IP(arp_cache[key].ip_addr, ip_addr) == 0))
	{
		COPY_MAC(mac_addr, arp_cache[key].mac_addr);
		return TRUE;
	}

	return FALSE;
}
Esempio n. 5
0
/*
 * Delete ARP entry with the given IP address
 */
void ARPDeleteEntry(char *ip_addr)
{
	int i;

	for (i = 0; i < MAX_ARP; i++)
	{
		if ( (ARPtable[i].is_empty == FALSE) &&
		     (COMPARE_IP(ARPtable[i].ip_addr, ip_addr)) == 0)
		{
			ARPtable[i].is_empty = TRUE;
			verbose(2, "[ARPDeleteEntry]:: arp entry #%d deleted", i);
		}
	}
	return;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
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;
}
Esempio n. 11
0
int process_rx_packet(uint8_t *pu8Packet, uint32_t u32Len)
{
    ARP_PACKET    *arp = (ARP_PACKET *)pu8Packet;
    IP_PACKET    *ip  = (IP_PACKET *)pu8Packet;
    UDP_PACKET    *udp  = (UDP_PACKET *)pu8Packet;

    if (pu8Packet[0] == 0xFF) {     /* this is a broadcast packet */
        /*
         *  We manage the ARP reply process here.
         *  In the following code, if we have received a ARP request,
         *  we send ARP reply immediately.
         */
        if ((!COMPARE_IP(arp->au8TargetIP, g_au8IpAddr)) &&
                (arp->u16Type == SWAP16(PROTOCOL_ARP)) && (arp->u16Operation == SWAP16(ARP_REQUEST))) {
            arp_reply(arp->su8SenderIP, arp->au8SenderHA);
        }

        return 0;
    } else {                    /* this is a multicast or unicast packet */
        /*
         *  This is a unicast packet to us.
         */
        if ((ip->u8Prot == IP_PRO_TCP) && (!COMPARE_IP(ip->au8DestIP, g_au8IpAddr))) {
            // write me: process TCP packets here
            return 0;
        }

        if ((ip->u8Prot == IP_PRO_UDP) && (udp->u16SrcPort == SWAP16(67))) {
            // This is a DHCP packet...

            s_u32PktRdy = u32Len;
            memcpy(au8RxBuf, pu8Packet, u32Len);
            return 0;
        }

        if ((ip->u8Prot == IP_PRO_UDP) && (!COMPARE_IP(ip->au8DestIP, g_au8IpAddr))) {
            // write me: process UDP packets here
            return 0;
        }

        /*
         * Check ICMP Echo Request packet -
         * if matched, we reply it right here
         */
        if ((ip->u8Prot == IP_PRO_ICMP) && (!COMPARE_IP(ip->au8DestIP, g_au8IpAddr)) &&
                (pu8Packet[34] == 0x08)) {
            IP_PACKET    *tx_ip;


            /* duplicate packet then modify it */
            memcpy((char *)&au8TxBuf[0], (char *)&pu8Packet[0], u32Len);


            tx_ip = (IP_PACKET *)&au8TxBuf[0];
            memcpy((char *)tx_ip->au8DestMac, (char *)ip->au8SrcMac, 6);
            memcpy((char *)tx_ip->au8SrcMac, (char *)g_au8MacAddr, 6);
            tx_ip->u16Type = SWAP16(PROTOCOL_IP);
            tx_ip->u8VerHLen = 0x45;         /* fixed value, do not change it */
            tx_ip->u8ToS = 0;                /* no special priority */
            tx_ip->u16TLen = SWAP16(60);
            tx_ip->u16ID = SWAP16(s_u16IpPacketId);
            tx_ip->u16Frag = 0;
            tx_ip->u8TTL = 64;
            tx_ip->u8Prot = IP_PRO_ICMP;
            tx_ip->u16HdrChksum = 0;
            memcpy((char *)tx_ip->au8SrcIP, (char *)g_au8IpAddr, 4);
            memcpy((char *)tx_ip->au8DestIP, (char *)ip->au8SrcIP, 4);
            tx_ip->u16HdrChksum = ~chksum((uint16_t *)&tx_ip->u8VerHLen, 10);  /* 20 bytes */

            s_u16IpPacketId++;

            /* ICMP reply */
            au8TxBuf[34] = 0;

            /* ICMP checksum */
            au8TxBuf[36] = 0;
            au8TxBuf[37] = 0;
            *(uint16_t *)&au8TxBuf[36] = ~chksum((uint16_t *)&au8TxBuf[34], (u32Len - 34) / 2);

            EMAC_SendPkt(au8TxBuf, u32Len);

            return 0;
        }
    }

    return 0;
}
Esempio n. 12
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;
}