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

📄 ospf6_lsa.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2003 Yasuhiro Ohara * * This file is part of GNU Zebra. * * GNU Zebra 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, or (at your option) any * later version. * * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,  * Boston, MA 02111-1307, USA.   */#include <zebra.h>/* Include other stuffs */#include "log.h"#include "linklist.h"#include "vector.h"#include "vty.h"#include "command.h"#include "memory.h"#include "thread.h"#include "ospf6_proto.h"#include "ospf6_lsa.h"#include "ospf6_lsdb.h"#include "ospf6_message.h"#include "ospf6_top.h"#include "ospf6_area.h"#include "ospf6_interface.h"#include "ospf6_neighbor.h"#include "ospf6_flood.h"#include "ospf6d.h"vector ospf6_lsa_handler_vector;intospf6_unknown_lsa_show (struct vty *vty, struct ospf6_lsa *lsa){  u_char *start, *end, *current;  char byte[4];  start = (u_char *) lsa->header + sizeof (struct ospf6_lsa_header);  end = (u_char *) lsa->header + ntohs (lsa->header->length);  vty_out (vty, "        Unknown contents:%s", VNL);  for (current = start; current < end; current ++)    {      if ((current - start) % 16 == 0)        vty_out (vty, "%s        ", VNL);      else if ((current - start) % 4 == 0)        vty_out (vty, " ");      snprintf (byte, sizeof (byte), "%02x", *current);      vty_out (vty, "%s", byte);    }  vty_out (vty, "%s%s", VNL, VNL);  return 0;}struct ospf6_lsa_handler unknown_handler ={  OSPF6_LSTYPE_UNKNOWN,  "Unknown",  ospf6_unknown_lsa_show,  OSPF6_LSA_DEBUG,};voidospf6_install_lsa_handler (struct ospf6_lsa_handler *handler){  /* type in handler is host byte order */  int index = handler->type & OSPF6_LSTYPE_FCODE_MASK;  vector_set_index (ospf6_lsa_handler_vector, index, handler);}struct ospf6_lsa_handler *ospf6_get_lsa_handler (u_int16_t type){  struct ospf6_lsa_handler *handler = NULL;  int index = ntohs (type) & OSPF6_LSTYPE_FCODE_MASK;  if (ospf6_lsa_handler_vector &&      index < vector_max (ospf6_lsa_handler_vector))    handler = vector_slot (ospf6_lsa_handler_vector, index);  else    handler = &unknown_handler;  if (handler == NULL)    handler = &unknown_handler;  return handler;}char *ospf6_lstype_name (u_int16_t type){  static char buf[8];  struct ospf6_lsa_handler *handler;  handler = ospf6_get_lsa_handler (type);  if (handler && handler != &unknown_handler)    return handler->name;  snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type));  return buf;}u_charospf6_lstype_debug (u_int16_t type){  struct ospf6_lsa_handler *handler;  handler = ospf6_get_lsa_handler (type);  return handler->debug;}/* RFC2328: Section 13.2 */intospf6_lsa_is_differ (struct ospf6_lsa *lsa1,                     struct ospf6_lsa *lsa2){  int len;  assert (OSPF6_LSA_IS_SAME (lsa1, lsa2));  /* XXX, Options ??? */  ospf6_lsa_age_current (lsa1);  ospf6_lsa_age_current (lsa2);  if (ntohs (lsa1->header->age) == MAXAGE &&      ntohs (lsa2->header->age) != MAXAGE)    return 1;  if (ntohs (lsa1->header->age) != MAXAGE &&      ntohs (lsa2->header->age) == MAXAGE)    return 1;  /* compare body */  if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))    return 1;  len = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header);  return memcmp (lsa1->header + 1, lsa2->header + 1, len);}intospf6_lsa_is_changed (struct ospf6_lsa *lsa1,                      struct ospf6_lsa *lsa2){  int length;  if (OSPF6_LSA_IS_MAXAGE (lsa1) ^ OSPF6_LSA_IS_MAXAGE (lsa2))    return 1;  if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))    return 1;  length = OSPF6_LSA_SIZE (lsa1->header) - sizeof (struct ospf6_lsa_header);  assert (length > 0);  return memcmp (OSPF6_LSA_HEADER_END (lsa1->header),                 OSPF6_LSA_HEADER_END (lsa2->header), length);}/* ospf6 age functions *//* calculate birth */static voidospf6_lsa_age_set (struct ospf6_lsa *lsa){  struct timeval now;  assert (lsa && lsa->header);  if (gettimeofday (&now, (struct timezone *)NULL) < 0)    zlog_warn ("LSA: gettimeofday failed, may fail LSA AGEs: %s",               strerror (errno));  lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age);  lsa->birth.tv_usec = now.tv_usec;  return;}/* this function calculates current age from its birth,   then update age field of LSA header. return value is current age */u_int16_tospf6_lsa_age_current (struct ospf6_lsa *lsa){  struct timeval now;  u_int32_t ulage;  u_int16_t age;  assert (lsa);  assert (lsa->header);  /* current time */  if (gettimeofday (&now, (struct timezone *)NULL) < 0)    zlog_warn ("LSA: gettimeofday failed, may fail LSA AGEs: %s",               strerror (errno));  /* calculate age */  ulage = now.tv_sec - lsa->birth.tv_sec;  /* if over MAXAGE, set to it */  age = (ulage > MAXAGE ? MAXAGE : ulage);  lsa->header->age = htons (age);  return age;}/* update age field of LSA header with adding InfTransDelay */voidospf6_lsa_age_update_to_send (struct ospf6_lsa *lsa, u_int32_t transdelay){  unsigned short age;  age = ospf6_lsa_age_current (lsa) + transdelay;  if (age > MAXAGE)    age = MAXAGE;  lsa->header->age = htons (age);}voidospf6_lsa_premature_aging (struct ospf6_lsa *lsa){  /* log */  if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type))    zlog_info ("LSA: Premature aging: %s", lsa->name);  THREAD_OFF (lsa->expire);  THREAD_OFF (lsa->refresh);  memset (&lsa->birth, 0, sizeof (struct timeval));  thread_execute (master, ospf6_lsa_expire, lsa, 0);}/* check which is more recent. if a is more recent, return -1;   if the same, return 0; otherwise(b is more recent), return 1 */intospf6_lsa_compare (struct ospf6_lsa *a, struct ospf6_lsa *b){  signed long seqnuma, seqnumb;  u_int16_t cksuma, cksumb;  u_int16_t agea, ageb;  assert (a && a->header);  assert (b && b->header);  assert (OSPF6_LSA_IS_SAME (a, b));  seqnuma = ((signed long) ntohl (a->header->seqnum))             - (signed long) INITIAL_SEQUENCE_NUMBER;  seqnumb = ((signed long) ntohl (b->header->seqnum))             - (signed long) INITIAL_SEQUENCE_NUMBER;  /* compare by sequence number */  /* XXX, LS sequence number wrapping */  if (seqnuma > seqnumb)    return -1;  else if (seqnuma < seqnumb)    return 1;  /* Checksum */  cksuma = ntohs (a->header->checksum);  cksumb = ntohs (b->header->checksum);  if (cksuma > cksumb)    return -1;  if (cksuma < cksumb)    return 0;  /* Update Age */  agea = ospf6_lsa_age_current (a);  ageb = ospf6_lsa_age_current (b);  /* MaxAge check */  if (agea == MAXAGE && ageb != MAXAGE)    return -1;  else if (agea != MAXAGE && ageb == MAXAGE)    return 1;  /* Age check */  if (agea > ageb && agea - ageb >= MAX_AGE_DIFF)    return 1;  else if (agea < ageb && ageb - agea >= MAX_AGE_DIFF)    return -1;  /* neither recent */  return 0;}char *ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size){  char id[16], adv_router[16];  inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));  inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,             sizeof (adv_router));  snprintf (buf, size, "[%s Id:%s Adv:%s]",            ospf6_lstype_name (lsa->header->type), id, adv_router);  return buf;}voidospf6_lsa_header_print_raw (struct ospf6_lsa_header *header){  char id[16], adv_router[16];  inet_ntop (AF_INET, &header->id, id, sizeof (id));  inet_ntop (AF_INET, &header->adv_router, adv_router,             sizeof (adv_router));  zlog_info ("    [%s Id:%s Adv:%s]",             ospf6_lstype_name (header->type), id, adv_router);  zlog_info ("    Age: %4hu SeqNum: %#08lx Cksum: %04hx Len: %d",             ntohs (header->age), (u_long) ntohl (header->seqnum),             ntohs (header->checksum), ntohs (header->length));}voidospf6_lsa_header_print (struct ospf6_lsa *lsa){  ospf6_lsa_age_current (lsa);  ospf6_lsa_header_print_raw (lsa->header);}voidospf6_lsa_show_summary_header (struct vty *vty){  vty_out (vty, "%-12s %-15s %-15s %4s %8s %4s %4s %-8s%s",           "Type", "LSId", "AdvRouter", "Age", "SeqNum",           "Cksm", "Len", "Duration", VNL);}voidospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa){  char adv_router[16], id[16];  struct timeval now, res;  char duration[16];  assert (lsa);  assert (lsa->header);  inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));  inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,             sizeof (adv_router));  gettimeofday (&now, NULL);  timersub (&now, &lsa->installed, &res);  timerstring (&res, duration, sizeof (duration));  vty_out (vty, "%-12s %-15s %-15s %4hu %8lx %04hx %4hu %8s%s",           ospf6_lstype_name (lsa->header->type),           id, adv_router, ospf6_lsa_age_current (lsa),           (u_long) ntohl (lsa->header->seqnum),           ntohs (lsa->header->checksum), ntohs (lsa->header->length),           duration, VNL);}voidospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa){  u_char *start, *end, *current;  char byte[4];  start = (u_char *) lsa->header;  end = (u_char *) lsa->header + ntohs (lsa->header->length);  vty_out (vty, "%s", VNL);  vty_out (vty, "%s:%s", lsa->name, VNL);  for (current = start; current < end; current ++)    {      if ((current - start) % 16 == 0)        vty_out (vty, "%s        ", VNL);      else if ((current - start) % 4 == 0)        vty_out (vty, " ");      snprintf (byte, sizeof (byte), "%02x", *current);      vty_out (vty, "%s", byte);    }  vty_out (vty, "%s%s", VNL, VNL);  return;}voidospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa){  char adv_router[64], id[64];  assert (lsa && lsa->header);  inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));  inet_ntop (AF_INET, &lsa->header->adv_router,             adv_router, sizeof (adv_router));  vty_out (vty, "%s", VNL);  vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),           ospf6_lstype_name (lsa->header->type), VNL);  vty_out (vty, "Link State ID: %s%s", id, VNL);  vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);  vty_out (vty, "LS Sequence Number: %#010lx%s",           (u_long) ntohl (lsa->header->seqnum), VNL);  vty_out (vty, "CheckSum: %#06hx Length: %hu%s",           ntohs (lsa->header->checksum),           ntohs (lsa->header->length), VNL);  vty_out (vty, "    Prev: %p This: %p Next: %p%s",           lsa->prev, lsa, lsa->next, VNL);  vty_out (vty, "%s", VNL);  return;}voidospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa){  char adv_router[64], id[64];  struct ospf6_lsa_handler *handler;  assert (lsa && lsa->header);  inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));  inet_ntop (AF_INET, &lsa->header->adv_router,             adv_router, sizeof (adv_router));  vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),           ospf6_lstype_name (lsa->header->type), VNL);  vty_out (vty, "Link State ID: %s%s", id, VNL);  vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);  vty_out (vty, "LS Sequence Number: %#010lx%s",           (u_long) ntohl (lsa->header->seqnum), VNL);  vty_out (vty, "CheckSum: %#06hx Length: %hu%s",           ntohs (lsa->header->checksum),           ntohs (lsa->header->length), VNL);  handler = ospf6_get_lsa_handler (lsa->header->type);  if (handler->show == NULL)    handler = &unknown_handler;  (*handler->show) (vty, lsa);  vty_out (vty, "%s", VNL);}/* OSPFv3 LSA creation/deletion function */struct ospf6_lsa *ospf6_lsa_create (struct ospf6_lsa_header *header){  struct ospf6_lsa *lsa = NULL;  struct ospf6_lsa_header *new_header = NULL;  u_int16_t lsa_size = 0;  /* size of the entire LSA */  lsa_size = ntohs (header->length);   /* XXX vulnerable */  /* allocate memory for this LSA */  new_header = (struct ospf6_lsa_header *)    XMALLOC (MTYPE_OSPF6_LSA, lsa_size);  /* copy LSA from original header */  memcpy (new_header, header, lsa_size);  /* LSA information structure */  /* allocate memory */  lsa = (struct ospf6_lsa *)    XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));  memset (lsa, 0, sizeof (struct ospf6_lsa));  lsa->header = (struct ospf6_lsa_header *) new_header;  /* dump string */  ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));  /* calculate birth of this lsa */  ospf6_lsa_age_set (lsa);  return lsa;}struct ospf6_lsa *ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header){  struct ospf6_lsa *lsa = NULL;  struct ospf6_lsa_header *new_header = NULL;  /* allocate memory for this LSA */  new_header = (struct ospf6_lsa_header *)    XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_header));  /* copy LSA from original header */  memcpy (new_header, header, sizeof (struct ospf6_lsa_header));  /* LSA information structure */  /* allocate memory */  lsa = (struct ospf6_lsa *)

⌨️ 快捷键说明

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