📄 ospf6_message.c
字号:
/* * 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 "memory.h"#include "log.h"#include "vty.h"#include "command.h"#include "thread.h"#include "linklist.h"#include "ospf6_proto.h"#include "ospf6_lsa.h"#include "ospf6_lsdb.h"#include "ospf6_network.h"#include "ospf6_message.h"#include "ospf6_top.h"#include "ospf6_area.h"#include "ospf6_neighbor.h"#include "ospf6_interface.h"#include "ospf6_flood.h"#include "ospf6d.h"unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};char *ospf6_message_type_str[] = { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" };/* print functions */static voidospf6_header_print (struct ospf6_header *oh){ char router_id[16], area_id[16]; inet_ntop (AF_INET, &oh->router_id, router_id, sizeof (router_id)); inet_ntop (AF_INET, &oh->area_id, area_id, sizeof (area_id)); zlog_info (" OSPFv%d Type:%d Len:%hu Router-ID:%s", oh->version, oh->type, ntohs (oh->length), router_id); zlog_info (" Area-ID:%s Cksum:%hx Instance-ID:%d", area_id, ntohs (oh->checksum), oh->instance_id);}voidospf6_hello_print (struct ospf6_header *oh){ struct ospf6_hello *hello; char options[16]; char drouter[16], bdrouter[16], neighbor[16]; char *p; ospf6_header_print (oh); assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO); hello = (struct ospf6_hello *) ((caddr_t) oh + sizeof (struct ospf6_header)); inet_ntop (AF_INET, &hello->drouter, drouter, sizeof (drouter)); inet_ntop (AF_INET, &hello->bdrouter, bdrouter, sizeof (bdrouter)); ospf6_options_printbuf (hello->options, options, sizeof (options)); zlog_info (" I/F-Id:%ld Priority:%d Option:%s", (u_long) ntohl (hello->interface_id), hello->priority, options); zlog_info (" HelloInterval:%hu DeadInterval:%hu", ntohs (hello->hello_interval), ntohs (hello->dead_interval)); zlog_info (" DR:%s BDR:%s", drouter, bdrouter); for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello)); p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh); p += sizeof (u_int32_t)) { inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor)); zlog_info (" Neighbor: %s", neighbor); } if (p != OSPF6_MESSAGE_END (oh)) zlog_info ("Trailing garbage exists");}voidospf6_dbdesc_print (struct ospf6_header *oh){ struct ospf6_dbdesc *dbdesc; char options[16]; char *p; ospf6_header_print (oh); assert (oh->type == OSPF6_MESSAGE_TYPE_DBDESC); dbdesc = (struct ospf6_dbdesc *) ((caddr_t) oh + sizeof (struct ospf6_header)); ospf6_options_printbuf (dbdesc->options, options, sizeof (options)); zlog_info (" MBZ: %#x Option: %s IfMTU: %hu", dbdesc->reserved1, options, ntohs (dbdesc->ifmtu)); zlog_info (" MBZ: %#x Bits: %s%s%s SeqNum: %#lx", dbdesc->reserved2, (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"), (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"), (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"), (u_long) ntohl (dbdesc->seqnum)); for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); p += sizeof (struct ospf6_lsa_header)) ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); if (p != OSPF6_MESSAGE_END (oh)) zlog_info ("Trailing garbage exists");}voidospf6_lsreq_print (struct ospf6_header *oh){ char id[16], adv_router[16]; char *p; ospf6_header_print (oh); assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ); for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh); p += sizeof (struct ospf6_lsreq_entry)) { struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *) p; inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router)); inet_ntop (AF_INET, &e->id, id, sizeof (id)); zlog_info (" [%s Id:%s Adv:%s]", ospf6_lstype_name (e->type), id, adv_router); } if (p != OSPF6_MESSAGE_END (oh)) zlog_info ("Trailing garbage exists");}voidospf6_lsupdate_print (struct ospf6_header *oh){ struct ospf6_lsupdate *lsupdate; u_long num; char *p; ospf6_header_print (oh); assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE); lsupdate = (struct ospf6_lsupdate *) ((caddr_t) oh + sizeof (struct ospf6_header)); num = ntohl (lsupdate->lsa_number); zlog_info (" Number of LSA: %ld", num); for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); p < OSPF6_MESSAGE_END (oh) && p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh); p += OSPF6_LSA_SIZE (p)) { ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header)) { zlog_info (" Malformed LSA length, quit printing"); break; } } if (p != OSPF6_MESSAGE_END (oh)) { char buf[32]; int num = 0; memset (buf, 0, sizeof (buf)); zlog_info (" Trailing garbage exists"); while (p < OSPF6_MESSAGE_END (oh)) { snprintf (buf, sizeof (buf), "%s %2x", buf, *p++); num++; if (num == 8) { zlog_info (" %s", buf); memset (buf, 0, sizeof (buf)); num = 0; } } if (num) zlog_info (" %s", buf); }}voidospf6_lsack_print (struct ospf6_header *oh){ char *p; ospf6_header_print (oh); assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK); for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); p += sizeof (struct ospf6_lsa_header)) ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); if (p != OSPF6_MESSAGE_END (oh)) zlog_info ("Trailing garbage exists");}/* Receive function */#define MSG_OK 0#define MSG_NG 1static intospf6_header_examin (struct in6_addr *src, struct in6_addr *dst, struct ospf6_interface *oi, struct ospf6_header *oh){ u_char type; type = OSPF6_MESSAGE_TYPE_CANONICAL (oh->type); /* version check */ if (oh->version != OSPFV3_VERSION) { if (IS_OSPF6_DEBUG_MESSAGE (type, RECV)) zlog_info ("Message with unknown version"); return MSG_NG; } /* Area-ID check */ if (oh->area_id != oi->area->area_id) { if (oh->area_id == BACKBONE_AREA_ID) { if (IS_OSPF6_DEBUG_MESSAGE (type, RECV)) zlog_info ("Message may be via Virtual Link: not supported"); return MSG_NG; } if (IS_OSPF6_DEBUG_MESSAGE (type, RECV)) zlog_info ("Area-ID mismatch"); return MSG_NG; } /* Instance-ID check */ if (oh->instance_id != oi->instance_id) { if (IS_OSPF6_DEBUG_MESSAGE (type, RECV)) zlog_info ("Instance-ID mismatch"); return MSG_NG; } /* Router-ID check */ if (oh->router_id == oi->area->ospf6->router_id) zlog_warn ("Detect duplicate Router-ID"); return MSG_OK;}voidospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_interface *oi, struct ospf6_header *oh){ struct ospf6_hello *hello; struct ospf6_neighbor *on; char *p; int twoway = 0; int neighborchange = 0; int backupseen = 0; if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK) return; hello = (struct ospf6_hello *) ((caddr_t) oh + sizeof (struct ospf6_header)); /* HelloInterval check */ if (ntohs (hello->hello_interval) != oi->hello_interval) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("HelloInterval mismatch"); return; } /* RouterDeadInterval check */ if (ntohs (hello->dead_interval) != oi->dead_interval) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("RouterDeadInterval mismatch"); return; } /* E-bit check */ if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) != OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("E-bit mismatch"); return; } /* Find neighbor, create if not exist */ on = ospf6_neighbor_lookup (oh->router_id, oi); if (on == NULL) { on = ospf6_neighbor_create (oh->router_id, oi); on->prev_drouter = on->drouter = hello->drouter; on->prev_bdrouter = on->bdrouter = hello->bdrouter; on->priority = hello->priority; on->ifindex = ntohl (hello->interface_id); memcpy (&on->linklocal_addr, src, sizeof (struct in6_addr)); } /* TwoWay check */ for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello)); p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh); p += sizeof (u_int32_t)) { u_int32_t *router_id = (u_int32_t *) p; if (*router_id == oi->area->ospf6->router_id) twoway++; } if (p != OSPF6_MESSAGE_END (oh)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Trailing garbage ignored"); } /* RouterPriority check */ if (on->priority != hello->priority) { on->priority = hello->priority; neighborchange++; } /* DR check */ if (on->drouter != hello->drouter) { on->prev_drouter = on->drouter; on->drouter = hello->drouter; if (on->prev_drouter == on->router_id || on->drouter == on->router_id) neighborchange++; } /* BDR check */ if (on->bdrouter != hello->bdrouter) { on->prev_bdrouter = on->bdrouter; on->bdrouter = hello->bdrouter; if (on->prev_bdrouter == on->router_id || on->bdrouter == on->router_id) neighborchange++; } /* BackupSeen check */ if (oi->state == OSPF6_INTERFACE_WAITING) { if (hello->bdrouter == on->router_id) backupseen++; else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0)) backupseen++; } /* Execute neighbor events */ thread_execute (master, hello_received, on, 0); if (twoway) thread_execute (master, twoway_received, on, 0); else thread_execute (master, oneway_received, on, 0); /* Schedule interface events */ if (backupseen) thread_add_event (master, backup_seen, oi, 0); if (neighborchange) thread_add_event (master, neighbor_change, oi, 0);}static voidospf6_dbdesc_recv_master (struct ospf6_header *oh, struct ospf6_neighbor *on){ struct ospf6_dbdesc *dbdesc; char *p; dbdesc = (struct ospf6_dbdesc *) ((caddr_t) oh + sizeof (struct ospf6_header)); if (on->state < OSPF6_NEIGHBOR_INIT) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor state less than Init, ignore"); return; } switch (on->state) { case OSPF6_NEIGHBOR_TWOWAY: if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor state is 2-Way, ignore"); return; case OSPF6_NEIGHBOR_INIT: thread_execute (master, twoway_received, on, 0); if (on->state != OSPF6_NEIGHBOR_EXSTART) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor state is not ExStart, ignore"); return; } /* else fall through to ExStart */ case OSPF6_NEIGHBOR_EXSTART: /* if neighbor obeys us as our slave, schedule negotiation_done and process LSA Headers. Otherwise, ignore this message */ if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -