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

📄 nl.c

📁 在ns2.28中实现的AODV的升级版本AODV-
💻 C
字号:
/***************************************************************************** * * Copyright (C) 2001 Uppsala University and Ericsson AB. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Author: Erik Nordström, <erik.nordstrom@it.uu.se> *  *****************************************************************************/#include <stdlib.h>#include <stdio.h>#include <string.h> #include <sys/time.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <asm/types.h>#include <linux/netlink.h>#include <sys/select.h>#include <netinet/in.h>#include <arpa/inet.h>#include "defs.h"#include "lnx/kaodv-netlink.h"#include "debug.h"#include "aodv_rreq.h"#include "aodv_timeout.h"#include "routing_table.h"#include "aodv_hello.h"#include "params.h"#include "aodv_socket.h"#include "aodv_rerr.h"/* Implements a Netlink socket communication channel to the kernel. Route * information and refresh messages are passed. */static int nlfd;static struct sockaddr_nl local;static struct sockaddr_nl peer;static void nl_callback(int fd);extern int llfeedback, active_route_timeout, qual_threshold, internet_gw_mode, wait_on_reboot;extern struct timer worb_timer;#define BUFLEN 256void nl_init(void){    int status;    nlfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_AODV);    if (nlfd < 0) {	perror("Unable to create netlink socket");	exit(-1);    }    memset(&local, 0, sizeof(struct sockaddr_nl));    local.nl_family = AF_NETLINK;    local.nl_pid = getpid();    local.nl_groups = AODVGRP_NOTIFY;        memset(&peer, 0, sizeof(struct sockaddr_nl));    peer.nl_family = AF_NETLINK;    peer.nl_pid = 0;    peer.nl_groups = 0;    status = bind(nlfd, (struct sockaddr *) &local, sizeof(local));    if (status == -1) {	perror("Bind failed");	exit(-1);    }    if (attach_callback_func(nlfd, nl_callback) < 0) {	alog(LOG_ERR, 0, __FUNCTION__, "Could not attach callback.");    }}void nl_cleanup(void){    close(nlfd);}static void nl_callback(int fd){    int n;    int addrlen;    char buf[BUFLEN];    struct in_addr dest_addr, src_addr;        addrlen = sizeof(peer);        n = recvfrom(nlfd, buf, BUFLEN, 0, 		 (struct sockaddr *) &peer, &addrlen);        if (n) {	kaodv_rt_msg_t *m;	kaodv_rt_update_msg_t *mu;	rt_table_t *rt, *fwd_rt, *rev_rt = NULL;	int type;		type = ((struct nlmsghdr *) buf)->nlmsg_type;		switch(type) {	    	case KAODVM_TIMEOUT:	    m = NLMSG_DATA((struct nlmsghdr *) (buf));	    dest_addr.s_addr = m->dest;	    	    DEBUG(LOG_DEBUG, 0, "Got TIMEOUT msg from kernel for %s", 		  ip_to_str(dest_addr));	    rt = rt_table_find(dest_addr);	    if (rt && rt->state == VALID)		route_expire_timeout(rt);	    else		DEBUG(LOG_DEBUG, 0, "Got rt timeoute event but there is no route");	    break;	case KAODVM_NOROUTE:	    m = NLMSG_DATA((struct nlmsghdr *) (buf));	    dest_addr.s_addr = m->dest;	    DEBUG(LOG_DEBUG, 0, "Got NOROUTE msg from kernel for %s", 		  ip_to_str(dest_addr));	    rreq_route_discovery(dest_addr, 0, NULL);	    break;	case KAODVM_REPAIR:	    m = NLMSG_DATA((struct nlmsghdr *) (buf));	    dest_addr.s_addr = m->dest;	    src_addr.s_addr = m->src;	    	    DEBUG(LOG_DEBUG, 0, "Got REPAIR msg from kernel for %s", 		  ip_to_str(dest_addr));	    fwd_rt = rt_table_find(dest_addr);	    	    if (fwd_rt) 		rreq_local_repair(fwd_rt, src_addr, NULL);	    	    break;	case KAODVM_ROUTE_UPDATE:	    mu = NLMSG_DATA((struct nlmsghdr *) (buf));	    dest_addr.s_addr = mu->dest;	    src_addr.s_addr = mu->src;	   /*  DEBUG(LOG_DEBUG, 0, "Got ROUTE_UPDATE msg from kernel for %s",  *//* 		  ip_to_str(dest_addr)); */	    	    if (dest_addr.s_addr == AODV_BROADCAST ||		dest_addr.s_addr == DEV_IFINDEX(mu->ifindex).broadcast.s_addr)		return;	    	    fwd_rt = rt_table_find(dest_addr);	    fwd_rt = rt_table_find(dest_addr);	    	    rt_table_update_route_timeouts(fwd_rt, rev_rt);	    	    break;	case KAODVM_SEND_RERR:	    mu = NLMSG_DATA((struct nlmsghdr *) (buf));	    dest_addr.s_addr = mu->dest;	    src_addr.s_addr = mu->src;	    	    if (dest_addr.s_addr == AODV_BROADCAST ||		dest_addr.s_addr == DEV_IFINDEX(mu->ifindex).broadcast.s_addr)		return;	    	    fwd_rt = rt_table_find(dest_addr);	    fwd_rt = rt_table_find(dest_addr);	    	    do {		struct in_addr rerr_dest;		RERR *rerr;				DEBUG(LOG_DEBUG, 0, "Sending RERR for unsolicited message from %s to dest %s", ip_to_str(src_addr), ip_to_str(dest_addr));		if (fwd_rt) {		    rerr = rerr_create(0, fwd_rt->dest_addr,				       fwd_rt->dest_seqno);		    		    rt_table_update_timeout(fwd_rt, DELETE_PERIOD);		} else		    rerr = rerr_create(0, dest_addr, 0);				/* Unicast the RERR to the source of the data transmission		 * if possible, otherwise we broadcast it. */				if (rev_rt && rev_rt->state == VALID)		    rerr_dest = rev_rt->next_hop;		else		    rerr_dest.s_addr = AODV_BROADCAST;				aodv_socket_send((AODV_msg *) rerr, rerr_dest,				 RERR_CALC_SIZE(rerr), 1, &DEV_IFINDEX(mu->ifindex));				if (wait_on_reboot) {		    DEBUG(LOG_DEBUG, 0, "Wait on reboot timer reset.");		    timer_set_timeout(&worb_timer, DELETE_PERIOD);		} 	    } while (0);			    break;	default:	    DEBUG(LOG_DEBUG, 0, "Got mesg type=%d\n", type);	}    } else {	printf("no bytes read\n");    }}static int nl_create_and_send_msg(int type, struct in_addr dest, 				  struct in_addr nhop, u_int32_t lifetime, 				  int flags){    int status;    struct {	struct nlmsghdr nlh;	kaodv_rt_msg_t rtm;    } req;        memset(&req, 0, sizeof(req));    req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req));    req.nlh.nlmsg_flags = NLM_F_REQUEST;    req.nlh.nlmsg_type = type;    req.nlh.nlmsg_pid = local.nl_pid;    req.rtm.dest = dest.s_addr;    req.rtm.nhop = nhop.s_addr;/*     req.rtm.gw = gw_addr.s_addr; */    req.rtm.flags = flags;    req.rtm.time = lifetime;    status = sendto(nlfd, &req, req.nlh.nlmsg_len, 0,		    (struct sockaddr *) &peer, sizeof(peer));        return status;}void nl_send_add_route_msg(struct in_addr dest, struct in_addr next_hop, 			   u_int32_t lifetime, int rt_flags){    int flags = 0;           DEBUG(LOG_DEBUG, 0, "Send ADD/UPDATE ROUTE to kernel: %s:%s", 	  ip_to_str(dest), ip_to_str(next_hop));        if (rt_flags & RT_INET_DEST)	flags |= KAODV_RT_GW_ENCAP;        if (rt_flags & RT_REPAIR)	flags |= KAODV_RT_REPAIR;    nl_create_and_send_msg(KAODVM_ADDROUTE, dest, next_hop, lifetime, flags);  }void nl_send_no_route_found_msg(struct in_addr dest){    struct in_addr tmp;    tmp.s_addr = 0;    DEBUG(LOG_DEBUG, 0, "Send NOROUTE_FOUND to kernel: %s", ip_to_str(dest));    nl_create_and_send_msg(KAODVM_NOROUTE_FOUND, dest, tmp, 0, 0);  }void nl_send_del_route_msg(struct in_addr dest){    struct in_addr tmp;    tmp.s_addr = 0;    DEBUG(LOG_DEBUG, 0, "Send DELROUTE to kernel: %s", ip_to_str(dest));    nl_create_and_send_msg(KAODVM_DELROUTE, dest, tmp, 0, 0);  }int nl_send_conf_msg(void){    int status;    struct {	struct nlmsghdr nlh;	kaodv_conf_msg_t cm;    } req;        memset(&req, 0, sizeof(req));    req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req));    req.nlh.nlmsg_flags = NLM_F_REQUEST;    req.nlh.nlmsg_type = KAODVM_CONFIG;    req.nlh.nlmsg_pid = local.nl_pid;    req.cm.qual_th = qual_threshold;    req.cm.active_route_timeout = active_route_timeout;    req.cm.is_gateway = internet_gw_mode;    status = sendto(nlfd, &req, req.nlh.nlmsg_len, 0,		    (struct sockaddr *) &peer, sizeof(peer));        return status;}

⌨️ 快捷键说明

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