156893Sfenner/*
256893Sfenner * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
356893Sfenner *	The Regents of the University of California.  All rights reserved.
456893Sfenner *
556893Sfenner * Redistribution and use in source and binary forms, with or without
656893Sfenner * modification, are permitted provided that: (1) source code distributions
756893Sfenner * retain the above copyright notice and this paragraph in its entirety, (2)
856893Sfenner * distributions including binary code include the above copyright notice and
956893Sfenner * this paragraph in its entirety in the documentation or other materials
1056893Sfenner * provided with the distribution, and (3) all advertising materials mentioning
1156893Sfenner * features or use of this software display the following acknowledgement:
1256893Sfenner * ``This product includes software developed by the University of California,
1356893Sfenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1456893Sfenner * the University nor the names of its contributors may be used to endorse
1556893Sfenner * or promote products derived from this software without specific prior
1656893Sfenner * written permission.
1756893Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1856893Sfenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1956893Sfenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2056893Sfenner */
2156893Sfenner
2256893Sfenner#ifndef lint
23127668Sbmsstatic const char rcsid[] _U_ =
24190207Srpaulo    "@(#) $Header: /tcpdump/master/tcpdump/print-rt6.c,v 1.27 2005-04-20 22:34:57 guy Exp $";
2556893Sfenner#endif
2656893Sfenner
2756893Sfenner#ifdef HAVE_CONFIG_H
2856893Sfenner#include "config.h"
2956893Sfenner#endif
3056893Sfenner
3156893Sfenner#ifdef INET6
3256893Sfenner
33127668Sbms#include <tcpdump-stdinc.h>
3456893Sfenner
3556893Sfenner#include <stdio.h>
3656893Sfenner
3775115Sfenner#include "ip6.h"
3856893Sfenner
3956893Sfenner#include "interface.h"
4056893Sfenner#include "addrtoname.h"
41127668Sbms#include "extract.h"
4256893Sfenner
4356893Sfennerint
44147899Ssamrt6_print(register const u_char *bp, const u_char *bp2 _U_)
4556893Sfenner{
4656893Sfenner	register const struct ip6_rthdr *dp;
4756893Sfenner	register const struct ip6_rthdr0 *dp0;
4856893Sfenner	register const u_char *ep;
4956893Sfenner	int i, len;
5075115Sfenner	register const struct in6_addr *addr;
5156893Sfenner
5256893Sfenner	dp = (struct ip6_rthdr *)bp;
5356893Sfenner	len = dp->ip6r_len;
5456893Sfenner
5575115Sfenner	/* 'ep' points to the end of available data. */
5656893Sfenner	ep = snapend;
5756893Sfenner
5856893Sfenner	TCHECK(dp->ip6r_segleft);
5956893Sfenner
6075115Sfenner	printf("srcrt (len=%d", dp->ip6r_len);	/*)*/
6175115Sfenner	printf(", type=%d", dp->ip6r_type);
6275115Sfenner	printf(", segleft=%d", dp->ip6r_segleft);
6356893Sfenner
6475115Sfenner	switch (dp->ip6r_type) {
6575115Sfenner#ifndef IPV6_RTHDR_TYPE_0
6675115Sfenner#define IPV6_RTHDR_TYPE_0 0
6775115Sfenner#endif
68127668Sbms#ifndef IPV6_RTHDR_TYPE_2
69127668Sbms#define IPV6_RTHDR_TYPE_2 2
70127668Sbms#endif
7156893Sfenner	case IPV6_RTHDR_TYPE_0:
72127668Sbms	case IPV6_RTHDR_TYPE_2:			/* Mobile IPv6 ID-20 */
7356893Sfenner		dp0 = (struct ip6_rthdr0 *)dp;
7456893Sfenner
7556893Sfenner		TCHECK(dp0->ip6r0_reserved);
7656893Sfenner		if (dp0->ip6r0_reserved || vflag) {
7775115Sfenner			printf(", rsv=0x%0x",
78127668Sbms			    EXTRACT_32BITS(&dp0->ip6r0_reserved));
7956893Sfenner		}
8056893Sfenner
8156893Sfenner		if (len % 2 == 1)
8256893Sfenner			goto trunc;
8356893Sfenner		len >>= 1;
8475115Sfenner		addr = &dp0->ip6r0_addr[0];
8556893Sfenner		for (i = 0; i < len; i++) {
8675115Sfenner			if ((u_char *)(addr + 1) > ep)
8756893Sfenner				goto trunc;
88127668Sbms
8975115Sfenner			printf(", [%d]%s", i, ip6addr_string(addr));
9075115Sfenner			addr++;
9156893Sfenner		}
9275115Sfenner		/*(*/
9375115Sfenner		printf(") ");
9456893Sfenner		return((dp0->ip6r0_len + 1) << 3);
9556893Sfenner		break;
9656893Sfenner	default:
9756893Sfenner		goto trunc;
9856893Sfenner		break;
9956893Sfenner	}
10056893Sfenner
10156893Sfenner trunc:
10256893Sfenner	fputs("[|srcrt]", stdout);
103127668Sbms	return -1;
10456893Sfenner}
10556893Sfenner#endif /* INET6 */
106