📄 nameservice.c
字号:
return NULL; } switch (type) { case NAME_HOST: valid = is_name_wellformed(my_list->name) && allowed_ip(&my_list->ip); break; case NAME_FORWARDER: valid = allowed_ip(&my_list->ip); break; case NAME_SERVICE: valid = allowed_service(my_list->name); break; case NAME_LATLON: valid = is_latlon_wellformed(my_list->name); break; } if ( !valid ) { OLSR_PRINTF(1, "NAME PLUGIN: invalid or malformed parameter %s (%s), fix your config!\n", my_list->name, olsr_ip_to_string(&my_list->ip)); next = my_list->next; free(my_list->name); my_list->name = NULL; free(my_list); my_list = NULL; return remove_nonvalid_names_from_list(next, type); } else { OLSR_PRINTF(2, "NAME PLUGIN: validate parameter %s (%s) -> OK\n", my_list->name, olsr_ip_to_string(&my_list->ip)); my_list->next = remove_nonvalid_names_from_list(my_list->next, type); return my_list; }}/** * called at unload: free everything * * XXX: should I delete the hosts/services/resolv.conf files on exit? */voidname_destructor(void){ OLSR_PRINTF(2, "NAME PLUGIN: exit. cleaning up...\n"); free_name_entry_list(&my_names); free_name_entry_list(&my_services); free_name_entry_list(&my_forwarders); free_all_list_entries(list); free_all_list_entries(service_list); free_all_list_entries(forwarder_list); free_all_list_entries(latlon_list); regfree(®ex_t_name); regfree(®ex_t_service); }/* free all list entries */void free_all_list_entries(struct db_entry **this_db_list) { int i; for(i = 0; i < HASHSIZE; i++) { struct db_entry **tmp = &this_db_list[i]; while(*tmp != NULL) { struct db_entry *to_delete = *tmp; *tmp = (*tmp)->next; free_name_entry_list(&to_delete->names); free(to_delete); to_delete = NULL; } }}/** * A timeout function called every time * * XXX:the scheduler is polled (by default 10 times a sec, * which is far too often): * * time out old list entries * and write changes to file */static int timeout_roundrobin = 0;voidolsr_timeout(void){ switch(timeout_roundrobin++) { case 0: timeout_old_names(list, &name_table_changed); timeout_old_names(forwarder_list, &forwarder_table_changed); timeout_old_names(service_list, &service_table_changed); timeout_old_names(latlon_list, &latlon_table_changed); break; case 1: write_resolv_file(); // if forwarder_table_changed break; case 2: write_hosts_file(); // if name_table_changed break; case 3: write_services_file(); // if service_table_changed break; case 4: write_latlon_file(); // latlon_table_changed break; default: timeout_roundrobin = 0; } // switch}voidtimeout_old_names(struct db_entry **this_list, olsr_bool *this_table_changed){ struct db_entry **tmp; struct db_entry *to_delete; int index; for(index=0;index<HASHSIZE;index++) { for (tmp = &this_list[index]; *tmp != NULL; ) { /* check if the entry for this ip is timed out */ if (olsr_timed_out(&(*tmp)->timer)) { to_delete = *tmp; /* update the pointer in the linked list */ *tmp = (*tmp)->next; OLSR_PRINTF(2, "NAME PLUGIN: %s timed out... deleting\n", olsr_ip_to_string(&to_delete->originator)); /* Delete */ free_name_entry_list(&to_delete->names); free(to_delete); *this_table_changed = OLSR_TRUE; } else { tmp = &(*tmp)->next; } } }}/** * Scheduled event: generate and send NAME packet */voidolsr_event(void *foo __attribute__((unused))){ /* send buffer: huge */ char buffer[10240]; union olsr_message *message = (union olsr_message *)buffer; struct interface *ifn; int namesize; /* looping trough interfaces */ for (ifn = ifnet; ifn ; ifn = ifn->int_next) { OLSR_PRINTF(3, "NAME PLUGIN: Generating packet - [%s]\n", ifn->int_name); /* fill message */ if(olsr_cnf->ip_version == AF_INET) { /* IPv4 */ message->v4.olsr_msgtype = MESSAGE_TYPE; message->v4.olsr_vtime = double_to_me(my_timeout); memcpy(&message->v4.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize); message->v4.ttl = MAX_TTL; message->v4.hopcnt = 0; message->v4.seqno = htons(get_msg_seqno()); namesize = encap_namemsg((struct namemsg*)&message->v4.message); namesize = namesize + sizeof(struct olsrmsg); message->v4.olsr_msgsize = htons(namesize); } else { /* IPv6 */ message->v6.olsr_msgtype = MESSAGE_TYPE; message->v6.olsr_vtime = double_to_me(my_timeout); memcpy(&message->v6.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize); message->v6.ttl = MAX_TTL; message->v6.hopcnt = 0; message->v6.seqno = htons(get_msg_seqno()); namesize = encap_namemsg((struct namemsg*)&message->v6.message); namesize = namesize + sizeof(struct olsrmsg6); message->v6.olsr_msgsize = htons(namesize); } if(net_outbuffer_push(ifn, message, namesize) != namesize ) { /* send data and try again */ net_output(ifn); if(net_outbuffer_push(ifn, message, namesize) != namesize ) { OLSR_PRINTF(1, "NAME PLUGIN: could not send on interface: %s\n", ifn->int_name); } } }}/** * Parse name olsr message of NAME type */voidolsr_parser(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *ipaddr){ struct namemsg *namemessage; union olsr_ip_addr originator; double vtime; int size; olsr_u16_t seqno; /* Fetch the originator of the messsage */ if(olsr_cnf->ip_version == AF_INET) { memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize); seqno = ntohs(m->v4.seqno); } else { memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize); seqno = ntohs(m->v6.seqno); } /* Fetch the message based on IP version */ if(olsr_cnf->ip_version == AF_INET) { vtime = me_to_double(m->v4.olsr_vtime); size = ntohs(m->v4.olsr_msgsize); namemessage = (struct namemsg*)&m->v4.message; } else { vtime = me_to_double(m->v6.olsr_vtime); size = ntohs(m->v6.olsr_msgsize); namemessage = (struct namemsg*)&m->v6.message; } /* Check if message originated from this node. If so - back off */ if(memcmp(&originator, &olsr_cnf->main_addr, olsr_cnf->ipsize) == 0) return; /* Check that the neighbor this message was received from is symmetric. If not - back off*/ if(check_neighbor_link(ipaddr) != SYM_LINK) { OLSR_PRINTF(3, "NAME PLUGIN: Received msg from NON SYM neighbor %s\n", olsr_ip_to_string(ipaddr)); return; } /* Check if this message has been processed before * Remeber that this also registeres the message as * processed if nessecary */ if(olsr_check_dup_table_proc(&originator, seqno)) { /* If not so - process */ update_name_entry(&originator, namemessage, size, vtime); } /* Forward the message if nessecary * default_fwd does all the work for us! */ olsr_forward_message(m, &originator, seqno, in_if, ipaddr);}/** * Encapsulate a name message into a packet. * * It assumed that there is enough space in the buffer to do this! * * Returns: the length of the message that was appended */intencap_namemsg(struct namemsg* msg){ struct name_entry *my_name; struct name_entry *my_service; // add the hostname, service and forwarder entries after the namemsg header char* pos = (char*)msg + sizeof(struct namemsg); short i=0; // names for (my_name = my_names; my_name!=NULL; my_name = my_name->next) { pos = create_packet( (struct name*) pos, my_name); i++; } // forwarders for (my_name = my_forwarders; my_name!=NULL; my_name = my_name->next) { pos = create_packet( (struct name*) pos, my_name); i++; } // services for (my_service = my_services; my_service!=NULL; my_service = my_service->next) { pos = create_packet( (struct name*) pos, my_service); i++; } // latlon if ('\0' != latlon_in_file[0]) { FILE* in = fopen( latlon_in_file, "r" ); if (in != NULL) { fscanf(in, "%f,%f", &my_lat, &my_lon); fclose(in); } else { OLSR_PRINTF(0, "NAME PLUGIN: cant read latlon in file %s\n", latlon_in_file); } } if (0.0 != my_lat && 0.0 != my_lon) { char s[64]; struct name_entry e; memset(&e, 0, sizeof(e)); sprintf(s, "%f,%f,%d", my_lat, my_lon, get_isdefhna_latlon()); e.len = strlen(s); e.type = NAME_LATLON; e.name = s; lookup_defhna_latlon(&e.ip); pos = create_packet( (struct name*) pos, &e); i++; } // write the namemsg header with the number of announced entries and the protocol version msg->nr_names = htons(i); msg->version = htons(NAME_PROTOCOL_VERSION); return pos - (char*)msg; //length}/** * convert each of my to be announced name_entries into network * compatible format * * return the length of the name packet */char* create_packet(struct name* to, struct name_entry *from){ char *pos = (char*) to; int k; OLSR_PRINTF(3, "NAME PLUGIN: Announcing name %s (%s) %d\n", from->name, olsr_ip_to_string(&from->ip), from->len); to->type = htons(from->type); to->len = htons(from->len); memcpy(&to->ip, &from->ip, olsr_cnf->ipsize); pos += sizeof(struct name); strncpy(pos, from->name, from->len); pos += from->len; for (k = from->len; (k & 3) != 0; k++) *pos++ = '\0'; return pos;}/** * decapsulate a received name, service or forwarder and update the corresponding hash table if necessary */voiddecap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_table_changed ){ struct name_entry *tmp; struct name_entry *already_saved_name_entries; char *name = (char*)from_packet + sizeof(struct name); int type_of_from_packet = ntohs(from_packet->type); unsigned int len_of_name = ntohs(from_packet->len); OLSR_PRINTF(4, "NAME PLUGIN: decap type=%d, len=%d, name=%s\n", type_of_from_packet, len_of_name, name); //XXX: should I check the from_packet->ip here? If so, why not also check the ip fro HOST and SERVICE? if( (type_of_from_packet==NAME_HOST && !is_name_wellformed(name)) || (type_of_from_packet==NAME_SERVICE && !is_service_wellformed(name)) || (type_of_from_packet==NAME_LATLON && !is_latlon_wellformed(name))) { OLSR_PRINTF(4, "NAME PLUGIN: invalid name [%s] received, skipping.\n", name ); return; } //ignore all packets with a too long name //or a spoofed len of its included name string
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -