/******************************************************************************* gateway_list.cc contains list manipulation functions *******************************************************************************/ #include "ipq_list.h" //universal object which shall handle the packets extern IPQ_HANDLER ipqhnd; IPQ_LIST global_ipqlist; /*global list*/ struct ipq_list_node * create_node() { struct ipq_list_node * tmp = (struct ipq_list_node *) malloc (sizeof(struct ipq_list_node)); if(tmp == NULL) { #ifdef AT_MESSAGES printk(KERN_EMERG "gateway_list:create_node() Could not allocate memory\n"); #endif /*AT_MESSAGES*/ return NULL; } else { /*printk("Creating a new node\n");*/ tmp->next = NULL; } return tmp;/*If err tmp=NULL else some positive pointer*/ } /*init_list() *destroy list destroys the entire list including the dummy node. *make sure that init_list should be placed in the init_module */ void init_list(struct ipq_list_head **iplh) { (*iplh) = (struct ipq_list_head *) malloc(sizeof (struct ipq_list_head)); if(iplh != NULL) { (*iplh)->head = create_node(); (*iplh)->tail = NULL; } else { #ifdef AT_MESSAGES printk(KERN_DEBUG "init list: kmalloc error\n"); #endif /*AT_MESSAGES*/ return; } } /*always add to the end of the list*/ void add_to_list(struct ipq_list_head **iplh, struct ipq_list_node *ipln) { /*Anandha's suggestion, we can't have duplicates*/ if(check_list_for_duplicates(iplh, test_func, ipln) == -1) return; if((*iplh)->head->next != NULL) { (*iplh)->tail->next = create_node(); ((*iplh)->tail->next)->n = ipln->n; /*copy the node sent in*/ (*iplh)->tail = (*iplh)->tail->next; } else /*The list was empty, a new packet has arrived*/ { (*iplh)->tail = create_node(); ((*iplh)->tail)->n = ipln->n; /*copy the node sent in*/ (*iplh)->head->next = (*iplh)->tail; } } /* * Search and Destroy: The Matrix */ void remove_from_list(struct ipq_list_head **iplh, struct ipq_list_node *ipln) { struct ipq_list_node *tmp, *head; head = (*iplh)->head; while(head->next != NULL) { if((head->next)->n == ipln->n) { tmp = head->next; head->next = head->next->next; free(tmp); if(head->next == NULL)/*case we are deleting the tail node*/ (*iplh)->tail = head; /*we need the tail pointer as well*/ break; } head = head->next; } } /* * Annihilate them (make sure to call in cleanup_module) */ void destroy_list(struct ipq_list_head **iplh) { struct ipq_list_node *tmp; while((*iplh)->head->next != NULL) { /*delete the nodes in the actual list*/ tmp = (*iplh)->head->next; (*iplh)->head->next = (*iplh)->head->next->next; //printf("Num: %d\n", tmp->n); fflush(stdout); free(tmp); } free((*iplh)->head); /*delete the dummy node*/ (*iplh)->head = NULL; } int apply_function_to_list(struct ipq_list_head **iplh, int (*func) (struct ipq_list_node *, void *), void *param) { struct ipq_list_node *head; int count = 0; head = (*iplh)->head; if(head == NULL) { printf("Error: Trying to apply function to an empty list\n"); return 0; //TODO check if this is correct to return this value } while(head->next != NULL) { head = head->next; (*func)(head, param); count++; } return count*16;/*number of bytes written*/ } int check_list_for_duplicates(struct ipq_list_head **iplh, int (*func) (struct ipq_list_node *, void *), void *param) { struct ipq_list_node *head; head = (*iplh)->head; if(head == NULL) { printf("Error: Trying to apply function to an empty list\n"); return -1; //apparently error value is negative } while(head->next != NULL) { head = head->next; if((*func)(head, param) == -1) return -1; } return 0;/*number of IP addresses written*/ } /*checks if an entry already exists*/ int test_func(struct ipq_list_node *gln, void *param) { if(gln->n == ((struct ipq_list_node *)param)->n) { #ifdef AT_MESSAGES printf("Entry already exists\n"); #endif /*AT_MESSAGES*/ printf("Entry already exists\n"); return -1; } return 0; } int print_list(struct ipq_list_node *ipln, void *param) { cout << " node: " << ipln->n; return 0; } int IPQ_LIST::insertInList(unsigned int ipAddr, ipq_id_t id) { ipq_list_node tmp_node; tmp_node.n = id; //search for(int i=0; i <= index; i++) { if(ipqList[i].daddr == ipAddr) { //add the new packet right here add_to_list(&ipqList[i].ipqlst, &tmp_node); return 0; //success } } //you are here means the ipAddr is being seen for the first time index++; //increment the index, one more on the waiting list ipqList[index].daddr = ipAddr; ipqList[index].timer = REPLY_TIMEOUT; //timer maxed init_list(&ipqList[index].ipqlst); //initialize the new list add_to_list(&ipqList[index].ipqlst, &tmp_node);//add it to the new list return 0;//success } int IPQ_LIST::isDestSeen(unsigned int ipAddr) { for(int i=0; i <= index; i++) { if(ipAddr == ipqList[i].daddr) { return i; //seen } } return -1; //not seen } int IPQ_LIST::getTimerValue (int num) { return ipqList [num].timer; } void IPQ_LIST::decrementTimer(int timeout) //decrement all { for(int i=0; i <= index; i++) { if(ipqList[i].timer >= MIN_GRANULARITY) { ipqList[i].timer -= MIN_GRANULARITY; } } } int dropPacket(struct ipq_list_node *ipln, void *param) { if (ipq_set_verdict(ipqhnd.getHandler(), ipln->n, NF_DROP, 0, NULL) < 0 ){ ipq_perror("set verdict(): DROP Oops!"); exit(1); } return 0; } int acceptPacket(struct ipq_list_node *ipln, void *param) { if (ipq_set_verdict(ipqhnd.getHandler(), ipln->n, NF_ACCEPT, 0, NULL) < 0 ){ ipq_perror("set verdict(): ACCEPT Oops!"); exit(1); } return 0; } int IPQ_LIST::nf_dropList(unsigned int ipAddr) { //search struct _ipq_list tmp_node; for(int i=0; i <= index; i++) { if(ipqList[i].daddr == ipAddr) { //first switch them tmp_node = ipqList[i]; ipqList[i] = ipqList[index]; ipqList[index] = tmp_node; apply_function_to_list(&ipqList[index].ipqlst, dropPacket, NULL);//put nf_drop on all of them cout << endl; destroy_list(&ipqList[index].ipqlst); //destroy the list index--; //now decrement the index return 0; //success } } cout <<"Error, something in dropList should have matched" << endl; return -1; } int IPQ_LIST::nf_acceptList(unsigned int ipAddr) { //search struct _ipq_list tmp_node; for(int i=0; i <= index; i++) { if(ipqList[i].daddr == ipAddr) { //first switch them tmp_node = ipqList[i]; ipqList[i] = ipqList[index]; ipqList[index] = tmp_node; apply_function_to_list(&ipqList[index].ipqlst, acceptPacket, NULL);//put nf_accept on all of them cout << endl; destroy_list(&ipqList[index].ipqlst); //destroy the list index--; //now decrement the index return 0; //success } } cout <<"Error, something in acceptList should have matched" << endl; return -1; } /* int main() { global_ipqlist.insertInList(1, 1); global_ipqlist.insertInList(1, 2); global_ipqlist.insertInList(2, 3); global_ipqlist.insertInList(2, 4); global_ipqlist.insertInList(3, 5); global_ipqlist.insertInList(3, 6); global_ipqlist.insertInList(3, 7); global_ipqlist.nf_acceptList(1); global_ipqlist.nf_acceptList(2); global_ipqlist.nf_acceptList(3); } */