1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <ctype.h> 28 #include <fcntl.h> 29 #include <sys/socket.h> 30 #include <sys/types.h> 31 #include <net/if.h> 32 #include <netinet/in_systm.h> 33 #include <netinet/in.h> 34 #include <netinet/ip.h> 35 #include <inet/led.h> 36 #include <inet/ip6.h> 37 #include <arpa/inet.h> 38 #include <protocols/routed.h> 39 #include <protocols/ripngd.h> 40 #include "snoop.h" 41 42 extern char *dlc_header; 43 static char *show_cmd6(); 44 45 static struct in6_addr all_zeroes_addr = { { 0x0, 0x0, 0x0, 0x0, 46 0x0, 0x0, 0x0, 0x0, 47 0x0, 0x0, 0x0, 0x0, 48 0x0, 0x0, 0x0, 0x0 } }; 49 50 int 51 interpret_rip6(int flags, struct rip6 *rip6, int fraglen) 52 { 53 char *p; 54 struct netinfo6 *n; 55 int len, count; 56 struct in6_addr *dst; 57 int notdefault = 0; 58 char dststr[INET6_ADDRSTRLEN]; 59 60 if (flags & F_SUM) { 61 switch (rip6->rip6_cmd) { 62 case RIPCMD6_REQUEST: p = "C"; break; 63 case RIPCMD6_RESPONSE: p = "R"; break; 64 default: p = "?"; break; 65 } 66 67 switch (rip6->rip6_cmd) { 68 case RIPCMD6_REQUEST: 69 case RIPCMD6_RESPONSE: 70 len = fraglen - 4; 71 count = 0; 72 for (n = rip6->rip6_nets; 73 len >= sizeof (struct netinfo6); n++) { 74 count++; 75 len -= sizeof (struct netinfo6); 76 } 77 (void) sprintf(get_sum_line(), 78 "RIPng %s (%d destinations)", p, count); 79 break; 80 default: 81 (void) sprintf(get_sum_line(), "RIPng %s", p); 82 break; 83 } 84 } 85 86 if (flags & F_DTAIL) { 87 88 show_header("RIPng: ", "Routing Information Protocol for IPv6", 89 fraglen); 90 show_space(); 91 (void) sprintf(get_line((char *)(uintptr_t)rip6->rip6_cmd - 92 dlc_header, 1), "Opcode = %d (%s)", rip6->rip6_cmd, 93 show_cmd6(rip6->rip6_cmd)); 94 (void) sprintf(get_line((char *)(uintptr_t)rip6->rip6_vers - 95 dlc_header, 1), "Version = %d", rip6->rip6_vers); 96 97 switch (rip6->rip6_cmd) { 98 case RIPCMD6_REQUEST: 99 case RIPCMD6_RESPONSE: 100 show_space(); 101 (void) sprintf(get_line(0, 0), "Address" 102 " Prefix Metric"); 103 len = fraglen - 4; 104 for (n = rip6->rip6_nets; 105 len >= sizeof (struct netinfo6); n++) { 106 if (rip6->rip6_vers > 0) { 107 n->rip6_metric = n->rip6_metric; 108 } 109 dst = &n->rip6_prefix; 110 notdefault = bcmp((caddr_t *)dst, 111 (caddr_t *)&all_zeroes_addr, sizeof (*dst)); 112 (void) inet_ntop(AF_INET6, (char *)dst, dststr, 113 INET6_ADDRSTRLEN); 114 (void) sprintf(get_line((char *)n - dlc_header, 115 sizeof (struct netinfo6)), 116 "%-30s %-10d %-5d %s", 117 notdefault ? dststr : 118 " (default)", n->rip6_prefix_length, 119 n->rip6_metric, n->rip6_metric == 16 ? 120 " (not reachable)":""); 121 len -= sizeof (struct netinfo); 122 } 123 break; 124 } 125 } 126 return (fraglen); 127 } 128 129 static char * 130 show_cmd6(c) 131 int c; 132 { 133 switch (c) { 134 case RIPCMD6_REQUEST: return ("route request"); 135 case RIPCMD6_RESPONSE: return ("route response"); 136 } 137 return ("?"); 138 } 139