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

📄 ospf6_message.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 4 页
字号:
      OSPF6_MESSAGE_ATTACH (response, lsa->header, ntohs (lsa->header->length));      lsanum++;    }  /* send response LSUpdate to this request */  if (lsanum)    {      lsupdate.lsupdate_num = htonl (lsanum);      ospf6_message_send (OSPF6_MESSAGE_TYPE_LSUPDATE, response,                          &o6n->hisaddr, o6i->if_id);    }  /* statistics */  o6n->lsa_receive[OSPF6_MESSAGE_TYPE_LSREQ]    += length / sizeof (struct ospf6_lsreq);}voidospf6_process_lsupdate (struct iovec *message,                        struct in6_addr *src,                        struct in6_addr *dst,                        struct ospf6_interface *o6i,                        u_int32_t router_id){  struct ospf6_header *ospf6_header;  u_int16_t length;  struct ospf6_lsupdate *lsupdate;  struct ospf6_neighbor *o6n;  unsigned long lsanum;  struct ospf6_lsa_header *lsa_header;  /* assert interface */  assert (o6i);  /* caluculate length */  ospf6_header = (struct ospf6_header *) message[0].iov_base;  length = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);  length = (length < message[1].iov_len ? length : message[1].iov_len);  /* find neighbor. if cannot be found, reject this message */  o6n = ospf6_neighbor_lookup (router_id, o6i);  if (! o6n)    {      if (IS_OSPF6_DUMP_LSUPDATE)        zlog_info ("  neighbor not found, reject");      return;    }  if (memcmp (src, &o6n->hisaddr, sizeof (struct in6_addr)))    {      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))        zlog_info ("From Secondary I/F of the neighbor: ignore");      return;    }  /* if neighbor state less than ExChange, reject this message */  if (o6n->state < NBS_EXCHANGE)    {      if (IS_OSPF6_DUMP_LSUPDATE)        zlog_info ("  neighbor state less than Exchange, reject");      return;    }  /* set linkstate update pointer */  lsupdate = (struct ospf6_lsupdate *) message[1].iov_base;  /* save linkstate update info */  lsanum = ntohl (lsupdate->lsupdate_num);  /* statistics */  o6n->ospf6_stat_received_lsa += lsanum;  o6n->ospf6_stat_received_lsupdate++;  /* RFC2328 Section 10.9: When the neighbor responds to these requests     with the proper Link State Update packet(s), the Link state request     list is truncated and a new Link State Request packet is sent. */  /* process LSAs */  for (lsa_header = (struct ospf6_lsa_header *) (lsupdate + 1);       lsanum && (char *)lsa_header < (char *)lsupdate + length;       lsanum--)    {      ospf6_dbex_receive_lsa (lsa_header, o6n);      lsa_header = OSPF6_LSA_NEXT (lsa_header);    }  /* send new Link State Request packet if this LS Update packet     can be recognized as a response to our previous LS request */  if (! IN6_IS_ADDR_MULTICAST(dst) &&      (o6n->state == NBS_EXCHANGE || o6n->state == NBS_LOADING))    thread_add_event (master, ospf6_send_lsreq, o6n, 0);  return;}voidospf6_process_lsack (struct iovec *message,                     struct in6_addr *src,                     struct in6_addr *dst,                     struct ospf6_interface *o6i,                     u_int32_t router_id){  struct ospf6_header *ospf6_header;  u_int16_t length;  struct ospf6_neighbor *o6n;  struct ospf6_lsa_header *lsa_header;  struct ospf6_lsa *lsa, *copy, *rem;  /* assert interface */  assert (o6i);  /* caluculate length */  ospf6_header = (struct ospf6_header *) message[0].iov_base;  length = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);  length = (length < message[1].iov_len ? length : message[1].iov_len);  /* find neighbor. if cannot be found, reject this message */  o6n = ospf6_neighbor_lookup (router_id, o6i);  if (!o6n)    {      if (IS_OSPF6_DUMP_LSACK)        zlog_info ("LSACK: neighbor not found, reject");      return;    }  if (memcmp (src, &o6n->hisaddr, sizeof (struct in6_addr)))    {      if (IS_OSPF6_DUMP_LSACK)        zlog_info ("LSACK: From Secondary I/F of the neighbor: ignore");      return;    }  /* if neighbor state less than ExChange, reject this message */  if (o6n->state < NBS_EXCHANGE)    {      if (IS_OSPF6_DUMP_LSACK)        zlog_info ("LSACK: neighbor state less than Exchange, reject");      return;    }  /* process each LSA header */  for (lsa_header = (struct ospf6_lsa_header *) message[1].iov_base;       (char *)(lsa_header + 1) <= (char *)(message[1].iov_base + length);       lsa_header++)    {      /* find database copy */      copy = ospf6_lsdb_lookup (lsa_header->type, lsa_header->ls_id,                                lsa_header->advrtr,                                ospf6_lsa_get_scope (lsa_header->type, o6i));      /* if no database copy */      if (!copy)        {          if (IS_OSPF6_DUMP_LSACK)            zlog_info ("LSACK: no database copy, ignore");          continue;        }      /* if not on his retrans list */      rem = ospf6_lsdb_lookup_lsdb (copy->header->type, copy->header->id,                                    copy->header->adv_router,                                    o6n->retrans_list);      if (rem == NULL)        {          if (IS_OSPF6_DUMP_LSACK)            zlog_info ("LSACK: not on %s's retranslist, ignore", o6n->str);          continue;        }      /* create temporary LSA from Ack message */      lsa = ospf6_lsa_summary_create ((struct ospf6_lsa_header__ *) lsa_header);      /* if the same instance, remove from retrans list.         else, log and ignore */      if (ospf6_lsa_check_recent (lsa, copy) == 0)        ospf6_neighbor_retrans_remove (rem, o6n);      else        {          /* Log the questionable acknowledgement,             and examine the next one. */          zlog_info ("LSACK: questionable acknowledge: %s", copy->str);          zlog_info ("LSACK:   received: seq: %#x age: %hu",                     ntohl (lsa->header->seqnum),                     ntohs (lsa->header->age));          zlog_info ("LSACK:   instance: seq: %#x age: %hu",                     ntohl (copy->header->seqnum),                     ospf6_lsa_age_current (copy));        }      /* release temporary LSA from Ack message */      ospf6_lsa_delete (lsa);    }  ospf6_maxage_remover ();  return;}struct {  void (*process) (struct iovec *, struct in6_addr *, struct in6_addr *,                   struct ospf6_interface *, u_int32_t);} ospf6_message_process_type [] ={  {ospf6_process_unknown},  {ospf6_process_hello},  {ospf6_process_dbdesc},  {ospf6_process_lsreq},  {ospf6_process_lsupdate},  {ospf6_process_lsack}};/* process ospf6 protocol header. then, call next process function   for each message type */static void ospf6_message_process (struct iovec *message,                       struct in6_addr *src,                       struct in6_addr *dst,                       struct ospf6_interface *o6i){  struct ospf6_header *ospf6_header = NULL;  u_char type;  u_int32_t router_id;  char srcname[64];  assert (o6i);  assert (src);  assert (dst);  /* set ospf6_hdr pointer to head of buffer */  ospf6_header = (struct ospf6_header *) message[0].iov_base;  /* version check */  if (ospf6_header->version != OSPF6_VERSION)    {      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))        zlog_info ("version mismatch, drop");      return;    }  /* area id check */  if (ospf6_header->area_id != o6i->area->area_id)    {      if (ospf6_header->area_id == 0)        {          if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))            zlog_info ("virtual link not yet, drop");          return;        }      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))        zlog_info ("area id mismatch, drop");      return;    }  /* instance id check */  if (ospf6_header->instance_id != o6i->instance_id)    {      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))        zlog_info ("instance id mismatch, drop");      return;    }  /* message type check */  type = (ospf6_header->type >= OSPF6_MESSAGE_TYPE_MAX ?          OSPF6_MESSAGE_TYPE_UNKNOWN : ospf6_header->type);  /* log */  if (IS_OSPF6_DUMP_MESSAGE (type))    {      char srcname[64], dstname[64];      inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));      inet_ntop (AF_INET6, src, srcname, sizeof (srcname));      zlog_info ("Receive %s on %s",                 ospf6_message_type_string[type], o6i->interface->name);      zlog_info ("    %s -> %s", srcname, dstname);      ospf6_message_log (message);    }  /* router id check */  router_id = ospf6_header->router_id;  if (ospf6_header->router_id == o6i->area->ospf6->router_id)    {      inet_ntop (AF_INET6, src, srcname, sizeof (srcname));      zlog_warn ("*** Router-ID mismatch: from %s on %s",                 srcname, o6i->interface->name);      return;    }  /* octet statistics relies on some asumption:       on ethernet, no IPv6 Extention header, etc */#define OSPF6_IP6_HEADER_SIZE   40#define OSPF6_ETHER_HEADER_SIZE 14  o6i->message_stat[type].recv++;  o6i->message_stat[type].recv_octet += ntohs (ospf6_header->len)    + OSPF6_IP6_HEADER_SIZE + OSPF6_ETHER_HEADER_SIZE;  /* futher process */  (*ospf6_message_process_type[type].process) (&message[0], src, dst, o6i, router_id);  return;}intospf6_receive (struct thread *thread){  int sockfd;  struct in6_addr src, dst;  unsigned int ifindex;  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_header ospf6_header;  char buffer[OSPF6_MESSAGE_RECEIVE_BUFSIZE];  struct ospf6_interface *o6i;  unsigned char type;  /* get socket */  sockfd = THREAD_FD (thread);  /* add next read thread */  thread_add_read (master, ospf6_receive, NULL, sockfd);  /* initialize */  OSPF6_MESSAGE_CLEAR (message);  memset (&ospf6_header, 0, sizeof (struct ospf6_header));  OSPF6_MESSAGE_ATTACH (message, &ospf6_header, sizeof (struct ospf6_header));  OSPF6_MESSAGE_ATTACH (message, buffer, OSPF6_MESSAGE_RECEIVE_BUFSIZE);  /* receive message */  ospf6_recvmsg (&src, &dst, &ifindex, message);  type = (OSPF6_MESSAGE_TYPE_UNKNOWN < ospf6_header.type &&          ospf6_header.type <= OSPF6_MESSAGE_TYPE_LSACK ?          ospf6_header.type : OSPF6_MESSAGE_TYPE_UNKNOWN);  o6i = ospf6_interface_lookup_by_index (ifindex);  if (!o6i || !o6i->area)    {      //zlog_warn ("*** received interface ospf6 disabled");      return 0;    }  /* if not passive, process message */  if (! CHECK_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE))    ospf6_message_process (message, &src, &dst, o6i);  else if (IS_OSPF6_DUMP_MESSAGE (type))    zlog_info ("Ignore message on passive interface %s",               o6i->interface->name);  return 0;}/* send section */intospf6_message_length (struct iovec *message){  int i, length = 0;  for (i = 0; i < OSPF6_MESSAGE_IOVEC_SIZE; i++)    {      if (message[i].iov_base == NULL && message[i].iov_len == 0)        break;      length += message[i].iov_len;    }  return length;}#define OSPF6_MESSAGE_LENGTH(msg) \(ospf6_message_length (msg))voidospf6_message_send (unsigned char type, struct iovec *msg,                    struct in6_addr *dst, u_int ifindex){  struct ospf6_interface *o6i;  struct ospf6_header ospf6_header;  char dst_name[64], src_name[64];  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];  int msg_len;  /* ospf6 interface lookup */  o6i = ospf6_interface_lookup_by_index (ifindex);  assert (o6i);  msg_len = OSPF6_MESSAGE_LENGTH (msg);  /* I/F MTU check */#if 0  if (msg_len + sizeof (struct ospf6_header) >= o6i->interface->mtu)#else  if (msg_len + sizeof (struct ospf6_header) >= o6i->ifmtu)#endif    {      /* If Interface MTU is 0, save the case         since zebra had been failed to get MTU from Kernel */      if (o6i->interface->mtu != 0)        {          zlog_warn ("Message: Send failed on %s: exceeds I/F MTU",                     o6i->interface->name);          zlog_warn ("Message:   while sending %s: Len:%d MTU:%d",                     ospf6_message_type_string[type],                     msg_len + sizeof (struct ospf6_header),                     o6i->ifmtu);          return;        }      else        {          zlog_warn ("Message: I/F MTU check ignored on %s",                     o6i->interface->name);        }    }  /* Initialize */  OSPF6_MESSAGE_CLEAR (message);  /* set OSPF header */  memset (&ospf6_header, 0, sizeof (ospf6_header));  ospf6_header.version = OSPF6_VERSION;  ospf6_header.type = type;  ospf6_header.len = htons (msg_len + sizeof (struct ospf6_header));  ospf6_header.router_id = ospf6->router_id;  ospf6_header.area_id = o6i->area->area_id;  /* checksum is calculated by kernel */  ospf6_header.instance_id = o6i->instance_id;  ospf6_header.reserved = 0;  OSPF6_MESSAGE_ATTACH (message, &ospf6_header, sizeof (struct ospf6_header));  /* Attach rest to message */  OSPF6_MESSAGE_JOIN (message, msg);  /* statistics */  if (type >= OSPF6_MESSAGE_TYPE_MAX)    type = OSPF6_MESSAGE_TYPE_UNKNOWN;  o6i->message_stat[type].send++;  o6i->message_stat[type].send_octet += ntohs (ospf6_header.len);  /* log */  if (IS_OSPF6_DUMP_MESSAGE (type))    {      inet_ntop (AF_INET6, dst, dst_name, sizeof (dst_name));      if (o6i->lladdr)        inet_ntop (AF_INET6, o6i->lladdr, src_name, sizeof (src_name));      else        memcpy (src_name, "Unknown", sizeof (src_name));      zlog_info ("Send %s on %s",                 ospf6_message_type_string[type], o6i->interface->name);      zlog_info ("    %s -> %s", src_name, dst_name);      ospf6_message_log (message);    }  /* send message */  ospf6_sendmsg (o6i->lladdr, dst, &ifindex, message);}intospf6_send_hello (struct thread *thread){  listnode n;  struct ospf6_interface *o6i;  struct ospf6_neighbor *o6n;  struct in6_addr dst;  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_hello hello;  char router_buffer[1024]; /* xxx */  u_int router_size;  /* which ospf6 interface to send */  o6i = (struct ospf6_interface *) THREAD_ARG (thread);  o6i->thread_send_hello = (struct thread *) NULL;  /* assure interface is up */  if (o6i->state <= IFS_DOWN)    {      if (IS_OSPF6_DUMP_HELLO)        zlog_warn ("Send HELLO Failed: Interface not enabled: %s",                   o6i->interface->name);      return 0;    }  /* clear message buffer */  OSPF6_MESSAGE_CLEAR (message);  /* set Hello fields */  hello.interface_id = htonl (o6i->if_id);  hello.rtr_pri = o6i->priority;  memcpy (hello.options, o6i->area->options, sizeof (hello.options));  hello.hello_interval = htons (o6i->hello_interval);  hello.router_dead_interval = htons (o6i->dead_interval);  hello.dr = o6i->dr;  hello.bdr = o6i->bdr;  OSPF6_MESSAGE_ATTACH (message, &hello, sizeof (struct ospf6_hello));  /* set neighbor router id */  router_size = 0;  for (n = listhead (o6i->neighbor_list); n; nextnode (n))    {

⌨️ 快捷键说明

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