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 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "defs.h" 30 #include "tables.h" 31 32 static void print_opt(struct nd_opt_hdr *opt, int len); 33 34 void 35 print_route_sol(char *str, struct phyint *pi, 36 struct nd_router_solicit *rs, int len, struct sockaddr_in6 *addr) 37 { 38 struct nd_opt_hdr *opt; 39 char abuf[INET6_ADDRSTRLEN]; 40 41 logmsg(LOG_DEBUG, "%s %s (%d bytes) on %s\n", str, 42 inet_ntop(addr->sin6_family, (void *)&addr->sin6_addr, 43 abuf, sizeof (abuf)), 44 len, pi->pi_name); 45 46 len -= sizeof (*rs); 47 opt = (struct nd_opt_hdr *)&rs[1]; 48 print_opt(opt, len); 49 } 50 51 void 52 print_route_adv(char *str, struct phyint *pi, 53 struct nd_router_advert *ra, int len, struct sockaddr_in6 *addr) 54 { 55 struct nd_opt_hdr *opt; 56 char abuf[INET6_ADDRSTRLEN]; 57 58 logmsg(LOG_DEBUG, "%s %s (%d bytes) on %s\n", str, 59 inet_ntop(addr->sin6_family, (void *)&addr->sin6_addr, 60 abuf, sizeof (abuf)), 61 len, pi->pi_name); 62 logmsg(LOG_DEBUG, "\tMax hop limit: %u\n", ra->nd_ra_curhoplimit); 63 logmsg(LOG_DEBUG, "\tManaged address configuration: %s\n", 64 (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) ? 65 "Set" : "Not set"); 66 logmsg(LOG_DEBUG, "\tOther configuration flag: %s\n", 67 (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) ? 68 "Set" : "Not set"); 69 logmsg(LOG_DEBUG, "\tRouter lifetime: %u\n", 70 ntohs(ra->nd_ra_router_lifetime)); 71 logmsg(LOG_DEBUG, "\tReachable timer: %u\n", 72 ntohl(ra->nd_ra_reachable)); 73 logmsg(LOG_DEBUG, "\tReachable retrans timer: %u\n", 74 ntohl(ra->nd_ra_retransmit)); 75 76 len -= sizeof (*ra); 77 opt = (struct nd_opt_hdr *)&ra[1]; 78 print_opt(opt, len); 79 } 80 81 static void 82 print_opt(struct nd_opt_hdr *opt, int len) 83 { 84 struct nd_opt_prefix_info *po; 85 struct nd_opt_mtu *mo; 86 struct nd_opt_lla *lo; 87 int optlen; 88 char abuf[INET6_ADDRSTRLEN]; 89 char llabuf[BUFSIZ]; 90 91 while (len >= sizeof (struct nd_opt_hdr)) { 92 optlen = opt->nd_opt_len * 8; 93 if (optlen == 0) { 94 logmsg(LOG_DEBUG, "Zero length option!\n"); 95 break; 96 } 97 switch (opt->nd_opt_type) { 98 case ND_OPT_PREFIX_INFORMATION: 99 po = (struct nd_opt_prefix_info *)opt; 100 if (optlen != sizeof (*po) || 101 optlen > len) 102 break; 103 104 logmsg(LOG_DEBUG, "\tPrefix: %s/%u\n", 105 inet_ntop(AF_INET6, (void *)&po->nd_opt_pi_prefix, 106 abuf, sizeof (abuf)), 107 po->nd_opt_pi_prefix_len); 108 logmsg(LOG_DEBUG, "\t\tOn link flag:%s\n", 109 (po->nd_opt_pi_flags_reserved & 110 ND_OPT_PI_FLAG_ONLINK) ? 111 "Set" : "Not set"); 112 logmsg(LOG_DEBUG, "\t\tAuto addrconf flag:%s\n", 113 (po->nd_opt_pi_flags_reserved & 114 ND_OPT_PI_FLAG_AUTO) ? 115 "Set" : "Not set"); 116 logmsg(LOG_DEBUG, "\t\tValid time: %u\n", 117 ntohl(po->nd_opt_pi_valid_time)); 118 logmsg(LOG_DEBUG, "\t\tPreferred time: %u\n", 119 ntohl(po->nd_opt_pi_preferred_time)); 120 break; 121 case ND_OPT_MTU: 122 mo = (struct nd_opt_mtu *)opt; 123 if (optlen != sizeof (*mo) || 124 optlen > len) 125 break; 126 logmsg(LOG_DEBUG, "\tMTU: %d\n", 127 ntohl(mo->nd_opt_mtu_mtu)); 128 break; 129 case ND_OPT_SOURCE_LINKADDR: 130 lo = (struct nd_opt_lla *)opt; 131 if (optlen < 8 || 132 optlen > len) 133 break; 134 (void) fmt_lla(llabuf, sizeof (llabuf), 135 lo->nd_opt_lla_hdw_addr, 136 optlen - sizeof (nd_opt_hdr_t)); 137 logmsg(LOG_DEBUG, "\tSource LLA: len %d <%s>\n", 138 optlen - sizeof (nd_opt_hdr_t), 139 llabuf); 140 break; 141 case ND_OPT_TARGET_LINKADDR: 142 lo = (struct nd_opt_lla *)opt; 143 if (optlen < 8|| 144 optlen > len) 145 break; 146 (void) fmt_lla(llabuf, sizeof (llabuf), 147 lo->nd_opt_lla_hdw_addr, 148 optlen - sizeof (nd_opt_hdr_t)); 149 logmsg(LOG_DEBUG, "\tTarget LLA: len %d <%s>\n", 150 optlen - sizeof (nd_opt_hdr_t), 151 llabuf); 152 break; 153 case ND_OPT_REDIRECTED_HEADER: 154 logmsg(LOG_DEBUG, "\tRedirected header option!\n"); 155 break; 156 default: 157 logmsg(LOG_DEBUG, "Unknown option %d (0x%x)\n", 158 opt->nd_opt_type, opt->nd_opt_type); 159 break; 160 } 161 opt = (struct nd_opt_hdr *)((char *)opt + optlen); 162 len -= optlen; 163 } 164 } 165 166 char * 167 fmt_lla(char *llabuf, int bufsize, uchar_t *lla, int llalen) 168 { 169 int i; 170 char *cp = llabuf; 171 172 for (i = 0; i < llalen; i++) { 173 if (i == llalen - 1) /* Last byte? */ 174 (void) snprintf(cp, bufsize, "%02x", lla[i] & 0xFF); 175 else 176 (void) snprintf(cp, bufsize, "%02x:", lla[i] & 0xFF); 177 bufsize -= strlen(cp); 178 cp += strlen(cp); 179 } 180 return (llabuf); 181 } 182