📄 aodv_socket.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 * * Authors: Erik Nordstr鰉, <erik.nordstrom@it.uu.se> * *****************************************************************************/#include <sys/types.h>#ifdef NS_PORT#include "aodv-uu.h"#else#include <sys/socket.h>#include <netinet/in.h>#include <net/if.h>#include <netinet/udp.h>#include "aodv_socket.h"#include "timer_queue.h"#include "aodv_rreq.h"#include "aodv_rerr.h"#include "aodv_rrep.h"#include "params.h"#include "aodv_hello.h"#include "aodv_neighbor.h"#include "debug.h"#include "defs.h"#ifdef USE_IW_SPY#include "link_qual.h"#endif#endif /* NS_PORT */#ifndef NS_PORT#define SO_RECVBUF_SIZE 256*1024static char recv_buf[RECV_BUF_SIZE];static char send_buf[SEND_BUF_SIZE];extern int wait_on_reboot, hello_qual_threshold, ratelimit;#ifdef USE_IW_SPYextern char *spy_addrs;#endifstatic void aodv_socket_read(int fd);/* Simple function (based on R. Stevens) to calculate UDP header checksum */static inline u_int16_t in_udp_csum(unsigned long saddr, unsigned long daddr, unsigned short len, unsigned short proto, unsigned short *buf){ unsigned short *w; int nleft = ntohs(len); int sum = 0; sum += (saddr >> 16) + (saddr & 0xffff); sum += (daddr >> 16) + (daddr & 0xffff); sum += (proto << 8); sum += len; w = buf; while(nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) sum += *(unsigned char *) w; sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return ~sum;}#endif /* NS_PORT */void NS_CLASS aodv_socket_init(){#ifndef NS_PORT struct sockaddr_in aodv_addr; struct ifreq ifr; int i, retval = 0; int on = 1; int tos = IPTOS_LOWDELAY; int bufsize = SO_RECVBUF_SIZE; socklen_t optlen = sizeof(bufsize); /* Create a UDP socket */ if (this_host.nif == 0) { fprintf(stderr, "No interfaces configured\n"); exit(-1); } /* Open a socket for every AODV enabled interface */ for (i = 0; i < MAX_NR_INTERFACES; i++) { if (!DEV_NR(i).enabled) continue; /* AODV socket */ DEV_NR(i).sock = socket(PF_INET, SOCK_RAW, IPPROTO_UDP); if (DEV_NR(i).sock < 0) { perror(""); exit(-1); }#ifdef CONFIG_GATEWAY /* Data packet send socket */ DEV_NR(i).psock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW); if (DEV_NR(i).psock < 0) { perror(""); exit(-1); }#endif /* Bind the socket to the AODV port number */ memset(&aodv_addr, 0, sizeof(aodv_addr)); aodv_addr.sin_family = AF_INET; aodv_addr.sin_port = htons(AODV_PORT); aodv_addr.sin_addr.s_addr = htonl(INADDR_ANY); retval = bind(DEV_NR(i).sock, (struct sockaddr *) &aodv_addr, sizeof(struct sockaddr)); if (retval < 0) { perror("Bind failed "); exit(-1); } if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(int)) < 0) { perror("SO_BROADCAST failed "); exit(-1); } memset(&ifr, 0, sizeof(struct ifreq)); strcpy(ifr.ifr_name, DEV_NR(i).ifname); if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) { fprintf(stderr, "SO_BINDTODEVICE failed for %s", DEV_NR(i).ifname); perror(" "); exit(-1); } if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_PRIORITY, &tos, sizeof(int)) < 0) { perror("Setsockopt SO_PRIORITY failed "); exit(-1); } /* We provide our own IP header... */ if (setsockopt(DEV_NR(i).sock, SOL_IP, IP_HDRINCL, &on, sizeof(int)) < 0) { perror("Setsockopt IP_HDRINCL failed "); exit(-1); }#ifdef CONFIG_GATEWAY if (setsockopt(DEV_NR(i).psock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) { fprintf(stderr, "SO_BINDTODEVICE failed for %s", DEV_NR(i).ifname); perror(" "); exit(-1); } bufsize = 4 * 65535; if (setsockopt(DEV_NR(i).psock, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize, optlen) < 0) { DEBUG(LOG_NOTICE, 0, "Could not set send socket buffer size"); } if (getsockopt(DEV_NR(i).psock, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize, &optlen) == 0) { alog(LOG_NOTICE, 0, __FUNCTION__, "RAW send socket buffer size set to %d", bufsize); }#endif /* Set max allowable receive buffer size... */ for (;; bufsize -= 1024) { if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize, optlen) == 0) { alog(LOG_NOTICE, 0, __FUNCTION__, "Receive buffer size set to %d", bufsize); break; } if (bufsize < RECV_BUF_SIZE) { alog(LOG_ERR, 0, __FUNCTION__, "Could not set receive buffer size"); exit(-1); } } retval = attach_callback_func(DEV_NR(i).sock, aodv_socket_read); if (retval < 0) { perror("register input handler failed "); exit(-1); } }#endif /* NS_PORT */ num_rreq = 0; num_rerr = 0;}void NS_CLASS aodv_socket_process_packet(AODV_msg * aodv_msg, int len, struct in_addr src, struct in_addr dst, int ttl, unsigned int ifindex){ /* If this was a HELLO message... Process as HELLO. */ if ((aodv_msg->type == AODV_RREP && ttl == 1 && dst.s_addr == AODV_BROADCAST)) { hello_process((RREP *) aodv_msg, len, ifindex); return; } /* Make sure we add/update neighbors */ neighbor_add(aodv_msg, src, ifindex); /* Check what type of msg we received and call the corresponding function to handle the msg... */ switch (aodv_msg->type) { case AODV_RREQ: rreq_process((RREQ *) aodv_msg, len, src, dst, ttl, ifindex); break; case AODV_RREP: DEBUG(LOG_DEBUG, 0, "Received RREP"); rrep_process((RREP *) aodv_msg, len, src, dst, ttl, ifindex); break; case AODV_RERR: DEBUG(LOG_DEBUG, 0, "Received RERR"); rerr_process((RERR *) aodv_msg, len, src, dst); break; case AODV_RREP_ACK: DEBUG(LOG_DEBUG, 0, "Received RREP_ACK"); rrep_ack_process((RREP_ack *) aodv_msg, len, src, dst); break; default: alog(LOG_WARNING, 0, __FUNCTION__, "Unknown msg type %u rcvd from %s to %s", aodv_msg->type, ip_to_str(src), ip_to_str(dst)); }}#ifdef NS_PORTvoid NS_CLASS recvAODVUUPacket(Packet * p){ int len, i, ttl = 0; struct in_addr src, dst; struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); hdr_aodvuu *ah = HDR_AODVUU(p); src.s_addr = ih->saddr(); dst.s_addr = ih->daddr(); len = ch->size() - IP_HDR_LEN; ttl = ih->ttl(); AODV_msg *aodv_msg = (AODV_msg *) recv_buf; /* Only handle AODVUU packets */ assert(ch->ptype() == PT_AODVUU); /* Only process incoming packets */ assert(ch->direction() == hdr_cmn::UP); /* Copy message to receive buffer */ memcpy(recv_buf, ah, RECV_BUF_SIZE); /* Deallocate packet, we have the information we need... */ Packet::free(p); /* Ignore messages generated locally */ for (i = 0; i < MAX_NR_INTERFACES; i++) if (this_host.devs[i].enabled && memcmp(&src, &this_host.devs[i].ipaddr, sizeof(struct in_addr)) == 0) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -