#include #include "icrp.h" //#include // added for syscall //_syscall2(int, add_routable_node, unsigned int, arg1, int, arg2); /* Note that there is no notion of routing differently in different stages. * all the states should be transparent to this layer */ extern class ICRP icrp; int ROUTER::orphanRouting(EVENT event) { char *pkt = machine->getPacketFrmDDCA(); //get the recent most packet from ddca //the packet that invoked us //process a query that came to us struct ddca_header *dh = (struct ddca_header *)(pkt + sizeof(struct ip)); struct query_body * qb = (struct query_body *)(pkt + sizeof(struct ip) + sizeof(struct ddca_header)); icrp.processQuery(dh, qb); cout <<"Entering the orphanRouting function " << endl; return 1; } int ROUTER::unclusteredRouting(EVENT event) { /* //no point in getting a routing packet from DDCA, it will be discarded char *pkt = machine->getPacketFrmDDCA(); //get the recent most packet from ddca //the packet that invoked us //unclustered state can not process queries //process a query that came to us struct ddca_header *dh = (struct ddca_header *)(pkt + sizeof(struct ip)); struct query_body * qb = (struct query_body *)(pkt + sizeof(struct ip) + sizeof(struct ddca_header)); icrp.processQuery(dh, qb); */ cout <<"Entering the unclusteredRouting function " << endl; return 1; } int ROUTER::childRouting(EVENT event) { char *pkt = machine->getPacketFrmDDCA(); //get the recent most packet from ddca //the packet that invoked us /* switch (event) { case RCV_HELLO_MSG: // do some work cerr << "** Received hello message **\n"; break; } */ //process a query that came to us struct ddca_header *dh = (struct ddca_header *)(pkt + sizeof(struct ip)); struct query_body * qb = (struct query_body *)(pkt + sizeof(struct ip) + sizeof(struct ddca_header)); icrp.processQuery(dh, qb); cout <<"Entering the childRouting function " << endl; cout << "with event = "<< event << endl; return 1; } int ROUTER::parentRouting(EVENT event) { char *pkt = machine->getPacketFrmDDCA(); //get the recent most packet from ddca //the packet that invoked us /* switch (event) { case RCV_HELLO_MSG: // do some work cerr << "** Received hello message **\n"; break; } */ //process a query that came to us struct ddca_header *dh = (struct ddca_header *)(pkt + sizeof(struct ip)); struct query_body * qb = (struct query_body *)(pkt + sizeof(struct ip) + sizeof(struct ddca_header)); icrp.processQuery(dh, qb); cout <<"Entering the parentRouting function " << endl; cout << "with event = "<< event << endl; return 1; } RTEntry * ROUTER::existEntry(RTEntry *entry) { //should return the index if found //-1 if not //very inefficient, O(n) search //cout << "inside exist, index = " << index << endl; for(int i = 0; i <= index; i++) { // cout << " index = " << index << endl; if(entry->nid == rTable[i].nid ) { return &rTable[i]; //it does exist } } return NULL; //the entry did not exist } int ROUTER::insertEntry(RTEntry *entry) { RTEntry *tmpEntry; struct in_addr ha; tmpEntry = existEntry (entry); //cout << "inside, index = " << index << endl; if(tmpEntry == NULL) { entry->aliveSince = RTENTRY_ALIVE_LIMIT; rTable[++index] = *entry; ha.s_addr = entry->nid; cerr << "Well, inserted entry = " << inet_ntoa (ha) << endl; return index; } else { cout <<"insertEntry(): Entry exists! could not be inserted"<aliveSince = RTENTRY_ALIVE_LIMIT; return -1; } } int ROUTER::deleteEntry(RTEntry *entry) { RTEntry * tmpEntry; if((tmpEntry = existEntry(entry)) != NULL) { *tmpEntry = rTable[index];//if the last one is being deleted, it //writes itself in its own place and //decrements the index thus deleting itself index -= 1; return 0; //successful deletion } else { cout <<"deleteEntry(): Entry does not exist, can't delete" << endl; return -1; } } // update entry to keep alive the route // not really needed as insertEntry takes care of this, but ..... int ROUTER::updateEntry (RTEntry *entry) { RTEntry *tmpEntry; if ((tmpEntry = existEntry (entry)) == NULL) { cerr << "Fatal error: entry not found in routing table" << endl; return -1; } tmpEntry->aliveSince = RTENTRY_ALIVE_LIMIT; return -1; } int ROUTER::updateRoutingTable () { //for all the entries, check for which ones the timer has expired //for the ones that are already expired, delete the entries from the table //will need to call functions from class ipRouting to deal with them. struct in_addr ha; unsigned int myCid = 0; myCid = machine->getCid (); for(int i = 0; i <= index; i++) { rTable [i].aliveSince--; if (rTable[i].aliveSince <= 0) { ha.s_addr = rTable [i].nid; cerr << "DELETING route = " << inet_ntoa (ha) << endl; delRoute (rTable[i].nid, rTable[i].gw); remove_routable (rTable[i].nid); remove_gateway (rTable[i].nid); if (rTable [i].cid == myCid) // if node is part of my cluster { //add_routable_node (rTable[i].nid, DELETE_RT); //remove_routable (rTable[i].nid); machine->delete_from_cluster (); } deleteEntry (&(rTable[i])); } } return -1; } // function to check if we are a gateway node and appropriately // change status int ROUTER::updateGatewayStatus () { //struct in_addr ha; unsigned int myCid = 0; myCid = machine->getCid (); for (int i = 0; i <= index; i++) { if (rTable[i].cid != myCid)// get my own cid here to check return 1; // basically, i am still a gateway } // if i come upto here, basically means that i am no more // a gateway -- poor me return 0; } /* Original deleteEntry Function int ROUTER::deleteEntry(RTEntry *entry) { int tmpIndex; if((tmpIndex = existEntry(entry)) != -1) { rTable[tmpIndex] = rTable[index];//if the last one is being deleted, it //writes itself in its own place and //decrements the index thus deleting itself index -= 1; return tmpIndex; } else { cout <<"deleteEntry(): Entry does not exist, can't delete" << endl; return -1; } } */ int ROUTER::flushTable() { index = -1; return -1; } int ROUTER::printTable() { struct in_addr tmp; cout <<"---------------------printing table----------------------" << endl; for(int i = 0; i <= index; i++) { tmp.s_addr = rTable[i].nid; cout <<"Entry: " << i << "is: " << inet_ntoa(tmp) << endl; } cout << "--------------------------------------------------------" << endl; return 0; } int ROUTER::initRouting () { if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("Opening socket for routing table entries\n"); } cerr << "Initializing the routing FOR ADDING KERNEL ENTRIES" << endl; return 0; } // Add a route to the kernel routing table int ROUTER::addRoute (unsigned addr, unsigned gateway) { struct rtentry ent; struct sockaddr_in *sock; memset (&ent, 0, sizeof (ent)); sock = (struct sockaddr_in *) &ent.rt_dst; sock->sin_family = AF_INET; // can set our ip here using the function to get our own ip sock->sin_addr.s_addr = addr; // setting the mask sock = (struct sockaddr_in *) &ent.rt_genmask; sock->sin_family = AF_INET; sock->sin_addr.s_addr = inet_addr ("255.255.255.255"); ent.rt_flags = 0; // setting the gateway sock = (struct sockaddr_in *) &ent.rt_gateway; sock->sin_family = AF_INET; sock->sin_addr.s_addr = gateway; ent.rt_flags |= (RTF_UP | RTF_GATEWAY); if (ioctl(sockfd, SIOCADDRT, (char *)&ent) < 0) { perror ("addRoute"); return -1; } return 0; } // Delete a route in the kernel routing table int ROUTER::delRoute (unsigned addr, unsigned gateway) { struct rtentry ent; struct sockaddr_in *sock; memset (&ent, 0, sizeof (ent)); sock = (struct sockaddr_in *) &ent.rt_dst; sock->sin_family = AF_INET; // setting the destination address sock->sin_addr.s_addr = addr; // setting the mask sock = (struct sockaddr_in *) &ent.rt_genmask; sock->sin_family = AF_INET; sock->sin_addr.s_addr = inet_addr ("255.255.255.255"); ent.rt_flags = 0; // setting the gateway sock = (struct sockaddr_in *) &ent.rt_gateway; sock->sin_family = AF_INET; sock->sin_addr.s_addr = gateway; ent.rt_flags |= (RTF_UP | RTF_GATEWAY); if (ioctl(sockfd, SIOCDELRT, (char *)&ent) < 0) { perror ("delRoute"); return -1; } return 0; } /* Since we are going to do a limited broadcast, no need of the IP address of the recepient */ /* int ROUTER::bcastNewChild(RTEntry rte) { //--03/16/02 I think that I had put this function to broadcast whenever //whenever a new child got added to a cluster. this RPKT_HEADER I guess //is not much useful. we will proceed with the initial designs, //that is, use ddca_header for determining whether the packet is a //ddca or routing packet and then append another header below that //some sort of body, I guess char msg[1500]; int len; // RTEntry *tmp_rte ; ddca_header *dh; RPKT *rpkt; //build the ddca header now dh = (struct ddca_header *)(msg + IP_HEADER_LENGTH); dh->ver = 1; dh->proto = PKT_ROUTING; dh->ttl = 255; dh->reserved = 0; dh->seq = 0; dh->nid = machine->getNid(); dh->cid = machine->getCid(); dh->csum = 197; //copy the new entry into the buffer rpkt = (RPKT *)(msg + IP_HEADER_LENGTH + DDCA_LEN); rpkt->rpktType = CHILD_UPDATE; (rpkt->type).nc_update.rte = rte; len = sizeof(struct ddca_header) + sizeof(RPKT); machine->broadcastMsgRT(msg,len ); return 1; } */ int ROUTER::checkBcastPkt() { /* if the broadcast packet has been received then just discard it. In fact the whole concept of limited broadcast is embodied in the reception only. if you rcv a packet right now, you broadcast it, if you already received it, you discard it. */ return 0; } int ROUTER::QRY_RCMP(unsigned int ipAddr) { //for each border node, send a message saying to forward it, further return 0; } //this function sets the node on which the function is called to a border node int ROUTER::setBorderNode() { //search for yourself in the routing table and wherever the entry is found //set its isBorderNode to 1. RTEntry rte; RTEntry *tmp; rte.nid = machine->getNid(); if((tmp = existEntry(&rte)) != NULL ) { tmp->isBorderNode = 1; //Well, we are a border node now onwards return 1; } else { cerr << "Router::setBorderNode -> Could not locate self in routing table" << endl; return 0; } }