📄 _ospf6.c
字号:
/*
* Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
*/
#if 0
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/tcpdump/print-ospf6.c,v 1.2 1999/11/21 09:36:58 fenner Exp $ (LBL)";
#endif
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include "interfac.h"
#include "a2name.h"
#include "ospf6.h"
#ifdef USE_INET6
struct bits {
u_int32_t bit;
const char *str;
};
static const struct bits ospf6_option_bits[] = {
{ OSPF6_OPTION_V6, "V6" },
{ OSPF6_OPTION_E, "E" },
{ OSPF6_OPTION_MC, "MC" },
{ OSPF6_OPTION_N, "N" },
{ OSPF6_OPTION_R, "R" },
{ OSPF6_OPTION_DC, "DC" },
{ 0, NULL }
};
static const struct bits ospf6_rla_flag_bits[] = {
{ RLA_FLAG_B, "B" },
{ RLA_FLAG_E, "E" },
{ RLA_FLAG_V, "V" },
{ RLA_FLAG_W, "W" },
{ 0, NULL }
};
static struct tok type2str[] = {
{ OSPF_TYPE_UMD, "umd" },
{ OSPF_TYPE_HELLO,"hello" },
{ OSPF_TYPE_DB, "dd" },
{ OSPF_TYPE_LSR, "ls_req" },
{ OSPF_TYPE_LSU, "ls_upd" },
{ OSPF_TYPE_LSA, "ls_ack" },
{ 0, NULL }
};
static char tstr[] = " [|ospf]";
/* Forwards */
static void ospf6_print_seqage (u_int32_t, time_t);
static void ospf6_print_bits (const struct bits *, u_char);
static int ospf6_print_lshdr (const struct lsa_hdr *);
static int ospf6_print_lsa (const struct lsa *);
static int ospf6_decode_v3 (const struct ospf6hdr *, const u_char *);
static void ospf6_print_ls_type(u_int, const rtrid_t *, const rtrid_t *, const char *);
static void ospf6_print_seqage (u_int32_t seq, time_t us)
{
time_t sec = us % 60;
time_t mins = (us / 60) % 60;
time_t hour = us / 3600;
PRINTF (" S %X age ", seq);
if (hour)
PRINTF ("%lu:%02lu:%02lu", (u_int32_t)hour, (u_int32_t)mins, (u_int32_t)sec);
else if (mins)
PRINTF ("%lu:%02lu", (u_int32_t)mins, (u_int32_t)sec);
else PRINTF ("%lu", (u_int32_t) sec);
}
static void ospf6_print_bits (const struct bits *bp, u_char options)
{
char sep = ' ';
do
{
if (options & bp->bit)
{
PRINTF ("%c%s", sep, bp->str);
sep = '/';
}
}
while ((++bp)->bit);
}
static void ospf6_print_ls_type (u_int ls_type,
const rtrid_t *ls_stateid,
const rtrid_t *ls_router,
const char *fmt)
{
char *scope;
switch (ls_type & LS_SCOPE_MASK)
{
case LS_SCOPE_LINKLOCAL:
scope = "linklocal-";
break;
case LS_SCOPE_AREA:
scope = "area-";
break;
case LS_SCOPE_AS:
scope = "AS-";
break;
default:
scope = "";
break;
}
switch (ls_type & LS_TYPE_MASK)
{
case LS_TYPE_ROUTER:
PRINTF (" %srtr %s", scope, ipaddr_string (ls_router));
break;
case LS_TYPE_NETWORK:
PRINTF (" %snet dr %s if %s", scope,
ipaddr_string (ls_router), ipaddr_string (ls_stateid));
break;
case LS_TYPE_INTER_AP:
PRINTF (" %sinter-area-prefix %s abr %s", scope,
ipaddr_string (ls_stateid), ipaddr_string (ls_router));
break;
case LS_TYPE_INTER_AR:
PRINTF (" %sinter-area-router %s rtr %s", scope,
ipaddr_string (ls_router), ipaddr_string (ls_stateid));
break;
case LS_TYPE_ASE:
PRINTF (" %sase %s asbr %s", scope,
ipaddr_string (ls_stateid), ipaddr_string (ls_router));
break;
case LS_TYPE_GROUP:
PRINTF (" %sgroup %s rtr %s", scope,
ipaddr_string (ls_stateid), ipaddr_string (ls_router));
break;
case LS_TYPE_TYPE7:
PRINTF (" %stype7 %s rtr %s", scope,
ipaddr_string (ls_stateid), ipaddr_string (ls_router));
break;
case LS_TYPE_LINK:
PRINTF (" %slink %s rtr %s", scope,
ipaddr_string (ls_stateid), ipaddr_string (ls_router));
break;
case LS_TYPE_INTRA_AP:
PRINTF (" %sintra-area-prefix %s rtr %s", scope,
ipaddr_string (ls_stateid), ipaddr_string (ls_router));
break;
default:
PRINTF (" %s", scope);
PRINTF (fmt, ls_type);
break;
}
}
static int ospf6_print_lshdr (const struct lsa_hdr *lshp)
{
TCHECK (lshp->ls_type);
PUTS (" {"); /* } (ctags) */
TCHECK (lshp->ls_seq);
ospf6_print_seqage (ntohl (lshp->ls_seq), ntohs (lshp->ls_age));
ospf6_print_ls_type (ntohs (lshp->ls_type), &lshp->ls_stateid,
&lshp->ls_router, "ls_type %d");
return (0);
trunc:
return (1);
}
static int ospf6_print_lsaprefix (const struct lsa_prefix *lsapp)
{
struct in6_addr prefix;
int k;
TCHECK (*lsapp);
k = (lsapp->lsa_p_len + 31) / 32;
if (k * 4 > sizeof(struct in6_addr))
{
PRINTF ("??prefixlen %d??", lsapp->lsa_p_len);
goto trunc;
}
memset (&prefix, 0, sizeof(prefix));
memcpy (&prefix, lsapp->lsa_p_prefix, k * 4);
PRINTF (" %s/%d", ip6addr_string (&prefix), lsapp->lsa_p_len);
if (lsapp->lsa_p_opt)
PRINTF ("(opt=%x)", lsapp->lsa_p_opt);
return (sizeof(*lsapp) - 4 + k * 4);
trunc:
return -1;
}
/*
* Print a single link state advertisement. If truncated return 1, else 0.
*/
static int ospf6_print_lsa (const struct lsa *lsap)
{
const struct rlalink *rlp;
const u_char *ls_end;
#if 0
const struct tos_metric *tosp;
const struct aslametric *almp;
const struct mcla *mcp;
const u_int32_t *lp;
#endif
const rtrid_t *ap;
const struct llsa *llsap;
const struct lsa_prefix *lsapp;
int j, k;
if (ospf6_print_lshdr (&lsap->ls_hdr))
return (1);
TCHECK (lsap->ls_hdr.ls_length);
ls_end = (u_char *) lsap + ntohs (lsap->ls_hdr.ls_length);
switch (ntohs (lsap->ls_hdr.ls_type))
{
case LS_TYPE_ROUTER | LS_SCOPE_AREA:
TCHECK (lsap->lsa_un.un_rla.rla_flags);
ospf6_print_bits (ospf6_rla_flag_bits, lsap->lsa_un.un_rla.rla_flags);
TCHECK (lsap->lsa_un.un_rla.rla_options);
ospf6_print_bits (ospf6_option_bits, ntohl (lsap->lsa_un.un_rla.rla_options));
TCHECK (lsap->lsa_un.un_rla.rla_link);
rlp = lsap->lsa_un.un_rla.rla_link;
while (rlp + sizeof(*rlp) <= (struct rlalink *) ls_end)
{
TCHECK (*rlp);
PUTS (" {"); /* } (ctags) */
switch (rlp->link_type)
{
case RLA_TYPE_VIRTUAL:
PUTS (" virt");
/* Fall through */
case RLA_TYPE_ROUTER:
PRINTF (" nbrid %s nbrif %s if %s",
ipaddr_string (&rlp->link_nrtid),
ipaddr_string (&rlp->link_nifid),
ipaddr_string (&rlp->link_ifid));
break;
case RLA_TYPE_TRANSIT:
PRINTF (" dr %s drif %s if %s",
ipaddr_string (&rlp->link_nrtid),
ipaddr_string (&rlp->link_nifid),
ipaddr_string (&rlp->link_ifid));
break;
default:
/* { (ctags) */
PRINTF (" ??RouterLinksType 0x%02x?? }", rlp->link_type);
return (0);
}
PRINTF (" metric %d", ntohs (rlp->link_metric));
/* { (ctags) */
PUTS (" }");
rlp++;
}
break;
case LS_TYPE_NETWORK | LS_SCOPE_AREA:
TCHECK (lsap->lsa_un.un_nla.nla_options);
ospf6_print_bits (ospf6_option_bits,
ntohl (lsap->lsa_un.un_nla.nla_options));
PUTS (" rtrs");
ap = lsap->lsa_un.un_nla.nla_router;
while ((u_char *) ap < ls_end)
{
TCHECK (*ap);
PRINTF (" %s", ipaddr_string (ap));
++ap;
}
break;
case LS_TYPE_INTER_AP | LS_SCOPE_AREA:
TCHECK (lsap->lsa_un.un_inter_ap.inter_ap_metric);
PRINTF (" metric %lu",
ntohl (lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC);
lsapp = lsap->lsa_un.un_inter_ap.inter_ap_prefix;
while (lsapp + sizeof(lsapp) <= (struct lsa_prefix *) ls_end)
{
k = ospf6_print_lsaprefix (lsapp);
if (k < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -