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

📄 ospf6_message.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (memcmp (received->options, last_received->options, 3) != 0)    return 0;  if (received->ifmtu != last_received->ifmtu)    return 0;  if (received->bits != last_received->bits)    return 0;  if (received->seqnum != last_received->seqnum)    return 0;  return 1;}voidospf6_process_dbdesc_master (struct iovec *message, struct ospf6_neighbor *o6n){  struct ospf6_header *ospf6_header;  u_int16_t length, lsa_count;  struct ospf6_dbdesc *dbdesc;  struct ospf6_lsa_header *lsa_header;  /* 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);  /* set database description pointer */  dbdesc = (struct ospf6_dbdesc *) message[1].iov_base;  switch (o6n->state)    {      case NBS_DOWN:      case NBS_ATTEMPT:      case NBS_TWOWAY:        if (IS_OSPF6_DUMP_DBDESC)          zlog_info ("DbDesc from %s Ignored: state less than Init",                     o6n->str);        return;      case NBS_INIT:        thread_execute (master, twoway_received, o6n, 0);        if (o6n->state != NBS_EXSTART)          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("DbDesc from %s Ignored: state less than ExStart",                         o6n->str);            return;          }        /* else fall through to ExStart */      case NBS_EXSTART:        if (DDBIT_IS_SLAVE (dbdesc->bits) &&            !DDBIT_IS_INITIAL (dbdesc->bits) &&            ntohl (dbdesc->seqnum) == o6n->dbdesc_seqnum)          {            ospf6_neighbor_dbex_init (o6n);            if (o6n->thread_rxmt_dbdesc)              thread_cancel (o6n->thread_rxmt_dbdesc);            o6n->thread_rxmt_dbdesc = (struct thread *) NULL;            thread_add_event (master, negotiation_done, o6n, 0);          }        else          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("  negotiation failed with %s", o6n->str);            return;          }        break;      case NBS_EXCHANGE:        /* duplicate dbdesc dropped by master */        if (!memcmp (dbdesc, &o6n->last_dd,                     sizeof (struct ospf6_dbdesc)))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("  duplicate dbdesc, drop");            return;          }        /* check Initialize bit and Master/Slave bit */        if (DDBIT_IS_INITIAL (dbdesc->bits))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("Initialize bit mismatch");            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        if (DDBIT_IS_MASTER (dbdesc->bits))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("Master/Slave bit mismatch");            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        /* dbdesc option check */        if (memcmp (dbdesc->options, o6n->last_dd.options,                    sizeof (dbdesc->options)))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("dbdesc option field changed");            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        /* dbdesc sequence number check */        if (ntohl (dbdesc->seqnum) != o6n->dbdesc_seqnum)          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_warn ("*** dbdesc seqnumber mismatch: %d expected",                         o6n->dbdesc_seqnum);            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        break;      case NBS_LOADING:      case NBS_FULL:        /* duplicate dbdesc dropped by master */        if (ospf6_dbdesc_is_duplicate (dbdesc, &o6n->last_dd))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("  duplicate dbdesc, drop");            return;          }        else          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("  not duplicate dbdesc in state %s",                         ospf6_neighbor_state_string[o6n->state]);            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        break; /* not reached */      default:        assert (0);        break; /* not reached */    }  /* process LSA headers */  lsa_count = 0;  for (lsa_header = (struct ospf6_lsa_header *) (dbdesc + 1);       (char *)(lsa_header + 1) <= (char *)dbdesc + length;       lsa_header++)    {      if (ospf6_dbex_check_dbdesc_lsa_header (lsa_header, o6n) < 0)        {          thread_add_event (master, seqnumber_mismatch, o6n, 0);          return;        }      lsa_count ++;    }  /* increment dbdesc seqnum */  o6n->dbdesc_seqnum++;  /* cancel transmission/retransmission thread */  if (o6n->thread_send_dbdesc)    thread_cancel (o6n->thread_send_dbdesc);  o6n->thread_send_dbdesc = (struct thread *) NULL;  if (o6n->thread_rxmt_dbdesc)    thread_cancel (o6n->thread_rxmt_dbdesc);  o6n->thread_rxmt_dbdesc = (struct thread *) NULL;  /* more bit check */  if (!DD_IS_MBIT_SET (dbdesc->bits) && !DD_IS_MBIT_SET (o6n->dbdesc_bits))    thread_add_event (master, exchange_done, o6n, 0);  else    o6n->thread_send_dbdesc =      thread_add_event (master, ospf6_send_dbdesc, o6n, 0);  /* save last received dbdesc */  memcpy (&o6n->last_dd, dbdesc, sizeof (struct ospf6_dbdesc));  /* statistics */  o6n->lsa_receive[OSPF6_MESSAGE_TYPE_DBDESC] += lsa_count;  return;}voidospf6_process_dbdesc_slave (struct iovec *message, struct ospf6_neighbor *o6n){  struct ospf6_header *ospf6_header;  u_int16_t length, lsa_count;  struct ospf6_dbdesc *dbdesc;  struct ospf6_lsa_header *lsa_header;  /* 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);  /* set database description pointer */  dbdesc = (struct ospf6_dbdesc *) message[1].iov_base;  switch (o6n->state)    {      case NBS_DOWN:      case NBS_ATTEMPT:      case NBS_TWOWAY:        return;      case NBS_INIT:        thread_execute (master, twoway_received, o6n, 0);        if (o6n->state != NBS_EXSTART)          {            return;          }        /* else fall through to ExStart */      case NBS_EXSTART:        if (DD_IS_IBIT_SET (dbdesc->bits) &&            DD_IS_MBIT_SET (dbdesc->bits) &&            DD_IS_MSBIT_SET (dbdesc->bits))          {            /* Master/Slave bit set to slave */            DD_MSBIT_CLEAR (o6n->dbdesc_bits);            /* Initialize bit clear */            DD_IBIT_CLEAR (o6n->dbdesc_bits);            /* sequence number set to master's */            o6n->dbdesc_seqnum = ntohl (dbdesc->seqnum);            ospf6_neighbor_dbex_init (o6n);            if (o6n->thread_rxmt_dbdesc)              thread_cancel (o6n->thread_rxmt_dbdesc);            o6n->thread_rxmt_dbdesc = (struct thread *) NULL;            thread_add_event (master, negotiation_done, o6n, 0);          }        else          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("negotiation failed");            return;          }        break;      case NBS_EXCHANGE:        /* duplicate dbdesc dropped by master */        if (!memcmp (dbdesc, &o6n->last_dd,                     sizeof (struct ospf6_dbdesc)))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("  duplicate dbdesc, retransmit dbdesc");            if (o6n->thread_rxmt_dbdesc)              thread_cancel (o6n->thread_rxmt_dbdesc);            o6n->thread_rxmt_dbdesc =              thread_add_event (master, ospf6_send_dbdesc_rxmt, o6n, 0);            return;          }        /* check Initialize bit and Master/Slave bit */        if (DDBIT_IS_INITIAL (dbdesc->bits))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("Initialize bit mismatch");            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        if (DDBIT_IS_SLAVE (dbdesc->bits))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("Master/Slave bit mismatch");            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        /* dbdesc option check */        if (memcmp (dbdesc->options, o6n->last_dd.options,                    sizeof (dbdesc->options)))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("dbdesc option field changed");            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        /* dbdesc sequence number check */        if (ntohl (dbdesc->seqnum) != o6n->dbdesc_seqnum + 1)          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_warn ("*** dbdesc seqnumber mismatch: %d expected",                         o6n->dbdesc_seqnum + 1);            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        break;      case NBS_LOADING:      case NBS_FULL:        /* duplicate dbdesc cause slave to retransmit */        if (ospf6_dbdesc_is_duplicate (dbdesc, &o6n->last_dd))          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("  duplicate dbdesc, retransmit");            if (o6n->thread_rxmt_dbdesc)              thread_cancel (o6n->thread_rxmt_dbdesc);            o6n->thread_rxmt_dbdesc =              thread_add_event (master, ospf6_send_dbdesc_rxmt, o6n, 0);            return;          }        else          {            if (IS_OSPF6_DUMP_DBDESC)              zlog_info ("  not duplicate dbdesc in state %s",                         ospf6_neighbor_state_string[o6n->state]);            thread_add_event (master, seqnumber_mismatch, o6n, 0);            return;          }        break; /* not reached */      default:        assert (0);        break; /* not reached */    }  /* process LSA headers */  lsa_count = 0;  for (lsa_header = (struct ospf6_lsa_header *) (dbdesc + 1);       (char *)(lsa_header + 1) <= (char *)dbdesc + length;       lsa_header++)    {      if (ospf6_dbex_check_dbdesc_lsa_header (lsa_header, o6n) < 0)        {          thread_add_event (master, seqnumber_mismatch, o6n, 0);          return;        }      lsa_count ++;    }  /* set dbdesc seqnum to master's */  o6n->dbdesc_seqnum = ntohl (dbdesc->seqnum);  if (o6n->thread_send_dbdesc)    thread_cancel (o6n->thread_send_dbdesc);  o6n->thread_send_dbdesc =    thread_add_event (master, ospf6_send_dbdesc, o6n, 0);  /* save last received dbdesc */  memcpy (&o6n->last_dd, dbdesc, sizeof (struct ospf6_dbdesc));  /* statistics */  o6n->lsa_receive[OSPF6_MESSAGE_TYPE_DBDESC] += lsa_count;  return;}voidospf6_process_dbdesc (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_dbdesc *dbdesc;  int Im_master = 0;  /* 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);  /* set database description pointer */  dbdesc = (struct ospf6_dbdesc *) message[1].iov_base;  /* find neighbor. if cannot be found, reject this message */  o6n = ospf6_neighbor_lookup (router_id, o6i);  if (!o6n)    {      if (IS_OSPF6_DUMP_DBDESC)        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;    }  /* interface mtu check */    /* xxx */  /* check am I master */  Im_master = ospf6_dbdesc_is_master (o6n);  if (Im_master < 0)    {      return; /* can't decide which is master, return */    }  if (Im_master)    ospf6_process_dbdesc_master (message, o6n);  else    ospf6_process_dbdesc_slave (message, o6n);  return;}voidospf6_process_lsreq (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_lsreq *lsreq;  struct iovec response[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_lsa *lsa;  unsigned long lsanum = 0;  struct ospf6_lsupdate lsupdate;  char buf_id[16], buf_router[16], buf_type[16];  /* 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_LSREQ)        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;    }  /* In states other than ExChange, Loading, or Full, the packet     should be ignored. */  if (o6n->state != NBS_EXCHANGE && o6n->state != NBS_LOADING      && o6n->state != NBS_FULL)    {      if (IS_OSPF6_DUMP_LSREQ)        zlog_info ("  neighbor state less than Exchange, reject");      return;    }  /* Initialize response LSUpdate packet */  OSPF6_MESSAGE_CLEAR (response);  memset (&lsupdate, 0, sizeof (struct ospf6_lsupdate));  OSPF6_MESSAGE_ATTACH (response, &lsupdate, sizeof (struct ospf6_lsupdate));  /* process each request */  lsanum = 0;  for (lsreq = (struct ospf6_lsreq *) message[1].iov_base;       (char *)(lsreq + 1) <= (char *)(message[1].iov_base + length);       lsreq++)    {      inet_ntop (AF_INET, &lsreq->adv_router, buf_router, sizeof (buf_router));      inet_ntop (AF_INET, &lsreq->id, buf_id, sizeof (buf_id));      /* find instance of database copy */      lsa = ospf6_lsdb_lookup (lsreq->type, lsreq->id, lsreq->adv_router,                               ospf6_lsa_get_scope (lsreq->type, o6i));      if (!lsa)        {          if (IS_OSPF6_DUMP_LSREQ)            zlog_info ("BadLSReq: %s requests [%s ID=%s Adv=%s] not found",                       o6n->str, ospf6_lsa_type_string (lsreq->type, buf_type,                                                        sizeof (buf_type)),                       buf_id, buf_router);          thread_add_event (master, bad_lsreq, o6n, 0);          return;        }      /* I/F MTU check */      if (sizeof (struct ospf6_header) + sizeof (struct ospf6_lsupdate)          + iov_totallen (response) + ntohs (lsa->header->length)          > o6i->ifmtu)        break;

⌨️ 快捷键说明

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