NETWORK ATTACKS FRAMEWORK  1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
NA_aodv_socket.cc
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * Copyright (C) 2001 Uppsala University and Ericsson AB.
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  * Authors: Erik Nordstr�, <erik.nordstrom@it.uu.se>
00020  *
00021  *****************************************************************************/
00022 
00023 #define NS_PORT
00024 #define OMNETPP
00025 
00026 #include <sys/types.h>
00027 
00028 #ifdef NS_PORT
00029 #ifndef OMNETPP
00030 #include "ns/aodv-uu.h"
00031 #else
00032 #include "../NA_aodv_uu_omnet.h"
00033 #endif
00034 #else
00035 #include <sys/socket.h>
00036 #include <netinet/in.h>
00037 #include <net/if.h>
00038 #include <netinet/udp.h>
00039 #include "NA_aodv_socket.h"
00040 #include "NA_timer_queue_aodv.h"
00041 #include "NA_aodv_rreq.h"
00042 #include "NA_aodv_rerr.h"
00043 #include "NA_aodv_rrep.h"
00044 #include "NA_params.h"
00045 #include "NA_aodv_hello.h"
00046 #include "NA_aodv_neighbor.h"
00047 #include "NA_debug_aodv.h"
00048 #include "NA_defs_aodv.h"
00049 
00050 #endif              /* NS_PORT */
00051 
00052 
00053 #ifndef NS_PORT
00054 #define SO_RECVBUF_SIZE 256*1024
00055 
00056 static char recv_buf[RECV_BUF_SIZE];
00057 static char send_buf[SEND_BUF_SIZE];
00058 
00059 extern int wait_on_reboot, hello_qual_threshold, ratelimit;
00060 
00061 static void aodv_socket_read(int fd);
00062 
00063 /* Seems that some libc (for example ulibc) has a bug in the provided
00064  * CMSG_NXTHDR() routine... redefining it here */
00065 
00066 static struct cmsghdr *__cmsg_nxthdr_fix(void *__ctl, size_t __size,
00067         struct cmsghdr *__cmsg)
00068 {
00069     struct cmsghdr *__ptr;
00070 
00071     __ptr = (struct cmsghdr *) (((unsigned char *) __cmsg) +
00072                                 CMSG_ALIGN(__cmsg->cmsg_len));
00073     if ((unsigned long) ((char *) (__ptr + 1) - (char *) __ctl) > __size)
00074         return NULL;
00075 
00076     return __ptr;
00077 }
00078 
00079 struct cmsghdr *cmsg_nxthdr_fix(struct msghdr *__msg, struct cmsghdr *__cmsg)
00080 {
00081     return __cmsg_nxthdr_fix(__msg->msg_control, __msg->msg_controllen, __cmsg);
00082 }
00083 
00084 #endif              /* NS_PORT */
00085 
00086 
00087 void NS_CLASS aodv_socket_init()
00088 {
00089 #ifndef NS_PORT
00090     struct sockaddr_in aodv_addr;
00091     struct ifreq ifr;
00092     int i, retval = 0;
00093     int on = 1;
00094     int tos = IPTOS_LOWDELAY;
00095     int bufsize = SO_RECVBUF_SIZE;
00096     socklen_t optlen = sizeof(bufsize);
00097 
00098     /* Create a UDP socket */
00099 
00100     if (this_host.nif == 0)
00101     {
00102         fprintf(stderr, "No interfaces configured\n");
00103         exit(-1);
00104     }
00105 
00106     /* Open a socket for every AODV enabled interface */
00107     for (i = 0; i < MAX_NR_INTERFACES; i++)
00108     {
00109         if (!DEV_NR(i).enabled)
00110             continue;
00111 
00112         /* AODV socket */
00113         DEV_NR(i).sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00114         if (DEV_NR(i).sock < 0)
00115         {
00116             perror("");
00117             exit(-1);
00118         }
00119 #ifdef CONFIG_GATEWAY
00120         /* Data packet send socket */
00121         DEV_NR(i).psock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
00122 
00123         if (DEV_NR(i).psock < 0)
00124         {
00125             perror("");
00126             exit(-1);
00127         }
00128 #endif
00129         /* Bind the socket to the AODV port number */
00130         memset(&aodv_addr, 0, sizeof(aodv_addr));
00131         aodv_addr.sin_family = AF_INET;
00132         aodv_addr.sin_port = htons(AODV_PORT);
00133         aodv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
00134 
00135         retval = bind(DEV_NR(i).sock, (struct sockaddr *) &aodv_addr,
00136                       sizeof(struct sockaddr));
00137 
00138         if (retval < 0)
00139         {
00140             perror("Bind failed ");
00141             exit(-1);
00142         }
00143         if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_BROADCAST,
00144                        &on, sizeof(int)) < 0)
00145         {
00146             perror("SO_BROADCAST failed ");
00147             exit(-1);
00148         }
00149 
00150         memset(&ifr, 0, sizeof(struct ifreq));
00151         strcpy(ifr.ifr_name, DEV_NR(i).ifname);
00152 
00153         if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_BINDTODEVICE,
00154                        &ifr, sizeof(ifr)) < 0)
00155         {
00156             fprintf(stderr, "SO_BINDTODEVICE failed for %s", DEV_NR(i).ifname);
00157             perror(" ");
00158             exit(-1);
00159         }
00160 
00161         if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_PRIORITY,
00162                        &tos, sizeof(int)) < 0)
00163         {
00164             perror("Setsockopt SO_PRIORITY failed ");
00165             exit(-1);
00166         }
00167 
00168         if (setsockopt(DEV_NR(i).sock, SOL_IP, IP_RECVTTL,
00169                        &on, sizeof(int)) < 0)
00170         {
00171             perror("Setsockopt IP_RECVTTL failed ");
00172             exit(-1);
00173         }
00174 
00175         if (setsockopt(DEV_NR(i).sock, SOL_IP, IP_PKTINFO,
00176                        &on, sizeof(int)) < 0)
00177         {
00178             perror("Setsockopt IP_PKTINFO failed ");
00179             exit(-1);
00180         }
00181 #ifdef CONFIG_GATEWAY
00182         if (setsockopt(DEV_NR(i).psock, SOL_SOCKET, SO_BINDTODEVICE,
00183                        &ifr, sizeof(ifr)) < 0)
00184         {
00185             fprintf(stderr, "SO_BINDTODEVICE failed for %s", DEV_NR(i).ifname);
00186             perror(" ");
00187             exit(-1);
00188         }
00189 
00190         bufsize = 4 * 65535;
00191 
00192         if (setsockopt(DEV_NR(i).psock, SOL_SOCKET, SO_SNDBUF,
00193                        (char *) &bufsize, optlen) < 0)
00194         {
00195             DEBUG(LOG_NOTICE, 0, "Could not set send socket buffer size");
00196         }
00197         if (getsockopt(DEV_NR(i).psock, SOL_SOCKET, SO_SNDBUF,
00198                        (char *) &bufsize, &optlen) == 0)
00199         {
00200             alog(LOG_NOTICE, 0, __FUNCTION__,
00201                  "RAW send socket buffer size set to %d", bufsize);
00202         }
00203 #endif
00204         /* Set max allowable receive buffer size... */
00205         for (;; bufsize -= 1024)
00206         {
00207             if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_RCVBUF,
00208                            (char *) &bufsize, optlen) == 0)
00209             {
00210                 alog(LOG_NOTICE, 0, __FUNCTION__,
00211                      "Receive buffer size set to %d", bufsize);
00212                 break;
00213             }
00214             if (bufsize < RECV_BUF_SIZE)
00215             {
00216                 alog(LOG_ERR, 0, __FUNCTION__,
00217                      "Could not set receive buffer size");
00218                 exit(-1);
00219             }
00220         }
00221 
00222         retval = attach_callback_func(DEV_NR(i).sock, aodv_socket_read);
00223 
00224         if (retval < 0)
00225         {
00226             perror("register input handler failed ");
00227             exit(-1);
00228         }
00229     }
00230 #endif              /* NS_PORT */
00231 
00232     num_rreq = 0;
00233     num_rerr = 0;
00234 }
00235 
00236 void NS_CLASS aodv_socket_process_packet(AODV_msg * aodv_msg, int len,
00237         struct in_addr src,
00238         struct in_addr dst,
00239         int ttl, unsigned int ifindex)
00240 {
00241     /* If this was a HELLO message... Process as HELLO. */
00242 #ifndef OMNETPP
00243     if ((aodv_msg->type == AODV_RREP && ttl == 1 &&
00244             dst.s_addr == AODV_BROADCAST))
00245     {
00246         hello_process((RREP *) aodv_msg, len, ifindex);
00247         return;
00248     }
00249 #else
00250     if ((aodv_msg->type == AODV_RREP && ttl == 0 && // ttl is decremented for ip layer before send to aodv
00251             dst.s_addr == ManetAddress(IPv4Address(AODV_BROADCAST))))
00252     {
00253         hello_process((RREP *) aodv_msg, len, ifindex);
00254         return;
00255     }
00256 #endif
00257     /* Make sure we add/update neighbors */
00258     neighbor_add(aodv_msg, src, ifindex);
00259 
00260     /* Check what type of msg we received and call the corresponding
00261        function to handle the msg... */
00262     switch (aodv_msg->type)
00263     {
00264 
00265     case AODV_RREQ:
00266         rreq_process((RREQ *) aodv_msg, len, src, dst, ttl, ifindex);
00267         break;
00268     case AODV_RREP:
00269         DEBUG(LOG_DEBUG, 0, "Received RREP");
00270         rrep_process((RREP *) aodv_msg, len, src, dst, ttl, ifindex);
00271         break;
00272     case AODV_RERR:
00273         DEBUG(LOG_DEBUG, 0, "Received RERR");
00274         rerr_process((RERR *) aodv_msg, len, src, dst);
00275         break;
00276     case AODV_RREP_ACK:
00277         DEBUG(LOG_DEBUG, 0, "Received RREP_ACK");
00278         rrep_ack_process((RREP_ack *) aodv_msg, len, src, dst);
00279         break;
00280     default:
00281         alog(LOG_WARNING, 0, __FUNCTION__,
00282              "Unknown msg type %u rcvd from %s to %s", aodv_msg->type,
00283              ip_to_str(src), ip_to_str(dst));
00284         break;
00285     }
00286 }
00287 
00288 #ifdef NS_PORT
00289 #ifndef OMNETPP
00290 void NS_CLASS recvAODVUUPacket(Packet * p)
00291 {
00292     int len, i, ttl = 0;
00293     struct in_addr src, dst;
00294     struct hdr_cmn *ch = HDR_CMN(p);
00295     struct hdr_ip *ih = HDR_IP(p);
00296     hdr_aodvuu *ah = HDR_AODVUU(p);
00297 
00298     src.s_addr = ih->saddr();
00299     dst.s_addr = ih->daddr();
00300     len = ch->size() - IP_HDR_LEN;
00301     ttl = ih->ttl();
00302 
00303     AODV_msg *aodv_msg = (AODV_msg *) recv_buf;
00304 
00305     /* Only handle AODVUU packets */
00306     assert(ch->ptype() == PT_AODVUU);
00307 
00308     /* Only process incoming packets */
00309     assert(ch->direction() == hdr_cmn::UP);
00310 
00311     /* Copy message to receive buffer */
00312     memcpy(recv_buf, ah, RECV_BUF_SIZE);
00313 
00314     /* Deallocate packet, we have the information we need... */
00315     Packet::free(p);
00316 
00317     /* Ignore messages generated locally */
00318     for (i = 0; i < MAX_NR_INTERFACES; i++)
00319         if (this_host.devs[i].enabled &&
00320                 memcmp(&src, &this_host.devs[i].ipaddr,
00321                        sizeof(struct in_addr)) == 0)
00322             return;
00323 
00324     aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, NS_IFINDEX);
00325 }
00326 #endif /*no omnet++*/
00327 #else
00328 static void aodv_socket_read(int fd)
00329 {
00330     struct in_addr src, dst;
00331     int i, len, ttl = -1;
00332     AODV_msg *aodv_msg;
00333     struct dev_info *dev;
00334     struct msghdr msgh;
00335     struct cmsghdr *cmsg;
00336     struct iovec iov;
00337     char ctrlbuf[CMSG_SPACE(sizeof(int)) +
00338                  CMSG_SPACE(sizeof(struct in_pktinfo))];
00339     struct sockaddr_in src_addr;
00340 
00341     iov.iov_base = recv_buf;
00342     iov.iov_len = RECV_BUF_SIZE;
00343     msgh.msg_name = &src_addr;
00344     msgh.msg_namelen = sizeof(src_addr);
00345     msgh.msg_iov = &iov;
00346     msgh.msg_iovlen = 1;
00347     msgh.msg_control = ctrlbuf;
00348     msgh.msg_controllen = sizeof(ctrlbuf);
00349 
00350     len = recvmsg(fd, &msgh, 0);
00351 
00352     if (len < 0)
00353     {
00354         alog(LOG_WARNING, 0, __FUNCTION__, "receive ERROR len=%d!", len);
00355         return;
00356     }
00357 
00358     src.s_addr = src_addr.sin_addr.s_addr;
00359 
00360     /* Get the ttl and destination address from the control message */
00361     for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
00362             cmsg = CMSG_NXTHDR_FIX(&msgh, cmsg))
00363     {
00364         if (cmsg->cmsg_level == SOL_IP)
00365         {
00366             switch (cmsg->cmsg_type)
00367             {
00368             case IP_TTL:
00369                 ttl = *(CMSG_DATA(cmsg));
00370                 break;
00371             case IP_PKTINFO:
00372                 dst.s_addr =
00373                     ((struct in_pktinfo *) CMSG_DATA(cmsg))->ipi_addr.s_addr;
00374             }
00375         }
00376     }
00377 
00378     if (ttl < 0)
00379     {
00380         DEBUG(LOG_DEBUG, 0, "No TTL, packet ignored!");
00381         return;
00382     }
00383 
00384     /* Ignore messages generated locally */
00385     for (i = 0; i < MAX_NR_INTERFACES; i++)
00386         if (this_host.devs[i].enabled &&
00387                 memcmp(&src, &this_host.devs[i].ipaddr,
00388                        sizeof(struct in_addr)) == 0)
00389             return;
00390 
00391     aodv_msg = (AODV_msg *) recv_buf;
00392 
00393     dev = devfromsock(fd);
00394 
00395     if (!dev)
00396     {
00397         DEBUG(LOG_ERR, 0, "Could not get device info!\n");
00398         return;
00399     }
00400 
00401     aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, dev->ifindex);
00402 }
00403 #endif              /* NS_PORT */
00404 
00405 void NS_CLASS aodv_socket_send(AODV_msg * aodv_msg, struct in_addr dst,
00406                                int len, u_int8_t ttl, struct dev_info *dev,double delay)
00407 {
00408 
00409     struct timeval now;
00410     int retval = 0;
00411     /* Rate limit stuff: */
00412 
00413 #ifdef OMNETPP
00414     if (ttl<=0)
00415     {
00416         delete aodv_msg;
00417         return;
00418     }
00419 #endif
00420 
00421 #ifndef NS_PORT
00422 
00423     struct sockaddr_in dst_addr;
00424 
00425     if (wait_on_reboot && aodv_msg->type == AODV_RREP)
00426         return;
00427 
00428     memset(&dst_addr, 0, sizeof(dst_addr));
00429     dst_addr.sin_family = AF_INET;
00430     dst_addr.sin_addr = dst;
00431     dst_addr.sin_port = htons(AODV_PORT);
00432 
00433     /* Set ttl */
00434     if (setsockopt(dev->sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)) < 0)
00435     {
00436         alog(LOG_WARNING, 0, __FUNCTION__, "ERROR setting ttl!");
00437         return;
00438     }
00439 #else
00440 
00441     /*
00442        NS_PORT: Sending of AODV_msg messages to other AODV-UU routing agents
00443        by encapsulating them in a Packet.
00444 
00445        Note: This method is _only_ for sending AODV packets to other routing
00446        agents, _not_ for forwarding "regular" IP packets!
00447      */
00448 
00449     /* If we are in waiting phase after reboot, don't send any RREPs */
00450     if (wait_on_reboot && aodv_msg->type == AODV_RREP)
00451     {
00452 #ifdef OMNETPP
00453         delete aodv_msg;
00454 #endif
00455         return;
00456     }
00457 #ifndef OMNETPP
00458     /*
00459        NS_PORT: Don't allocate packet until now. Otherwise packet uid
00460        (unique ID) space is unnecessarily exhausted at the beginning of
00461        the simulation, resulting in uid:s starting at values greater than 0.
00462      */
00463     Packet *p = allocpkt();
00464     struct hdr_cmn *ch = HDR_CMN(p);
00465     struct hdr_ip *ih = HDR_IP(p);
00466     hdr_aodvuu *ah = HDR_AODVUU(p);
00467 
00468     // Clear AODVUU part of packet
00469     memset(ah, '\0', ah->size());
00470 
00471     // Copy message contents into packet
00472     memcpy(ah, aodv_msg, len);
00473 
00474     // Set common header fields
00475     ch->ptype() = PT_AODVUU;
00476     ch->direction() = hdr_cmn::DOWN;
00477     ch->size() = IP_HDR_LEN + len;
00478     ch->iface() = -2;
00479     ch->getBitErrorRate() = 0;
00480     ch->prev_hop_ = (nsaddr_t) dev->ipaddr.s_addr;
00481 
00482     // Set IP header fields
00483     ih->saddr() = (nsaddr_t) dev->ipaddr.s_addr;
00484     ih->daddr() = (nsaddr_t) dst.s_addr;
00485     ih->ttl() = ttl;
00486 
00487     // Note: Port number for routing agents, not AODV port number!
00488     ih->sport() = RT_PORT;
00489     ih->dport() = RT_PORT;
00490 
00491     // Fake success
00492     retval = len;
00493 #endif /*omnet++ */
00494 #endif              /* NS_PORT */
00495 
00496     /* If rate limiting is enabled, check if we are sending either a
00497        RREQ or a RERR. In that case, drop the outgoing control packet
00498        if the time since last transmit of that type of packet is less
00499        than the allowed RATE LIMIT time... */
00500 
00501     if (ratelimit)
00502     {
00503 
00504         gettimeofday(&now, NULL);
00505 
00506         switch (aodv_msg->type)
00507         {
00508         case AODV_RREQ:
00509             if (num_rreq == (RREQ_RATELIMIT - 1))
00510             {
00511                 if (timeval_diff(&now, &rreq_ratel[0]) < 1000)
00512                 {
00513                     DEBUG(LOG_DEBUG, 0, "RATELIMIT: Dropping RREQ %ld ms",
00514                           timeval_diff(&now, &rreq_ratel[0]));
00515 #ifdef OMNETPP
00516                     delete aodv_msg;
00517 #else
00518 #ifdef NS_PORT
00519                     Packet::free(p);
00520 #endif
00521 #endif
00522                     return;
00523                 }
00524                 else
00525                 {
00526                     memmove(rreq_ratel, &rreq_ratel[1],
00527                             sizeof(struct timeval) * (num_rreq - 1));
00528                     memcpy(&rreq_ratel[num_rreq - 1], &now,
00529                            sizeof(struct timeval));
00530                 }
00531             }
00532             else
00533             {
00534                 memcpy(&rreq_ratel[num_rreq], &now, sizeof(struct timeval));
00535                 num_rreq++;
00536             }
00537             break;
00538         case AODV_RERR:
00539             if (num_rerr == (RERR_RATELIMIT - 1))
00540             {
00541                 if (timeval_diff(&now, &rerr_ratel[0]) < 1000)
00542                 {
00543                     DEBUG(LOG_DEBUG, 0, "RATELIMIT: Dropping RERR %ld ms",
00544                           timeval_diff(&now, &rerr_ratel[0]));
00545 #ifdef OMNETPP
00546                     delete aodv_msg;
00547 #else
00548 #ifdef NS_PORT
00549                     Packet::free(p);
00550 #endif
00551 #endif
00552                     return;
00553                 }
00554                 else
00555                 {
00556                     memmove(rerr_ratel, &rerr_ratel[1],
00557                             sizeof(struct timeval) * (num_rerr - 1));
00558                     memcpy(&rerr_ratel[num_rerr - 1], &now,
00559                            sizeof(struct timeval));
00560                 }
00561             }
00562             else
00563             {
00564                 memcpy(&rerr_ratel[num_rerr], &now, sizeof(struct timeval));
00565                 num_rerr++;
00566             }
00567             break;
00568         }
00569     }
00570 
00571     /* If we broadcast this message we update the time of last broadcast
00572        to prevent unnecessary broadcasts of HELLO msg's */
00573     if (dst.s_addr == ManetAddress(IPv4Address(AODV_BROADCAST)))
00574     {
00575         gettimeofday(&this_host.bcast_time, NULL);
00576 
00577 #ifdef NS_PORT
00578 #ifndef OMNETPP
00579         ch->addr_type() = NS_AF_NONE;
00580         sendPacket(p, dst, 0.0);
00581 #else
00582 //       IPv4Address   desAddIp4(dst.s_addr);
00583 //       IPvXAddress destAdd(desAddIp4);
00584 // In the floading proccess the random delay prevent collision for the synchronization between the nodes.
00585         ManetAddress destAdd;
00586         aodv_msg->prevFix=this->isStaticNode();
00587 
00588         if (this->isStaticNode())
00589         {
00590             if (dynamic_cast<RREP*>(aodv_msg))
00591             {
00592                 dynamic_cast<RREP*>(aodv_msg)->cost += costStatic;
00593             }
00594             else if (dynamic_cast<RREQ*> (aodv_msg))
00595             {
00596                 dynamic_cast<RREQ*>(aodv_msg)->cost += costStatic;
00597             }
00598         }
00599         else
00600         {
00601             if (dynamic_cast<RREP*>(aodv_msg))
00602             {
00603                 dynamic_cast<RREP*>(aodv_msg)->cost += costMobile;
00604             }
00605             else if (dynamic_cast<RREQ*>(aodv_msg))
00606             {
00607                 dynamic_cast<RREQ*>(aodv_msg)->cost += costMobile;
00608             }
00609         }
00610 
00611 
00612 
00613         if (dst.s_addr == ManetAddress(IPv4Address(AODV_BROADCAST)))
00614         {
00615             destAdd = ManetAddress(IPv4Address::ALLONES_ADDRESS);
00616         }
00617         else
00618         {
00619             destAdd = dst.s_addr;
00620         }
00621         if (delay>0)
00622         {
00623             if (useIndex)
00624                 sendToIp(aodv_msg, 654, destAdd, 654, ttl, delay, dev->ifindex);
00625             else
00626                 sendToIp(aodv_msg, 654, destAdd, 654, ttl, delay, dev->ipaddr.s_addr);
00627         }
00628         else
00629         {
00630             if (useIndex)
00631                 sendToIp(aodv_msg, 654, destAdd, 654, ttl, par ("broadcastDelay").doubleValue(), dev->ifindex);
00632             else
00633                 sendToIp(aodv_msg, 654, destAdd, 654, ttl, par ("broadcastDelay").doubleValue(), dev->ipaddr.s_addr);
00634         }
00635         totalSend++;
00636 //       sendToIp(aodv_msg, 654, destAdd, 654,ttl);
00637 #endif /*omnet++ */
00638 #else
00639         retval = sendto(dev->sock, send_buf, len, 0,
00640                         (struct sockaddr *) &dst_addr, sizeof(dst_addr));
00641 
00642         if (retval < 0)
00643         {
00644             alog(LOG_WARNING, errno, __FUNCTION__, "Failed send to bc %s",
00645                  ip_to_str(dst));
00646             return;
00647         }
00648 #endif
00649     }
00650     else
00651     {
00652 
00653 #ifdef NS_PORT
00654 #ifndef OMNETPP
00655         ch->addr_type() = NS_AF_INET;
00656         /* We trust the decision of next hop for all AODV messages... */
00657         if (dst.s_addr == AODV_BROADCAST)
00658             sendPacket(p, dst, 0.001 * Random::uniform());
00659         else
00660             sendPacket(p, dst, 0.0);
00661 #else
00662         // IPv4Address   desAddIp4(dst.s_addr);
00663         // IPvXAddress destAdd(desAddIp4);
00664         ManetAddress destAdd;
00665         if (dst.s_addr == ManetAddress(IPv4Address(AODV_BROADCAST)))
00666         {
00667             destAdd = ManetAddress(IPv4Address::ALLONES_ADDRESS);
00668             if (delay>0)
00669             {
00670                 if (useIndex)
00671                     sendToIp(aodv_msg, 654, destAdd, 654,ttl,delay,dev->ifindex);
00672                 else
00673                     sendToIp(aodv_msg, 654, destAdd, 654,ttl,delay,dev->ipaddr.s_addr);
00674             }
00675             else
00676             {
00677                 if (useIndex)
00678                     sendToIp(aodv_msg, 654, destAdd, 654,ttl,par("broadcastDelay").doubleValue(),dev->ifindex);
00679                 else
00680                     sendToIp(aodv_msg, 654, destAdd, 654,ttl,par("broadcastDelay").doubleValue(),dev->ipaddr.s_addr);
00681             }
00682         }
00683         else
00684         {
00685             destAdd = dst.s_addr;
00686             if (delay>0)
00687             {
00688                 if (useIndex)
00689                     sendToIp(aodv_msg, 654, destAdd, 654,ttl,delay,dev->ifindex);
00690                 else
00691                     sendToIp(aodv_msg, 654, destAdd, 654,ttl,delay,dev->ipaddr.s_addr);
00692             }
00693             else
00694             {
00695                 if (useIndex)
00696                     sendToIp(aodv_msg, 654, destAdd, 654,ttl,par("unicastDelay").doubleValue(),dev->ifindex);
00697                 else
00698                     sendToIp(aodv_msg, 654, destAdd, 654,ttl,par("unicastDelay").doubleValue(),dev->ipaddr.s_addr);
00699             }
00700         }
00701         totalSend++;
00702 #endif
00703 #else
00704         retval = sendto(dev->sock, send_buf, len, 0,
00705                         (struct sockaddr *) &dst_addr, sizeof(dst_addr));
00706 
00707         if (retval < 0)
00708         {
00709             alog(LOG_WARNING, errno, __FUNCTION__, "Failed send to %s",
00710                  ip_to_str(dst));
00711             return;
00712         }
00713 #endif
00714     }
00715 
00716     /* Do not print hello msgs... */
00717     if (!(aodv_msg->type == AODV_RREP && (dst.s_addr == ManetAddress(IPv4Address(AODV_BROADCAST)))))
00718         DEBUG(LOG_INFO, 0, "AODV msg to %s ttl=%d retval=%u size=%u",
00719               ip_to_str(dst), ttl, retval, len);
00720 
00721     return;
00722 }
00723 
00724 
00725 
00726 
00727 #ifndef OMNETPP
00728 AODV_msg *NS_CLASS aodv_socket_new_msg(void)
00729 {
00730     memset(send_buf, '\0', SEND_BUF_SIZE);
00731     return (AODV_msg *) (send_buf);
00732 }
00733 
00734 /* Copy an existing AODV message to the send buffer */
00735 AODV_msg *NS_CLASS aodv_socket_queue_msg(AODV_msg * aodv_msg, int size)
00736 {
00737     memcpy((char *) send_buf, aodv_msg, size);
00738     return (AODV_msg *) send_buf;
00739 }
00740 #endif
00741 void aodv_socket_cleanup(void)
00742 {
00743 #ifndef NS_PORT
00744     int i;
00745 
00746     for (i = 0; i < MAX_NR_INTERFACES; i++)
00747     {
00748         if (!DEV_NR(i).enabled)
00749             continue;
00750         close(DEV_NR(i).sock);
00751     }
00752 #endif              /* NS_PORT */
00753 }
00754 
 All Classes Files Functions Variables Typedefs Enumerator Defines