1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include "defs.h"
30*0Sstevel@tonic-gate #include "tables.h"
31*0Sstevel@tonic-gate
32*0Sstevel@tonic-gate static void print_opt(struct nd_opt_hdr *opt, int len);
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gate void
print_route_sol(char * str,struct phyint * pi,struct nd_router_solicit * rs,int len,struct sockaddr_in6 * addr)35*0Sstevel@tonic-gate print_route_sol(char *str, struct phyint *pi,
36*0Sstevel@tonic-gate struct nd_router_solicit *rs, int len, struct sockaddr_in6 *addr)
37*0Sstevel@tonic-gate {
38*0Sstevel@tonic-gate struct nd_opt_hdr *opt;
39*0Sstevel@tonic-gate char abuf[INET6_ADDRSTRLEN];
40*0Sstevel@tonic-gate
41*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "%s %s (%d bytes) on %s\n", str,
42*0Sstevel@tonic-gate inet_ntop(addr->sin6_family, (void *)&addr->sin6_addr,
43*0Sstevel@tonic-gate abuf, sizeof (abuf)),
44*0Sstevel@tonic-gate len, pi->pi_name);
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate len -= sizeof (*rs);
47*0Sstevel@tonic-gate opt = (struct nd_opt_hdr *)&rs[1];
48*0Sstevel@tonic-gate print_opt(opt, len);
49*0Sstevel@tonic-gate }
50*0Sstevel@tonic-gate
51*0Sstevel@tonic-gate void
print_route_adv(char * str,struct phyint * pi,struct nd_router_advert * ra,int len,struct sockaddr_in6 * addr)52*0Sstevel@tonic-gate print_route_adv(char *str, struct phyint *pi,
53*0Sstevel@tonic-gate struct nd_router_advert *ra, int len, struct sockaddr_in6 *addr)
54*0Sstevel@tonic-gate {
55*0Sstevel@tonic-gate struct nd_opt_hdr *opt;
56*0Sstevel@tonic-gate char abuf[INET6_ADDRSTRLEN];
57*0Sstevel@tonic-gate
58*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "%s %s (%d bytes) on %s\n", str,
59*0Sstevel@tonic-gate inet_ntop(addr->sin6_family, (void *)&addr->sin6_addr,
60*0Sstevel@tonic-gate abuf, sizeof (abuf)),
61*0Sstevel@tonic-gate len, pi->pi_name);
62*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tMax hop limit: %u\n", ra->nd_ra_curhoplimit);
63*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tManaged address configuration: %s\n",
64*0Sstevel@tonic-gate (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) ?
65*0Sstevel@tonic-gate "Set" : "Not set");
66*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tOther configuration flag: %s\n",
67*0Sstevel@tonic-gate (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) ?
68*0Sstevel@tonic-gate "Set" : "Not set");
69*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tRouter lifetime: %u\n",
70*0Sstevel@tonic-gate ntohs(ra->nd_ra_router_lifetime));
71*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tReachable timer: %u\n",
72*0Sstevel@tonic-gate ntohl(ra->nd_ra_reachable));
73*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tReachable retrans timer: %u\n",
74*0Sstevel@tonic-gate ntohl(ra->nd_ra_retransmit));
75*0Sstevel@tonic-gate
76*0Sstevel@tonic-gate len -= sizeof (*ra);
77*0Sstevel@tonic-gate opt = (struct nd_opt_hdr *)&ra[1];
78*0Sstevel@tonic-gate print_opt(opt, len);
79*0Sstevel@tonic-gate }
80*0Sstevel@tonic-gate
81*0Sstevel@tonic-gate static void
print_opt(struct nd_opt_hdr * opt,int len)82*0Sstevel@tonic-gate print_opt(struct nd_opt_hdr *opt, int len)
83*0Sstevel@tonic-gate {
84*0Sstevel@tonic-gate struct nd_opt_prefix_info *po;
85*0Sstevel@tonic-gate struct nd_opt_mtu *mo;
86*0Sstevel@tonic-gate struct nd_opt_lla *lo;
87*0Sstevel@tonic-gate int optlen;
88*0Sstevel@tonic-gate char abuf[INET6_ADDRSTRLEN];
89*0Sstevel@tonic-gate char llabuf[BUFSIZ];
90*0Sstevel@tonic-gate
91*0Sstevel@tonic-gate while (len >= sizeof (struct nd_opt_hdr)) {
92*0Sstevel@tonic-gate optlen = opt->nd_opt_len * 8;
93*0Sstevel@tonic-gate if (optlen == 0) {
94*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "Zero length option!\n");
95*0Sstevel@tonic-gate break;
96*0Sstevel@tonic-gate }
97*0Sstevel@tonic-gate switch (opt->nd_opt_type) {
98*0Sstevel@tonic-gate case ND_OPT_PREFIX_INFORMATION:
99*0Sstevel@tonic-gate po = (struct nd_opt_prefix_info *)opt;
100*0Sstevel@tonic-gate if (optlen != sizeof (*po) ||
101*0Sstevel@tonic-gate optlen > len)
102*0Sstevel@tonic-gate break;
103*0Sstevel@tonic-gate
104*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tPrefix: %s/%u\n",
105*0Sstevel@tonic-gate inet_ntop(AF_INET6, (void *)&po->nd_opt_pi_prefix,
106*0Sstevel@tonic-gate abuf, sizeof (abuf)),
107*0Sstevel@tonic-gate po->nd_opt_pi_prefix_len);
108*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\t\tOn link flag:%s\n",
109*0Sstevel@tonic-gate (po->nd_opt_pi_flags_reserved &
110*0Sstevel@tonic-gate ND_OPT_PI_FLAG_ONLINK) ?
111*0Sstevel@tonic-gate "Set" : "Not set");
112*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\t\tAuto addrconf flag:%s\n",
113*0Sstevel@tonic-gate (po->nd_opt_pi_flags_reserved &
114*0Sstevel@tonic-gate ND_OPT_PI_FLAG_AUTO) ?
115*0Sstevel@tonic-gate "Set" : "Not set");
116*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\t\tValid time: %u\n",
117*0Sstevel@tonic-gate ntohl(po->nd_opt_pi_valid_time));
118*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\t\tPreferred time: %u\n",
119*0Sstevel@tonic-gate ntohl(po->nd_opt_pi_preferred_time));
120*0Sstevel@tonic-gate break;
121*0Sstevel@tonic-gate case ND_OPT_MTU:
122*0Sstevel@tonic-gate mo = (struct nd_opt_mtu *)opt;
123*0Sstevel@tonic-gate if (optlen != sizeof (*mo) ||
124*0Sstevel@tonic-gate optlen > len)
125*0Sstevel@tonic-gate break;
126*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tMTU: %d\n",
127*0Sstevel@tonic-gate ntohl(mo->nd_opt_mtu_mtu));
128*0Sstevel@tonic-gate break;
129*0Sstevel@tonic-gate case ND_OPT_SOURCE_LINKADDR:
130*0Sstevel@tonic-gate lo = (struct nd_opt_lla *)opt;
131*0Sstevel@tonic-gate if (optlen < 8 ||
132*0Sstevel@tonic-gate optlen > len)
133*0Sstevel@tonic-gate break;
134*0Sstevel@tonic-gate (void) fmt_lla(llabuf, sizeof (llabuf),
135*0Sstevel@tonic-gate lo->nd_opt_lla_hdw_addr,
136*0Sstevel@tonic-gate optlen - sizeof (nd_opt_hdr_t));
137*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tSource LLA: len %d <%s>\n",
138*0Sstevel@tonic-gate optlen - sizeof (nd_opt_hdr_t),
139*0Sstevel@tonic-gate llabuf);
140*0Sstevel@tonic-gate break;
141*0Sstevel@tonic-gate case ND_OPT_TARGET_LINKADDR:
142*0Sstevel@tonic-gate lo = (struct nd_opt_lla *)opt;
143*0Sstevel@tonic-gate if (optlen < 8||
144*0Sstevel@tonic-gate optlen > len)
145*0Sstevel@tonic-gate break;
146*0Sstevel@tonic-gate (void) fmt_lla(llabuf, sizeof (llabuf),
147*0Sstevel@tonic-gate lo->nd_opt_lla_hdw_addr,
148*0Sstevel@tonic-gate optlen - sizeof (nd_opt_hdr_t));
149*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tTarget LLA: len %d <%s>\n",
150*0Sstevel@tonic-gate optlen - sizeof (nd_opt_hdr_t),
151*0Sstevel@tonic-gate llabuf);
152*0Sstevel@tonic-gate break;
153*0Sstevel@tonic-gate case ND_OPT_REDIRECTED_HEADER:
154*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "\tRedirected header option!\n");
155*0Sstevel@tonic-gate break;
156*0Sstevel@tonic-gate default:
157*0Sstevel@tonic-gate logmsg(LOG_DEBUG, "Unknown option %d (0x%x)\n",
158*0Sstevel@tonic-gate opt->nd_opt_type, opt->nd_opt_type);
159*0Sstevel@tonic-gate break;
160*0Sstevel@tonic-gate }
161*0Sstevel@tonic-gate opt = (struct nd_opt_hdr *)((char *)opt + optlen);
162*0Sstevel@tonic-gate len -= optlen;
163*0Sstevel@tonic-gate }
164*0Sstevel@tonic-gate }
165*0Sstevel@tonic-gate
166*0Sstevel@tonic-gate char *
fmt_lla(char * llabuf,int bufsize,uchar_t * lla,int llalen)167*0Sstevel@tonic-gate fmt_lla(char *llabuf, int bufsize, uchar_t *lla, int llalen)
168*0Sstevel@tonic-gate {
169*0Sstevel@tonic-gate int i;
170*0Sstevel@tonic-gate char *cp = llabuf;
171*0Sstevel@tonic-gate
172*0Sstevel@tonic-gate for (i = 0; i < llalen; i++) {
173*0Sstevel@tonic-gate if (i == llalen - 1) /* Last byte? */
174*0Sstevel@tonic-gate (void) snprintf(cp, bufsize, "%02x", lla[i] & 0xFF);
175*0Sstevel@tonic-gate else
176*0Sstevel@tonic-gate (void) snprintf(cp, bufsize, "%02x:", lla[i] & 0xFF);
177*0Sstevel@tonic-gate bufsize -= strlen(cp);
178*0Sstevel@tonic-gate cp += strlen(cp);
179*0Sstevel@tonic-gate }
180*0Sstevel@tonic-gate return (llabuf);
181*0Sstevel@tonic-gate }
182