/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include "defs.h" #include "tables.h" static void print_opt(struct nd_opt_hdr *opt, int len); void print_route_sol(char *str, struct phyint *pi, struct nd_router_solicit *rs, int len, struct sockaddr_in6 *addr) { struct nd_opt_hdr *opt; char abuf[INET6_ADDRSTRLEN]; logmsg(LOG_DEBUG, "%s %s (%d bytes) on %s\n", str, inet_ntop(addr->sin6_family, (void *)&addr->sin6_addr, abuf, sizeof (abuf)), len, pi->pi_name); len -= sizeof (*rs); opt = (struct nd_opt_hdr *)&rs[1]; print_opt(opt, len); } void print_route_adv(char *str, struct phyint *pi, struct nd_router_advert *ra, int len, struct sockaddr_in6 *addr) { struct nd_opt_hdr *opt; char abuf[INET6_ADDRSTRLEN]; logmsg(LOG_DEBUG, "%s %s (%d bytes) on %s\n", str, inet_ntop(addr->sin6_family, (void *)&addr->sin6_addr, abuf, sizeof (abuf)), len, pi->pi_name); logmsg(LOG_DEBUG, "\tMax hop limit: %u\n", ra->nd_ra_curhoplimit); logmsg(LOG_DEBUG, "\tManaged address configuration: %s\n", (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) ? "Set" : "Not set"); logmsg(LOG_DEBUG, "\tOther configuration flag: %s\n", (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) ? "Set" : "Not set"); logmsg(LOG_DEBUG, "\tRouter lifetime: %u\n", ntohs(ra->nd_ra_router_lifetime)); logmsg(LOG_DEBUG, "\tReachable timer: %u\n", ntohl(ra->nd_ra_reachable)); logmsg(LOG_DEBUG, "\tReachable retrans timer: %u\n", ntohl(ra->nd_ra_retransmit)); len -= sizeof (*ra); opt = (struct nd_opt_hdr *)&ra[1]; print_opt(opt, len); } static void print_opt(struct nd_opt_hdr *opt, int len) { struct nd_opt_prefix_info *po; struct nd_opt_mtu *mo; struct nd_opt_lla *lo; int optlen; char abuf[INET6_ADDRSTRLEN]; char llabuf[BUFSIZ]; while (len >= sizeof (struct nd_opt_hdr)) { optlen = opt->nd_opt_len * 8; if (optlen == 0) { logmsg(LOG_DEBUG, "Zero length option!\n"); break; } switch (opt->nd_opt_type) { case ND_OPT_PREFIX_INFORMATION: po = (struct nd_opt_prefix_info *)opt; if (optlen != sizeof (*po) || optlen > len) break; logmsg(LOG_DEBUG, "\tPrefix: %s/%u\n", inet_ntop(AF_INET6, (void *)&po->nd_opt_pi_prefix, abuf, sizeof (abuf)), po->nd_opt_pi_prefix_len); logmsg(LOG_DEBUG, "\t\tOn link flag:%s\n", (po->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK) ? "Set" : "Not set"); logmsg(LOG_DEBUG, "\t\tAuto addrconf flag:%s\n", (po->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO) ? "Set" : "Not set"); logmsg(LOG_DEBUG, "\t\tValid time: %u\n", ntohl(po->nd_opt_pi_valid_time)); logmsg(LOG_DEBUG, "\t\tPreferred time: %u\n", ntohl(po->nd_opt_pi_preferred_time)); break; case ND_OPT_MTU: mo = (struct nd_opt_mtu *)opt; if (optlen != sizeof (*mo) || optlen > len) break; logmsg(LOG_DEBUG, "\tMTU: %d\n", ntohl(mo->nd_opt_mtu_mtu)); break; case ND_OPT_SOURCE_LINKADDR: lo = (struct nd_opt_lla *)opt; if (optlen < 8 || optlen > len) break; (void) fmt_lla(llabuf, sizeof (llabuf), lo->nd_opt_lla_hdw_addr, optlen - sizeof (nd_opt_hdr_t)); logmsg(LOG_DEBUG, "\tSource LLA: len %d <%s>\n", optlen - sizeof (nd_opt_hdr_t), llabuf); break; case ND_OPT_TARGET_LINKADDR: lo = (struct nd_opt_lla *)opt; if (optlen < 8|| optlen > len) break; (void) fmt_lla(llabuf, sizeof (llabuf), lo->nd_opt_lla_hdw_addr, optlen - sizeof (nd_opt_hdr_t)); logmsg(LOG_DEBUG, "\tTarget LLA: len %d <%s>\n", optlen - sizeof (nd_opt_hdr_t), llabuf); break; case ND_OPT_REDIRECTED_HEADER: logmsg(LOG_DEBUG, "\tRedirected header option!\n"); break; default: logmsg(LOG_DEBUG, "Unknown option %d (0x%x)\n", opt->nd_opt_type, opt->nd_opt_type); break; } opt = (struct nd_opt_hdr *)((char *)opt + optlen); len -= optlen; } } char * fmt_lla(char *llabuf, int bufsize, uchar_t *lla, int llalen) { int i; char *cp = llabuf; for (i = 0; i < llalen; i++) { if (i == llalen - 1) /* Last byte? */ (void) snprintf(cp, bufsize, "%02x", lla[i] & 0xFF); else (void) snprintf(cp, bufsize, "%02x:", lla[i] & 0xFF); bufsize -= strlen(cp); cp += strlen(cp); } return (llabuf); }