void add_link_layer_address(unsigned char *ip, unsigned char *link_layer) { uint8_t i, min_time_idx = 0; uint32_t min_time; min_time = _link_layer_table[0].timestamp; for (i = 0 ; i < LINK_LAYER_CACHE_MAX_ENTRY ; ++i) { if (_link_layer_table[i].timestamp < min_time) { min_time = _link_layer_table[i].timestamp; min_time_idx = i; } if (IP_EQUAL(_link_layer_table[i].ip,ip) || IP_IS_NULL(_link_layer_table[i].ip)) { memcpy(_link_layer_table[i].link_layer, link_layer, LINK_LAYER_ADDRESS_SIZE); _link_layer_table[i].timestamp = NOW; if (IP_IS_NULL(_link_layer_table[i].ip)) { COPY_IP(_link_layer_table[i].ip,ip); } return; } } /* every entry is used, remove the oldest one */ COPY_IP(_link_layer_table[min_time_idx].ip,ip); memcpy(_link_layer_table[min_time_idx].link_layer, link_layer, LINK_LAYER_ADDRESS_SIZE); }
/* * 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 }
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; }
/* * TODO: Some form of conformance check so that only packets * destined to the particular Ethernet protocol are being captured * by the handler... right now.. this might capture other packets as well. */ void* fromEthernetDev(void *arg) { interface_t *iface = (interface_t *) arg; interface_array_t *iarr = (interface_array_t *)iface->iarray; uchar bcast_mac[] = MAC_BCAST_ADDR; gpacket_t *in_pkt; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // die as soon as cancelled while (1) { //printf("In fromEthernet Dev\n"); verbose(2, "[fromEthernetDev]:: Receiving a packet ..."); if ((in_pkt = (gpacket_t *)malloc(sizeof(gpacket_t))) == NULL) { fatal("[fromEthernetDev]:: unable to allocate memory for packet.. "); return NULL; } bzero(in_pkt, sizeof(gpacket_t)); vpl_recvfrom(iface->vpl_data, &(in_pkt->data), sizeof(pkt_data_t)); pthread_testcancel(); // 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)) { ip_packet_t *ip_pkt = (ip_packet_t *)in_pkt->data.data; if( ip_pkt->ip_prot == OSPF_PROTOCOL ){ } else{ //stub verification StubVerify( in_pkt, iface ); verbose(2, "[fromEthernetDev]:: SPacket dropped .. not for this router!? "); 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); // check for filtering.. if the it should be filtered.. then drop if (filteredPacket(filter, in_pkt)) { verbose(2, "[fromEthernetDev]:: Packet filtered..!"); free(in_pkt); continue; // skip the rest of the loop } verbose(2, "[fromEthernetDev]:: Packet is sent for enqueuing.."); enqueuePacket(pcore, in_pkt, sizeof(gpacket_t)); } }
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)); } }
void putARPCache(uchar *ip_addr, uchar *mac_addr) { int key; key = getARPCacheKey(ip_addr); arp_cache[key].is_empty = FALSE; COPY_IP(arp_cache[key].ip_addr, ip_addr); COPY_MAC(arp_cache[key].mac_addr, mac_addr); }
/* * 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; }
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; }
vpl_data_t *tun_connect(short int src_port, uchar* src_IP, short int dst_port, uchar* dst_IP) { int fd; int dst_ip; verbose(2, "[tun_connect]:: starting connection.. "); vpl_data_t *pri = (vpl_data_t *)malloc(sizeof(vpl_data_t)); bzero(pri, sizeof(sizeof(vpl_data_t))); COPY_IP(&dst_ip, dst_IP); // initialize the vpl_data structure.. much of it is unused here. // we are reusing vpl_data_t to minimize the changes for other code. pri->sock_type = "tun"; pri->ctl_sock = NULL; pri->ctl_addr = NULL; pri->data_addr = NULL; pri->local_addr = NULL; pri->data = -1; pri->control = -1; fd = socket(AF_INET,SOCK_DGRAM,0); if (fd == -1) { verbose(2, "[tun_connect]:: Creating UDP socket failed, error = %s", strerror(errno)); return NULL; } struct sockaddr_in* srcaddr = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in)); bzero(srcaddr,sizeof(*srcaddr)); srcaddr->sin_family = AF_INET; //srcaddr->sin_addr.s_addr=inet_addr(src_IP); Ahmed fix srcaddr->sin_addr.s_addr = htonl(INADDR_ANY); srcaddr->sin_port=htons(src_port); if(bind(fd,(struct sockaddr *)srcaddr,sizeof(*srcaddr))== -1) { verbose(2, "[tun_connect]:: Binding UDP Socket Failed, error = %s", strerror(errno)); free(srcaddr); return NULL; } struct sockaddr_in* dstaddr = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in)); bzero(dstaddr,sizeof(*dstaddr)); dstaddr->sin_family = AF_INET; dstaddr->sin_addr.s_addr=htonl(dst_ip); verbose(2, "destination IP = %s\n", inet_ntoa(dstaddr->sin_addr)); dstaddr->sin_port=htons(dst_port); pri->data = fd; pri->local_addr = (void*)srcaddr; pri->data_addr = (void*)dstaddr; return pri; }
void* fromTunDev(void *arg) { interface_t *iface = (interface_t *) arg; interface_array_t *iarr = (interface_array_t *)iface->iarray; 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, "[fromTunDev]:: Receiving a packet ..."); if ((in_pkt = (gpacket_t *)malloc(sizeof(gpacket_t))) == NULL) { fatal("[fromTunDev]:: unable to allocate memory for packet.. "); return NULL; } bzero(in_pkt, sizeof(gpacket_t)); pktsize = tun_recvfrom(iface->vpl_data, &(in_pkt->data), sizeof(pkt_data_t)); pthread_testcancel(); verbose(2, "[fromTunDev]:: Destination MAC is %s ", MAC2Colon(tmpbuf, in_pkt->data.header.dst)); if ((COMPARE_MAC(in_pkt->data.header.dst, iface->mac_addr) != 0) && (COMPARE_MAC(in_pkt->data.header.dst, bcast_mac) != 0)) { verbose(1, "[fromTunDev]:: 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); // check for filtering.. if the it should be filtered.. then drop if (filteredPacket(filter, in_pkt)) { verbose(2, "[fromTunDev]:: Packet filtered..!"); free(in_pkt); continue; // skip the rest of the loop } verbose(2, "[fromTunDev]:: Packet is sent for enqueuing.."); enqueuePacket(pcore, in_pkt, sizeof(gpacket_t)); } }
/* * 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; }
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; }
/* * Create an interface data structure and fill it with relevant information. * This routine does not setup any external elements.. other than finding * the device driver and linking it. We need the correct device driver for * the interface.. because a particular device would provide its own I/O routines. */ interface_t *newInterfaceStructure(char *vsock_name, char *device, uchar *mac_addr, uchar *nw_addr, int iface_mtu) { int iface_id; interface_t *iface; iface_id = gAtoi(device); // fill in the interface structure... iface = (interface_t *) malloc(sizeof(interface_t)); if (iface == NULL) { fatal("[createInterfaceStructure]:: Memory allocation error "); return NULL; } verbose(2, "[createInterfaceStructure]:: Memory allocated for interface structure "); bzero((void *)iface, sizeof(interface_t)); iface->interface_id = iface_id; iface->mode = IFACE_CLIENT_MODE; iface->state = INTERFACE_DOWN; // start in the DOWN state sscanf(device, "%[a-z]", iface->device_type); strcpy(iface->device_name, device); strcpy(iface->sock_name, vsock_name); COPY_MAC(iface->mac_addr, mac_addr); COPY_IP(iface->ip_addr, nw_addr); iface->device_mtu = iface_mtu; verbose(2, "[makeInterface]:: Searching the device driver for %s ", iface->device_type); iface->devdriver = findDeviceDriver(iface->device_type); iface->iarray = &netarray; return iface; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * TODO: Can we do these without super user permissions? */ void* fromTapDev(void *arg) { interface_t *iface = (interface_t *) arg; interface_array_t *iarr = (interface_array_t *)iface->iarray; uchar bcast_mac[] = MAC_BCAST_ADDR; char *pkttag; gpacket_t *in_pkt; int pktsize; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // die as soon as cancelled while (1) { verbose(2, "[fromTapDev]:: Receiving a packet ..."); if ((in_pkt = (gpacket_t *)malloc(sizeof(gpacket_t))) == NULL) { fatal("[fromTapDev]:: unable to allocate memory for packet.. "); return NULL; } bzero(in_pkt, sizeof(gpacket_t)); pktsize = tap_recvfrom(iface->vpl_data, &(in_pkt->data), sizeof(pkt_data_t)); pthread_testcancel(); // 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(1, "[fromTapDev]:: 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); // check for filtering.. if the it should be filtered.. then drop if (filteredPacket(filter, in_pkt)) { verbose(2, "[fromTapDev]:: Packet filtered..!"); free(in_pkt); continue; // skip the rest of the loop } // invoke the packet core classifier to get the packet tag // at the very minimum, we get the "default" tag! verbose(2, "[fromTapDev]:: Calling the classifier.."); pkttag = tagPacket(pcore, in_pkt); verbose(2, "[fromTapDev]:: Packet tagged as %s ", pkttag); if (!strcmp(rconfig.schedpolicy, "rr")) roundRobinQueuer(pcore, in_pkt, sizeof(gpacket_t), pkttag); else if (!strcmp(rconfig.schedpolicy, "wfq")) weightedFairQueuer(pcore, in_pkt, sizeof(gpacket_t), pkttag); else fatal("[fromTapDev]:: Unknown queuer specification! %s \n", rconfig.schedpolicy); } }
/* * 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; }
/* * TODO: Some form of conformance check so that only packets * destined to the particular Ethernet protocol are being captured * by the handler... right now.. this might capture other packets as well. */ void* fromEthernetDev(void *arg) { interface_t *iface = (interface_t *) arg; interface_array_t *iarr = (interface_array_t *)iface->iarray; uchar bcast_mac[] = MAC_BCAST_ADDR; gpacket_t *in_pkt; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // die as soon as cancelled while (1) { verbose(2, "[fromEthernetDev]:: Receiving a packet ..."); if ((in_pkt = (gpacket_t *)malloc(sizeof(gpacket_t))) == NULL) { fatal("[fromEthernetDev]:: unable to allocate memory for packet.. "); return NULL; } bzero(in_pkt, sizeof(gpacket_t)); vpl_recvfrom(iface->vpl_data, &(in_pkt->data), sizeof(pkt_data_t)); pthread_testcancel(); // 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(1, "[fromEthernetDev]:: Packet dropped .. not for this router!? "); 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); //Printing packet values /* printf("\n=========== INCOMING PACKET VALUES ================\n"); printf("\n----------HEADER VALUES :"); printf("\nSource MAC Address: %x : %x : %x : %x : %x : %x", in_pkt->data.header.src[0], in_pkt->data.header.src[1],in_pkt->data.header.src[2], in_pkt->data.header.src[3],in_pkt->data.header.src[4],in_pkt->data.header.src[5]); printf("\nDestination MAC Address: %x : %x : %x : %x : %x : %x", in_pkt->data.header.dst[0], in_pkt->data.header.dst[1],in_pkt->data.header.dst[2], in_pkt->data.header.dst[3],in_pkt->data.header.dst[4],in_pkt->data.header.dst[5]); printf("\nSource IP Address: %d.%d.%d.%d", in_pkt->frame.src_ip_addr[0], in_pkt->frame.src_ip_addr[1],in_pkt->frame.src_ip_addr[2], in_pkt->frame.src_ip_addr[3]); printf("\nProtocol is : %d",in_pkt->data.header.prot); printf("\nDestination Interface is : %d",in_pkt->frame.dst_interface); printf("\nIngress Port is : %d",in_pkt->frame.src_interface); printf("\nNXTH IP Destination: %d.%d.%d.%d", in_pkt->frame.nxth_ip_addr[0],in_pkt->frame.nxth_ip_addr[1], in_pkt->frame.nxth_ip_addr[2],in_pkt->frame.nxth_ip_addr[3]); printf("\n --- IP PACKET:"); ip_packet_t *ip_pkt; ip_pkt = (ip_packet_t *) in_pkt->data.data; 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);*/ // check for filtering.. if the it should be filtered.. then drop if (filteredPacket(filter, in_pkt)) { verbose(2, "[fromEthernetDev]:: Packet filtered..!"); free(in_pkt); continue; // skip the rest of the loop } verbose(2, "[fromEthernetDev]:: Packet is sent for enqueuing.."); //ENQUEUE PACKET TO QUEUE_1 if (in_pkt->data.header.prot == htons(ARP_PROTOCOL)) { ARPProcess(in_pkt); } else{ /* if(in_pkt->frame.src_interface == 1){ printf("\n RECEIVED PACKET FROM INTERFACE 1"); in_pkt->frame.dst_interface = 2; // HATA DO MUJHE in_pkt->data.header.src[0] = in_pkt->data.header.dst[0]; in_pkt->data.header.src[1] = in_pkt->data.header.dst[1]; in_pkt->data.header.src[2] = in_pkt->data.header.dst[2]; in_pkt->data.header.src[3] = in_pkt->data.header.dst[3]; in_pkt->data.header.src[4] = in_pkt->data.header.dst[4]; in_pkt->data.header.src[5] = in_pkt->data.header.dst[5]; in_pkt->data.header.dst[0] = 254; in_pkt->data.header.dst[1] = 253; in_pkt->data.header.dst[2] = 2; in_pkt->data.header.dst[3] = 0; in_pkt->data.header.dst[4] = 0; in_pkt->data.header.dst[5] = 1; in_pkt->data.header.src[0] = 254; in_pkt->data.header.src[1] = 253; in_pkt->data.header.src[2] = 3; in_pkt->data.header.src[3] = 01; in_pkt->data.header.src[4] = 0; in_pkt->data.header.src[5] = 2; } else if(in_pkt->frame.src_interface == 2){ printf("\n RECEIVED PACKET FROM INTERFACE 2"); in_pkt->frame.dst_interface = 1; in_pkt->data.header.src[0] = in_pkt->data.header.dst[0]; in_pkt->data.header.src[1] = in_pkt->data.header.dst[1]; in_pkt->data.header.src[2] = in_pkt->data.header.dst[2]; in_pkt->data.header.src[3] = in_pkt->data.header.dst[3]; in_pkt->data.header.src[4] = in_pkt->data.header.dst[4]; in_pkt->data.header.src[5] = in_pkt->data.header.dst[5]; in_pkt->data.header.dst[0] = 254; in_pkt->data.header.dst[1] = 253; in_pkt->data.header.dst[2] = 2; in_pkt->data.header.dst[3] = 0; in_pkt->data.header.dst[4] = 0; in_pkt->data.header.dst[5] = 2; in_pkt->data.header.src[0] = 254; in_pkt->data.header.src[1] = 253; in_pkt->data.header.src[2] = 03; in_pkt->data.header.src[3] = 01; in_pkt->data.header.src[4] = 0; in_pkt->data.header.src[5] = 1; }*/ writeQueue(queue1, (void *)in_pkt, sizeof(gpacket_t)); } } }
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; }
/* * TODO: Some form of conformance check so that only packets * destined to the particular Ethernet protocol are being captured * by the handler... right now.. this might capture other packets as well. */ void* fromEthernetDev(void *arg) { interface_t *iface = (interface_t *) arg; interface_array_t *iarr = (interface_array_t *)iface->iarray; uchar bcast_mac[] = MAC_BCAST_ADDR; gpacket_t *in_pkt; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // die as soon as cancelled while (1) { verbose(2, "[fromEthernetDev]:: Receiving a packet ..."); if ((in_pkt = (gpacket_t *)malloc(sizeof(gpacket_t))) == NULL) { fatal("[fromEthernetDev]:: unable to allocate memory for packet.. "); return NULL; } bzero(in_pkt, sizeof(gpacket_t)); vpl_recvfrom(iface->vpl_data, &(in_pkt->data), sizeof(pkt_data_t)); pthread_testcancel(); //FOR OSPF /* char tmpbuf[MAX_TMPBUF_LEN]; uchar valMac1[6]; uchar valMac2[6]; uchar valMac3[6]; char *test1 = "33:33:00:00:00:16"; char *test2 = "33:33:00:00:00:02"; char *test3 = "33:33:ff:00:00:04"; Colon2MAC(test1, valMac1); Colon2MAC(test2, valMac2); Colon2MAC(test3, valMac3); if(COMPARE_MAC(in_pkt->data.header.dst, valMac1) == 0 || COMPARE_MAC(in_pkt->data.header.dst, valMac2) == 0|| COMPARE_MAC(in_pkt->data.header.dst, valMac3) == 0){ uchar link_ip[4]; COPY_IP(link_ip, iface->ip_addr); link_ip[0] = IP_ZERO_PREFIX; printf("Received IPV6 ICMP bcast from : %s \n", IP2Dot(tmpbuf, link_ip)); //Then we know that this packet comes from a stub network //Set stub bit in neighbour table to true //printGPacket(in_pkt, 3, "IP_ROUTINE"); int index = findNeighbourIndex(link_ip); if(index == -1) { // Add to neighbour table addNeighbourEntry(iface->ip_addr, link_ip, iface->interface_id); // Add to graph addStubToGraph(findNeighbourIndex(link_ip)); updateRoutingTable(); //printf("BCASTING my new stub neighbour\n"); //bcast this change OSPFSendLSA(); } setStubToTrueFlag(link_ip); } */ // 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(1, "[fromEthernetDev]:: Packet dropped .. not for this router!? "); 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); //calculate Input rate if(start == 1){ counter_in = counter_in+sizeof(gpacket_t); } // check for filtering.. if the it should be filtered.. then drop if (filteredPacket(filter, in_pkt)) { verbose(2, "[fromEthernetDev]:: Packet filtered..!"); free(in_pkt); continue; // skip the rest of the loop } verbose(2, "[fromEthernetDev]:: Packet is sent for enqueuing.."); enqueuePacket(pcore, in_pkt, sizeof(gpacket_t)); } }