/******************************************************************************* gateway_list.c contains list manipulation functions *******************************************************************************/ #include "gateway_list.h" struct gateway_list_node * create_node() { struct gateway_list_node * tmp = (struct gateway_list_node *) malloc (sizeof(struct gateway_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 gateway_list_head **iplh) { (*iplh) = (struct gateway_list_head *) malloc(sizeof (struct gateway_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 gateway_list_head **iplh, struct gateway_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 gateway_list_head **iplh, struct gateway_list_node *ipln) { struct gateway_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 gateway_list_head **iplh) { struct gateway_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 gateway_list_head **iplh, int (*func) (struct gateway_list_node *, void *), void *param) { struct gateway_list_node *head; int count = 0; head = (*iplh)->head; if(head == NULL) { printf("Error: Trying to apply function to an empty list\n"); return; } while(head->next != NULL) { head = head->next; (*func)(head, param); count++; } return count*16;/*number of bytes written*/ } int check_list_for_duplicates(struct gateway_list_head **iplh, int (*func) (struct gateway_list_node *, void *), void *param) { struct gateway_list_node *head; head = (*iplh)->head; if(head == NULL) { printf("Error: Trying to apply function to an empty list\n"); return; } while(head->next != NULL) { head = head->next; if((*func)(head, param) == -1) return -1; } return 0;/*number of IP addresses written*/ } //Used for testing int fill_buffer(struct gateway_list_node *ipln, void *param) { sprintf(((struct printable_buffer *)param)->buff + ((struct printable_buffer *)param)->offset, "%d.%d.%d.%d\n", NIPQUAD(ipln->n)); //bug here, laziness did not compute size of data actually written ((struct printable_buffer *)param)->offset += 16; return 0; } int test_func(struct gateway_list_node *gln, void *param) { if(gln->n == ((struct gateway_list_node *)param)->n) { #ifdef AT_MESSAGES printf("Entry already exists\n"); #endif /*AT_MESSAGES*/ printf("Entry already exists\n"); return -1; } } int fill_new_buffer(struct gateway_list_node *ipln, void *param) { char buff[100]; sprintf(buff, "%d ", ipln->n); strcat(((struct printable_buffer *)param)->buff, buff); return strlen(buff); } int main() { int i; struct gateway_list_head *iplh; struct gateway_list_node ipl; struct printable_buffer junk_ptr; junk_ptr.buff = (char *)malloc(sizeof(char)*1000); junk_ptr.buff[0] = '\0'; junk_ptr.offset = 0; init_list(&iplh); remove_from_list(&iplh, &ipl); for(i =3; i > 0; i--) { // ipl.n = inet_addr("136.142.79.177"); ipl.n = i; add_to_list(&iplh, &ipl); } /* ipl.n = inet_addr("136.142.79.117"); add_to_list(&iplh, &ipl); ipl.n= inet_addr("136.142.79.177"); remove_from_list(&iplh, &ipl); */ //i = apply_function_to_list(&iplh, fill_buffer, (char *)&junk_ptr); //junk call i = apply_function_to_list(&iplh, fill_new_buffer, (char *)&junk_ptr); //junk call destroy_list(&iplh); printf("hehe\n"); write(1, junk_ptr.buff, strlen(junk_ptr.buff)); fflush(stdout); return 0; }