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