/* * 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 }
/* * Add a packet to ARP buffer: This packet is waiting resolution * ARGUMENTS: in_pkt - pointer to message that is to be copied into buffer * RETURNS: none */ void ARPAddBuffer(gpacket_t *in_pkt) { int i; gpacket_t *cppkt; // duplicate the packet.. cppkt = duplicatePacket(in_pkt); // Find an empty slot for (i = 0; i < MAX_ARP_BUFFERS; i++){ if (ARPbuffer[i].is_empty == TRUE) { ARPbuffer[i].is_empty = FALSE; ARPbuffer[i].wait_msg = cppkt; verbose(2, "[addARPBuffer]:: packet stored in entry %d", i); return; } } // No empty spot? Replace a packet, we need to deallocate the old packet free(ARPbuffer[i].wait_msg); ARPbuffer[i].wait_msg = cppkt; verbose(2, "[addARPBuffer]:: buffer full, packet buffered to replaced entry %d", buf_replace_indx); buf_replace_indx = (buf_replace_indx + 1) % MAX_ARP_BUFFERS; // adjust for FIFO return; }
/* * 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; }