ospf_network.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:6k
源码类别:

网络

开发平台:

Unix_Linux

  1. /*
  2.  * OSPF network related functions
  3.  *   Copyright (C) 1999 Toshiaki Takada
  4.  *
  5.  * This file is part of GNU Zebra.
  6.  *
  7.  * GNU Zebra is free software; you can redistribute it and/or modify it
  8.  * under the terms of the GNU General Public License as published by the
  9.  * Free Software Foundation; either version 2, or (at your option) any
  10.  * later version.
  11.  *
  12.  * GNU Zebra is distributed in the hope that it will be useful, but
  13.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
  19.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20.  * 02111-1307, USA.
  21.  */
  22. #include <zebra.h>
  23. #include "thread.h"
  24. #include "linklist.h"
  25. #include "prefix.h"
  26. #include "if.h"
  27. #include "sockunion.h"
  28. #include "log.h"
  29. #include "sockopt.h"
  30. #include "ospfd/ospfd.h"
  31. #include "ospfd/ospf_network.h"
  32. #include "ospfd/ospf_interface.h"
  33. #include "ospfd/ospf_asbr.h"
  34. #include "ospfd/ospf_lsa.h"
  35. #include "ospfd/ospf_lsdb.h"
  36. #include "ospfd/ospf_neighbor.h"
  37. #include "ospfd/ospf_packet.h"
  38. /* Join to the OSPF ALL SPF ROUTERS multicast group. */
  39. int
  40. ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p,
  41.    unsigned int ifindex)
  42. {
  43.   int ret;
  44.   
  45.   ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP,
  46.                                    p->u.prefix4, htonl (OSPF_ALLSPFROUTERS),
  47.                                    ifindex);
  48.   if (ret < 0)
  49.     zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (AllSPFRouters): %s",
  50.                strerror (errno));
  51.   else
  52.     zlog_info ("interface %s join AllSPFRouters Multicast group.",
  53.        inet_ntoa (p->u.prefix4));
  54.   return ret;
  55. }
  56. int
  57. ospf_if_drop_allspfrouters (struct ospf *top, struct prefix *p,
  58.     unsigned int ifindex)
  59. {
  60.   int ret;
  61.   ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP,
  62.                                    p->u.prefix4, htonl (OSPF_ALLSPFROUTERS),
  63.                                    ifindex);
  64.   if (ret < 0)
  65.     zlog_warn("can't setsockopt IP_DROP_MEMBERSHIP (AllSPFRouters): %s",
  66.       strerror (errno));
  67.   else
  68.     zlog_info ("interface %s leave AllSPFRouters Multicast group.",
  69.        inet_ntoa (p->u.prefix4));
  70.   return ret;
  71. }
  72. /* Join to the OSPF ALL Designated ROUTERS multicast group. */
  73. int
  74. ospf_if_add_alldrouters (struct ospf *top, struct prefix *p, unsigned int
  75.  ifindex)
  76. {
  77.   int ret;
  78.   ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP,
  79.                                    p->u.prefix4, htonl (OSPF_ALLDROUTERS),
  80.                                    ifindex);
  81.   if (ret < 0)
  82.     zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (AllDRouters): %s",
  83.                strerror (errno));
  84.   else
  85.     zlog_info ("interface %s join AllDRouters Multicast group.",
  86.        inet_ntoa (p->u.prefix4));
  87.   return ret;
  88. }
  89. int
  90. ospf_if_drop_alldrouters (struct ospf *top, struct prefix *p, unsigned int
  91.   ifindex)
  92. {
  93.   int ret;
  94.   ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP,
  95.                                    p->u.prefix4, htonl (OSPF_ALLDROUTERS),
  96.                                    ifindex);
  97.   if (ret < 0)
  98.     zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (AllDRouters): %s",
  99.        strerror (errno));
  100.   else
  101.     zlog_info ("interface %s leave AllDRouters Multicast group.",
  102.        inet_ntoa (p->u.prefix4));
  103.   return ret;
  104. }
  105. int
  106. ospf_if_ipmulticast (struct ospf *top, struct prefix *p, unsigned int ifindex)
  107. {
  108.   u_char val;
  109.   int ret, len;
  110.   
  111.   val = 0;
  112.   len = sizeof (val);
  113.   
  114.   /* Prevent receiving self-origined multicast packets. */
  115.   ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&val, len);
  116.   if (ret < 0)
  117.     zlog_warn ("can't setsockopt IP_MULTICAST_LOOP(0): %s", strerror (errno));
  118.   
  119.   /* Explicitly set multicast ttl to 1 -- endo. */
  120.   val = 1;
  121.   ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len);
  122.   if (ret < 0)
  123.     zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1): %s", strerror (errno));
  124.   ret = setsockopt_multicast_ipv4 (top->fd, IP_MULTICAST_IF,
  125.                                    p->u.prefix4, 0, ifindex);
  126.   if (ret < 0)
  127.     zlog_warn ("can't setsockopt IP_MULTICAST_IF: %s", strerror (errno));
  128.   return ret;
  129. }
  130. int
  131. ospf_sock_init (void)
  132. {
  133.   int ospf_sock;
  134.   int ret, tos, hincl = 1;
  135.   ospf_sock = socket (AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
  136.   if (ospf_sock < 0)
  137.     {
  138.       zlog_warn ("ospf_read_sock_init: socket: %s", strerror (errno));
  139.       return -1;
  140.     }
  141.   /* Set precedence field. */
  142. #ifdef IPTOS_PREC_INTERNETCONTROL
  143.   tos = IPTOS_PREC_INTERNETCONTROL;
  144.   ret = setsockopt (ospf_sock, IPPROTO_IP, IP_TOS,
  145.     (char *) &tos, sizeof (int));
  146.   if (ret < 0)
  147.     {
  148.       zlog_warn ("can't set sockopt IP_TOS %d to socket %d", tos, ospf_sock);
  149.       close (ospf_sock); /* Prevent sd leak. */
  150.       return ret;
  151.     }
  152. #endif /* IPTOS_PREC_INTERNETCONTROL */
  153.   /* we will include IP header with packet */
  154.   ret = setsockopt (ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof (hincl));
  155.   if (ret < 0)
  156.     zlog_warn ("Can't set IP_HDRINCL option");
  157. #if defined (IP_PKTINFO)
  158.   ret = setsockopt (ospf_sock, IPPROTO_IP, IP_PKTINFO, &hincl, sizeof (hincl));
  159.    if (ret < 0)
  160.     zlog_warn ("Can't set IP_PKTINFO option");
  161. #elif defined (IP_RECVIF)
  162.   ret = setsockopt (ospf_sock, IPPROTO_IP, IP_RECVIF, &hincl, sizeof (hincl));
  163.    if (ret < 0)
  164.     zlog_warn ("Can't set IP_RECVIF option");
  165. #else
  166. #warning "cannot be able to receive link information on this OS"
  167. #endif
  168.  
  169.   return ospf_sock;
  170. }