int printEthernetHeader(gpacket_t *msg) { char tmpbuf[MAX_TMPBUF_LEN]; int prot; printf("\n P A C K E T D A T A S E C T I O N of GMESSAGE \n"); printf(" DST MAC addr : \t %s\n", MAC2Colon(tmpbuf, msg->data.header.dst)); printf(" SRC MAC addr : \t %s\n", MAC2Colon(tmpbuf, msg->data.header.src)); prot = ntohs(msg->data.header.prot); printf(" Protocol : \t %x\n", prot); return prot; }
/* * ARPResolve: this routine is responsible for local ARP resolution. * It consults the local ARP cache to determine whether a valid ARP entry * is present. If a valid entry is not present, a remote request is sent out * and the packet that caused the request is buffered. The buffer is flushed * when the reply comes in. */ int ARPResolve(gpacket_t *in_pkt) { printf("CONNORS DEBUG: ARPResolve\n"); uchar mac_addr[6]; char tmpbuf[MAX_TMPBUF_LEN]; in_pkt->data.header.prot = htons(IP_PROTOCOL); // lookup the ARP table for the MAC for next hop if (ARPFindEntry(in_pkt->frame.nxth_ip_addr, mac_addr) == EXIT_FAILURE) { // no ARP match, buffer and send ARP request for next verbose(2, "[ARPResolve]:: buffering packet, sending ARP request"); ARPAddBuffer(in_pkt); in_pkt->frame.arp_bcast = TRUE; // tell gnet this is bcast to prevent recursive ARP lookup! // create a new message for ARP request ARPSendRequest(in_pkt); return EXIT_SUCCESS;; } verbose(2, "[ARPResolve]:: sent packet to MAC %s", MAC2Colon(tmpbuf, mac_addr)); COPY_MAC(in_pkt->data.header.dst, mac_addr); in_pkt->frame.arp_valid = TRUE; ARPSend2Output(in_pkt); return EXIT_SUCCESS; }
/* * Receive a packet from the vpl. You can use this with a "select" * function to multiplex between different interfaces or you can use * it in a multi-processed/multi-threaded server. The example code * given here should work in either mode. */ int tun_recvfrom(vpl_data_t *vpl, void *buf, int len) { int n, rcv_addr_len; struct sockaddr_in* dstaddr = (struct sockaddr_in*)vpl->data_addr; struct sockaddr_in rcvaddr; char tmpbuf[100]; rcv_addr_len = sizeof(rcvaddr); n=recvfrom(vpl->data,buf,len,0,(struct sockaddr *)&rcvaddr,&rcv_addr_len); if (n == -1) { verbose(2, "[tun_recvfrom]:: unable to receive packet, error = %s", strerror(errno)); return EXIT_FAILURE; } else if((rcvaddr.sin_addr.s_addr != dstaddr->sin_addr.s_addr) || rcvaddr.sin_port != dstaddr->sin_port) { verbose(2, "[tun_recvfrom]:: source IP or port does not match interface router"); return EXIT_FAILURE; } verbose(2, "[tun_recvfrom]:: Destination MAC is %s ", MAC2Colon(tmpbuf, buf)); //copy2Queue(consoleq, buf, len); Ahmed: is this necessary? return EXIT_SUCCESS; }
/* * list Interfaces: list all active interfaces... */ void printInterfaces(int mode) { int i; interface_t *ifptr; char tmpbuf[MAX_TMPBUF_LEN]; printf("\n\n"); printHorLine(mode); printf(" I N T E R F A C E T A B L E \n"); printHorLine(mode); switch (mode) { case NORMAL_LISTING: printf("Device\tState\tIP address\tMAC address\t\tMTU\n"); break; case VERBOSE_LISTING: printf("Int.\tState/Mode\tDevice\tIP address\tMAC address\t\tMTU\tSocket Name\tThread ID\n"); break; } for (i = 0; i < MAX_INTERFACES; i++) if (netarray.elem[i] != NULL) { ifptr = netarray.elem[i]; switch (mode) { case NORMAL_LISTING: printf("%s\t%c\t%s\t%s\t%d\n", ifptr->device_name, ifptr->state, IP2Dot(tmpbuf, ifptr->ip_addr), MAC2Colon((tmpbuf+20), ifptr->mac_addr), ifptr->device_mtu); break; case VERBOSE_LISTING: printf("%d\t%c%c\t\t%s\t%s\t%s\t%d\t%s\t%d\n", ifptr->interface_id, ifptr->state, ifptr->mode, ifptr->device_name, IP2Dot(tmpbuf, ifptr->ip_addr), MAC2Colon((tmpbuf+20), ifptr->mac_addr), ifptr->device_mtu, ifptr->sock_name, (int) ifptr->threadid); break; } } printHorLine(mode); printf("\n\n"); return; }
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))); }
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 printGPktFrame(gpacket_t *msg, char *routine) { char tmpbuf[MAX_TMPBUF_LEN]; printf("\n P A C K E T F R A M E S E C T I O N of GPACKET @ %s \n", routine); printf(" SRC interface : \t %d\n", msg->frame.src_interface); printf(" SRC IP addr : \t %s\n", IP2Dot(tmpbuf, msg->frame.src_ip_addr)); printf(" SRC HW addr : \t %s\n", MAC2Colon(tmpbuf, msg->frame.src_hw_addr)); printf(" DST interface : \t %d\n", msg->frame.dst_interface); printf(" NEXT HOP addr : \t %s\n", IP2Dot(tmpbuf, msg->frame.nxth_ip_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* 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)); } }
/* * print the ARP table */ void ARPPrintTable(void) { int i; char tmpbuf[MAX_TMPBUF_LEN]; printf("-----------------------------------------------------------\n"); printf(" A R P T A B L E \n"); printf("-----------------------------------------------------------\n"); printf("Index\tIP address\tMAC address \n"); for (i = 0; i < MAX_ARP; i++) if (ARPtable[i].is_empty == FALSE) printf("%d\t%s\t%s\n", i, IP2Dot(tmpbuf, ARPtable[i].ip_addr), MAC2Colon((tmpbuf+20), ARPtable[i].mac_addr)); printf("-----------------------------------------------------------\n"); return; }
/* * Receive a packet from the vpl. You can use this with a "select" * function to multiplex between different interfaces or you can use * it in a multi-processed/multi-threaded server. The example code * given here should work in either mode. */ int raw_recvfrom(vpl_data_t *vpl, void *buf, int len) { int n, rcv_addr_len; struct sockaddr rcvaddr; char tmpbuf[100]; rcv_addr_len = sizeof(rcvaddr); n=recvfrom(vpl->data, buf, len, 0, &rcvaddr, &rcv_addr_len); if (n == -1) { verbose(2, "[raw_recvfrom]:: unable to receive packet, error = %s", strerror(errno)); return EXIT_FAILURE; } verbose(2, "[raw_recvfrom]:: Destination MAC is %s ", MAC2Colon(tmpbuf, buf)); return EXIT_SUCCESS; }
void printARPCache(void) { int i; char tmpbuf[MAX_TMPBUF_LEN]; printf("\n-----------------------------------------------------------\n"); printf(" A R P C A C H E \n"); printf("-----------------------------------------------------------\n"); printf("Index\tIP address\tMAC address \n"); for (i = 0; i < MAX_ARP; i++) if (arp_cache[i].is_empty == FALSE) printf("%d\t%s\t%s\n", i, IP2Dot(tmpbuf, arp_cache[i].ip_addr), MAC2Colon((tmpbuf+20), arp_cache[i].mac_addr)); printf("-----------------------------------------------------------\n"); return; }
interface_t *GNETMakeTapInterface(char *device, uchar *mac_addr, uchar *nw_addr) { vpl_data_t *vcon; interface_t *iface; int iface_id; char tmpbuf[MAX_TMPBUF_LEN]; verbose(2, "[GNETMakeTapInterface]:: making Interface for [%s] with MAC %s and IP %s", device, MAC2Colon(tmpbuf, mac_addr), IP2Dot((tmpbuf+20), nw_addr)); iface_id = gAtoi(device); if (findInterface(iface_id) != NULL) { verbose(1, "[GNETMakeTapInterface]:: device %s already defined.. ", device); return NULL; } else { // setup the interface.. with default MTU of 1500 we cannot set it at this time. iface = newInterfaceStructure(device, device, mac_addr, nw_addr, 1500); /* * try connection (as client). only option here... */ verbose(2, "[GNETMakeTapInterface]:: trying to connect to %s..", device); if ((vcon = tap_connect(device)) == NULL) { verbose(1, "[GNETMakeTapInterface]:: unable to connect to %s", device); return NULL; } // fill in the rest of the interface iface->iface_fd = vcon->data; iface->vpl_data = vcon; upThisInterface(iface); return iface; } }
/* * ARGUMENTS: device: e.g. tun2 * mac_addr: hardware address of the interface * nw_addr: network address of the interface (IPv4 by default) * dst_ip: physical IP address of destination mesh station on the MBSS * dst_port: interface number of the destination interface on the destination yRouter * RETURNS: a pointer to the interface on success and NULL on failure */ interface_t *GNETMakeTunInterface(char *device, uchar *mac_addr, uchar *nw_addr, uchar* dst_ip, short int dst_port) { vpl_data_t *vcon; interface_t *iface; int iface_id; char tmpbuf[MAX_TMPBUF_LEN]; verbose(2, "[GNETMakeTunInterface]:: making Interface for [%s] with MAC %s and IP %s", device, MAC2Colon(tmpbuf, mac_addr), IP2Dot((tmpbuf+20), nw_addr)); iface_id = gAtoi(device); if (findInterface(iface_id) != NULL) { verbose(1, "[GNETMakeTunInterface]:: device %s already defined.. ", device); return NULL; } // setup the interface.. iface = newInterfaceStructure(device, device, mac_addr, nw_addr, MAX_MTU); verbose(2, "[GNETMakeTunInterface]:: trying to connect to %s..", device); vcon = tun_connect((short int)(BASEPORTNUM+iface_id+gAtoi(rconfig.router_name)*100), NULL, (short int)(BASEPORTNUM+dst_port+gAtoi(rconfig.router_name)*100), dst_ip); if(vcon == NULL) { verbose(1, "[GNETMakeTunInterface]:: unable to connect to %s", device); return NULL; } iface->iface_fd = vcon->data; iface->vpl_data = vcon; upThisInterface(iface); return iface; }
interface_t *GNETMakeEthInterface(char *vsock_name, char *device, uchar *mac_addr, uchar *nw_addr, int iface_mtu, int cforce) { vpl_data_t *vcon; interface_t *iface; int iface_id, thread_stat; char tmpbuf[MAX_TMPBUF_LEN]; vplinfo_t *vi; pthread_t threadid; verbose(2, "[GNETMakeEthInterface]:: making Interface for [%s] with MAC %s and IP %s", device, MAC2Colon(tmpbuf, mac_addr), IP2Dot((tmpbuf+20), nw_addr)); iface_id = gAtoi(device); if (findInterface(iface_id) != NULL) { verbose(1, "[GNETMakeEthInterface]:: device %s already defined.. ", device); return NULL; } else { // setup the interface.. iface = newInterfaceStructure(vsock_name, device, mac_addr, nw_addr, iface_mtu); /* * try connection (as client). if it fails and force client flag * is set, then return NULL. Otherwise, try server connection, * if this fails, print error and return NULL */ verbose(2, "[GNETMakeEthInterface]:: trying to connect to %s..", vsock_name); if ((vcon = vpl_connect(vsock_name)) == NULL) { verbose(2, "[GNETMakeEthInterface]:: connecting as server.. "); // if client mode is forced.. fail here.. cannot do much! if (cforce) { verbose(1, "[GNETMakeEthInterface]:: unable to make network connection..."); return NULL; } // try making a server connection... // now that the client connection has failed if ((vcon = vpl_create_server(vsock_name)) == NULL) { verbose(1, "[GNETMakeEthInterface]:: unable to make server connection.. "); return NULL; } vi = (vplinfo_t *)malloc(sizeof(vplinfo_t)); iface->mode = IFACE_SERVER_MODE; vi->vdata = vcon; vi->iface = iface; thread_stat = pthread_create(&(iface->sdwthread), NULL, (void *)delayedServerCall, (void *)vi); if (thread_stat != 0) return NULL; // return for now.. the thread spawned above will change the // interface state when the remote node makes the connection. return iface; } verbose(2, "[GNETMakeEthInterface]:: VPL connection made as client "); // fill in the rest of the interface iface->iface_fd = vcon->data; iface->vpl_data = vcon; upThisInterface(iface); return iface; } }