⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rerr.c

📁 一种AODV实现方法
💻 C
字号:
/*               Kernel AODV  v2.0National Institute of Standards and Technology               Luke Klein-Berndt-----------------------------------------------------  Version 2.0 new features:     * Updated to AODV draft version 11     * Managed internet gatewaying     * Monitor wireles signal strength     * Many bug fixes!-----------------------------------------------------Originally based upon MadHoc code. I am notsure how much of it is left anymore, but MadHocproved to be a great starting point.MadHoc was written by - Fredrik Lilieblad,Oskar Mattsson, Petra Nylund, Dan Ouchterlonyand Anders Roxenhag Mail: mad-hoc@flyinglinux.netThis software is Open Source under the GNU General Public Licence.*/#include "rerr.h"/****************************************************   rerr----------------------------------------------------Handles the generation of RERR messages****************************************************/extern u_int32_t g_broadcast_ip;extern u_int32_t g_my_ip;void free_rerrhdr(struct rerrhdr *tmp_rerrhdr);int send_rerr(struct rerrhdr *tmp_rerrhdr, u_int32_t sent_to);/****************************************************   link_break----------------------------------------------------link_break is called when a broken link to a neighbouringis detected. All active routes that have the unreachable node as nexthop are invalidated. All precursors for this entry are removed. TheRERR meassage including the unreachable destinations and their incremented seq numbers is finally rebroadcast.****************************************************/int link_break( u_int32_t brk_dst_ip){    struct route_table_entry *tmp_entry;    struct rerrhdr *new_rerrhdr = NULL;    struct precursor_entry *tmp_precursor;    struct precursor_entry *dead_precursor;    u_int32_t last_precursor;    u_int8_t precursor_num=0;    int rerrhdr_created = 0;    // remove the borken link from all the route table entries    delete_precursor_entry_from_route_table(brk_dst_ip);    tmp_entry=get_first_route_table_entry();    //go through list    while(tmp_entry != NULL)    {        //if the route has the broken IP for the next hop and is active        if((tmp_entry->next_hop == brk_dst_ip) && (tmp_entry->route_valid))        {#ifdef MESSAGES            printk("RERR: Broken link as next hop for - %s \n",inet_ntoa(tmp_entry->dst_ip));#endif            //expire the route            route_expiry(tmp_entry);#ifdef TRACE            printk("RERR: Route marked as expired\n");#endif            //if the rerr header has not been created yet            if(!rerrhdr_created)            {                if((new_rerrhdr =create_rerrhdr(tmp_entry->dst_ip,tmp_entry->dst_seq)) == NULL)                    return 1;                rerrhdr_created = 1;            }            else            {                append_unr_dst(new_rerrhdr, tmp_entry->dst_ip, tmp_entry->dst_seq);            }#ifdef TRACE            printk("RERR: About to delete precursors from route table entry\n");#endif            //remove all the precursors from the route            tmp_precursor=tmp_entry->precursors;            while (tmp_precursor!=NULL)            {                precursor_num++;                last_precursor=tmp_precursor->ip;                dead_precursor=tmp_precursor;                tmp_precursor=tmp_precursor->next;                kfree(dead_precursor);            }            tmp_entry->precursors=NULL;        }        //move on to the next entry        tmp_entry = tmp_entry->next;    }    //if there was a RERR created, send it out    if(rerrhdr_created)    {        if (precursor_num==1)            send_rerr(new_rerrhdr,last_precursor);        else            send_rerr(new_rerrhdr,g_broadcast_ip);        free_rerrhdr(new_rerrhdr);    }    return 0;}/****************************************************   route_expiry---------------------------------------------------- route_expiry invalidates an active route, i e an entry in the routing table.****************************************************/void route_expiry(struct route_table_entry *tmp_entry){    //marks a route as expired    tmp_entry->lifetime = (getcurrtime() + DELETE_PERIOD);    tmp_entry->dst_seq++;    tmp_entry->route_valid=FALSE;    delete_kernel_route_entry(tmp_entry->dst_ip, tmp_entry->next_hop);}/****************************************************   host_unr----------------------------------------------------host_unr is called when a packet is received destined for a nodewhich the forwarding node does not have an active route to. A RERRmessage is created to inform neighbours.****************************************************/int  host_unr(u_int32_t brk_dst_ip){    struct rerrhdr *new_rerrhdr = NULL;    struct route_table_entry *tmp_entry;    tmp_entry = find_route_table_entry(brk_dst_ip);    if((new_rerrhdr = create_rerrhdr(brk_dst_ip, 1)) == NULL)        return 1;    send_rerr(new_rerrhdr,g_broadcast_ip);    free_rerrhdr(new_rerrhdr);    return 0;}/****************************************************   rec_rerr----------------------------------------------------rec_rerr is called when the node receives a RERR packet fromanother node. If the precursor list for a broken destinations isnot empty a new RERR is created for that destination.****************************************************/int recv_rerr(struct event_queue_entry *working_packet){    struct rerr *tmp_hdr;    struct rerrhdr *new_rerrhdr = NULL;    struct rerrdst *tmp_dst;    struct route_table_entry *tmp_route;    struct interface_list_entry *tmp_interface;    int new_rerr_created = 0;    int i;    tmp_interface=find_interface_by_dev(working_packet->dev);    if (tmp_interface==NULL)        return 0;    tmp_hdr =(struct rerr *) ((char *) working_packet->data);    tmp_dst = (struct rerrdst *) ((char *) tmp_hdr + sizeof (struct rerr));#ifdef MESSAGES    printk("RERR: recieved a route error, count= %u\n",tmp_hdr->dst_count);#endif    for(i = 0; i < tmp_hdr->dst_count; i++)    {        //go through all the unr dst in the rerr#ifdef MESSAGES        printk("       -> %s",inet_ntoa(tmp_dst->unr_dst_ip));#endif        tmp_route = find_route_table_entry(tmp_dst->unr_dst_ip);        //Is the sender of the rerr the next hop for a broken destination for the current node?        if(tmp_route != NULL)        {            if( tmp_route->dst_ip != tmp_interface->ip )            {                if (tmp_route->next_hop == working_packet->src_ip)                {#ifdef MESSAGES                    printk(" Removing route");#endif                    tmp_route->dst_seq = ntohl(tmp_dst->unr_dst_seq);                    tmp_route->route_valid=FALSE;                    tmp_route->lifetime = (getcurrtime() + DELETE_PERIOD);                    delete_kernel_route_entry(tmp_route->dst_ip, tmp_route->next_hop);                    if(tmp_route->precursors != NULL)                    {                        // precursors exist                        if(!new_rerr_created)                        {                            new_rerr_created = 1;                            new_rerrhdr = create_rerrhdr(tmp_dst->unr_dst_ip, tmp_dst->unr_dst_seq);                        }                        else                        {                            append_unr_dst(new_rerrhdr, tmp_dst->unr_dst_ip,  tmp_dst->unr_dst_seq);                        }                    }                }            }        }	#ifdef MESSAGES        printk(" \n");	#endif        tmp_dst =(struct rerrdst *) ((char *) tmp_dst + sizeof (struct rerrdst));    }    if(new_rerr_created)    {        send_rerr(new_rerrhdr,g_broadcast_ip);        free_rerrhdr(new_rerrhdr);    }    return 0;}/****************************************************   create_rerrhdr----------------------------------------------------create_rerrhdr is used to create a new RERR message****************************************************/struct rerrhdr* create_rerrhdr(u_int32_t tmp_ip, u_int32_t tmp_dst_seq){    struct rerr_unr_dst *tmp_rerr_unr_dst;    struct rerrhdr *tmp_rerrhdr;    //create header    if((tmp_rerrhdr = kmalloc(sizeof(struct rerrhdr),GFP_ATOMIC)) == NULL)    {#ifndef NO_ERROR        printk("RERR: Error creating tmp_rerrhdr \n");#endif        return NULL;    }    //create spot for first entry    if((tmp_rerr_unr_dst = kmalloc(sizeof(struct rerr_unr_dst),GFP_ATOMIC)) == NULL)    {#ifndef NO_ERROR        printk("RERR: Error creating temp_rerr_unr_dst\n");#endif        return NULL;    }    //fill in info for first entry    tmp_rerr_unr_dst->unr_dst_ip = tmp_ip;    tmp_rerr_unr_dst->unr_dst_seq = tmp_dst_seq;    tmp_rerr_unr_dst->next = NULL;    //fill in info for header    tmp_rerrhdr->unr_dst = tmp_rerr_unr_dst;    tmp_rerrhdr->type = 3;    tmp_rerrhdr->dst_count = 1;    return tmp_rerrhdr;}/****************************************************   append_unr_dst----------------------------------------------------append_unr_dst adds an unreachable node to the previouslycreated RERR message.****************************************************/int append_unr_dst(struct rerrhdr *tmp_rerrhdr, u_int32_t tmp_ip,u_int32_t tmp_dst_seq){    struct rerr_unr_dst *tmp_rerr_unr_dst;    //get memory for new entry    if((tmp_rerr_unr_dst = kmalloc(sizeof(struct rerr_unr_dst),GFP_ATOMIC)) == NULL)    {#ifndef NO_ERROR        printk("RERR: Error appending new unr_dst\n");#endif        return 1;    }    //fill in info for entry    tmp_rerr_unr_dst->next = tmp_rerrhdr->unr_dst;    tmp_rerrhdr->unr_dst = tmp_rerr_unr_dst;    tmp_rerrhdr->dst_count++;    tmp_rerr_unr_dst->unr_dst_ip = tmp_ip;    tmp_rerr_unr_dst->unr_dst_seq = tmp_dst_seq;    return 0;}/****************************************************   free_rerrhdr---------------------------------------------------- free_rerrhdr frees the allocated memory for the rerrhdr list structure.****************************************************/void free_rerrhdr(struct rerrhdr *tmp_rerrhdr){    struct rerr_unr_dst *tmp_unr_dst;    struct rerr_unr_dst *dead_dst;    //for all the unreachable destinataion in the rerr    tmp_unr_dst=tmp_rerrhdr->unr_dst;    while (tmp_unr_dst!=NULL)    {        dead_dst=tmp_unr_dst;        tmp_unr_dst = tmp_unr_dst->next;        kfree(tmp_unr_dst);    }    kfree(tmp_rerrhdr);}/****************************************************   send_rerr---------------------------------------------------- send_rerr copies the incoming RERR message to a connected data area, which is a suitable format for the function send_datagram.****************************************************/int send_rerr(struct rerrhdr *tmp_rerrhdr, u_int32_t sent_to){    struct rerr *out_hdr;    struct rerrdst *out_dst;    struct rerr_unr_dst *tmp_dst;    void *data;    int datalen, i;    datalen = sizeof(struct rerr) + sizeof(struct rerrdst) * (tmp_rerrhdr->dst_count);    //get the needed memory    if((data = kmalloc(datalen,GFP_ATOMIC)) == NULL)    {#ifndef NO_ERROR        printk("RERR: Error creating packet to send RERR\n");#endif        return -1;    }    out_hdr =(struct rerr *) ((char *) data);    out_hdr->type = 3;    out_hdr->dst_count = tmp_rerrhdr->dst_count;    out_hdr->reserved =0;    out_dst=(struct rerrdst *) ((char *) out_hdr + sizeof(struct rerr));    tmp_dst = tmp_rerrhdr->unr_dst;    for(i = 0; i < tmp_rerrhdr->dst_count; i++)    {        out_dst->unr_dst_ip=tmp_dst->unr_dst_ip;	#ifdef MESSAGES        printk("RERR: adding... %s to RERR\n",inet_ntoa(out_dst->unr_dst_ip));	#endif        //convert it to network byte order        out_dst->unr_dst_seq=htonl(tmp_dst->unr_dst_seq);        out_dst =(struct rerrdst *) ((char *) out_dst + sizeof(struct rerrdst));        tmp_dst = tmp_dst->next;    }#ifdef TRACE    printk("RERR: sending out a RERR with %d UNR hosts\n",i);#endif    if (sent_to==g_broadcast_ip)        local_broadcast(NET_DIAMETER, data, datalen);    else        send_message(sent_to,NET_DIAMETER, data, datalen);    kfree(data);    return 0;}/* * print_rerrhdr * * Description: *   print_rerrhdr prints a RERR message * * Arguments: *   struct rerrhdr *new_rerrhdr - Pointer to the rerrhdr * * Returns: void */void print_rerrhdr(struct rerrhdr *new_rerrhdr){    struct rerr_unr_dst *tmp_rerr_unr_dst;    struct in_addr tmp_in_addr;    int i;    printk("Outgoing RERR message: type: %d dst_cnt: %d\n",           new_rerrhdr->type, new_rerrhdr->dst_count);    for(i = 0, tmp_rerr_unr_dst = new_rerrhdr->unr_dst;            i < new_rerrhdr->dst_count;            i++, tmp_rerr_unr_dst = tmp_rerr_unr_dst->next)    {        tmp_in_addr.s_addr = tmp_rerr_unr_dst->unr_dst_ip;        printk("unr_dst_ip: %s unr_dst_seq %d\n",               inet_ntoa(tmp_in_addr.s_addr),               tmp_rerr_unr_dst->unr_dst_seq);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -