13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011, Joyent Inc. All rights reserved.
25 */
26
27 #include <sys/types.h>
28 #include <sys/tihdr.h>
29 #include <sys/policy.h>
30 #include <sys/tsol/tnet.h>
31 #include <sys/kstat.h>
32
33 #include <inet/common.h>
34 #include <inet/ip.h>
35 #include <inet/tcp.h>
36 #include <inet/tcp_impl.h>
37 #include <inet/tcp_stats.h>
38 #include <inet/kstatcom.h>
39 #include <inet/snmpcom.h>
40
41 static int tcp_kstat_update(kstat_t *, int);
42 static int tcp_kstat2_update(kstat_t *, int);
43 static void tcp_sum_mib(tcp_stack_t *, mib2_tcp_t *);
44
45 static void tcp_add_mib(mib2_tcp_t *, mib2_tcp_t *);
46 static void tcp_add_stats(tcp_stat_counter_t *, tcp_stat_t *);
47 static void tcp_clr_stats(tcp_stat_t *);
48
49 tcp_g_stat_t tcp_g_statistics;
50 kstat_t *tcp_g_kstat;
51
52 /* Translate TCP state to MIB2 TCP state. */
80 case TCPS_FIN_WAIT_2:
81 return (MIB2_TCP_finWait2);
82 case TCPS_TIME_WAIT:
83 return (MIB2_TCP_timeWait);
84 default:
85 return (0);
86 }
87 }
88
89 /*
90 * Return SNMP stuff in buffer in mpdata.
91 */
92 mblk_t *
93 tcp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
94 {
95 mblk_t *mpdata;
96 mblk_t *mp_conn_ctl = NULL;
97 mblk_t *mp_conn_tail;
98 mblk_t *mp_attr_ctl = NULL;
99 mblk_t *mp_attr_tail;
100 mblk_t *mp6_conn_ctl = NULL;
101 mblk_t *mp6_conn_tail;
102 mblk_t *mp6_attr_ctl = NULL;
103 mblk_t *mp6_attr_tail;
104 struct opthdr *optp;
105 mib2_tcpConnEntry_t tce;
106 mib2_tcp6ConnEntry_t tce6;
107 mib2_transportMLPEntry_t mlp;
108 connf_t *connfp;
109 int i;
110 boolean_t ispriv;
111 zoneid_t zoneid;
112 int v4_conn_idx;
113 int v6_conn_idx;
114 conn_t *connp = Q_TO_CONN(q);
115 tcp_stack_t *tcps;
116 ip_stack_t *ipst;
117 mblk_t *mp2ctl;
118 mib2_tcp_t tcp_mib;
119 size_t tcp_mib_size, tce_size, tce6_size;
120
121 /*
122 * make a copy of the original message
123 */
124 mp2ctl = copymsg(mpctl);
125
126 if (mpctl == NULL ||
127 (mpdata = mpctl->b_cont) == NULL ||
128 (mp_conn_ctl = copymsg(mpctl)) == NULL ||
129 (mp_attr_ctl = copymsg(mpctl)) == NULL ||
130 (mp6_conn_ctl = copymsg(mpctl)) == NULL ||
131 (mp6_attr_ctl = copymsg(mpctl)) == NULL) {
132 freemsg(mp_conn_ctl);
133 freemsg(mp_attr_ctl);
134 freemsg(mp6_conn_ctl);
135 freemsg(mp6_attr_ctl);
136 freemsg(mpctl);
137 freemsg(mp2ctl);
138 return (NULL);
139 }
140
141 ipst = connp->conn_netstack->netstack_ip;
142 tcps = connp->conn_netstack->netstack_tcp;
143
144 if (legacy_req) {
145 tcp_mib_size = LEGACY_MIB_SIZE(&tcp_mib, mib2_tcp_t);
146 tce_size = LEGACY_MIB_SIZE(&tce, mib2_tcpConnEntry_t);
147 tce6_size = LEGACY_MIB_SIZE(&tce6, mib2_tcp6ConnEntry_t);
148 } else {
149 tcp_mib_size = sizeof (mib2_tcp_t);
150 tce_size = sizeof (mib2_tcpConnEntry_t);
151 tce6_size = sizeof (mib2_tcp6ConnEntry_t);
152 }
153
154 bzero(&tcp_mib, sizeof (tcp_mib));
155
156 /* build table of connections -- need count in fixed part */
157 SET_MIB(tcp_mib.tcpRtoAlgorithm, 4); /* vanj */
158 SET_MIB(tcp_mib.tcpRtoMin, tcps->tcps_rexmit_interval_min);
159 SET_MIB(tcp_mib.tcpRtoMax, tcps->tcps_rexmit_interval_max);
160 SET_MIB(tcp_mib.tcpMaxConn, -1);
161 SET_MIB(tcp_mib.tcpCurrEstab, 0);
162
163 ispriv =
164 secpolicy_ip_config((Q_TO_CONN(q))->conn_cred, B_TRUE) == 0;
165 zoneid = Q_TO_CONN(q)->conn_zoneid;
166
167 v4_conn_idx = v6_conn_idx = 0;
168 mp_conn_tail = mp_attr_tail = mp6_conn_tail = mp6_attr_tail = NULL;
169
170 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
171 ipst = tcps->tcps_netstack->netstack_ip;
172
173 connfp = &ipst->ips_ipcl_globalhash_fanout[i];
174
175 connp = NULL;
176
177 while ((connp =
178 ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
179 tcp_t *tcp;
180 boolean_t needattr;
181
182 if (connp->conn_zoneid != zoneid)
183 continue; /* not in this zone */
184
185 tcp = connp->conn_tcp;
186 TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
187 tcp->tcp_ibsegs = 0;
188 TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
264 tce6.tcp6ConnEntryInfo.ce_suna = 0;
265 tce6.tcp6ConnEntryInfo.ce_rnxt =
266 tcp->tcp_rnxt - tcp->tcp_rack;
267 tce6.tcp6ConnEntryInfo.ce_rack = 0;
268 }
269
270 tce6.tcp6ConnEntryInfo.ce_swnd = tcp->tcp_swnd;
271 tce6.tcp6ConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
272 tce6.tcp6ConnEntryInfo.ce_rto = tcp->tcp_rto;
273 tce6.tcp6ConnEntryInfo.ce_mss = tcp->tcp_mss;
274 tce6.tcp6ConnEntryInfo.ce_state = tcp->tcp_state;
275
276 tce6.tcp6ConnCreationProcess =
277 (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS :
278 connp->conn_cpid;
279 tce6.tcp6ConnCreationTime = connp->conn_open_time;
280
281 (void) snmp_append_data2(mp6_conn_ctl->b_cont,
282 &mp6_conn_tail, (char *)&tce6, tce6_size);
283
284 mlp.tme_connidx = v6_conn_idx++;
285 if (needattr)
286 (void) snmp_append_data2(mp6_attr_ctl->b_cont,
287 &mp6_attr_tail, (char *)&mlp, sizeof (mlp));
288 }
289 /*
290 * Create an IPv4 table entry for IPv4 entries and also
291 * for IPv6 entries which are bound to in6addr_any
292 * but don't have IPV6_V6ONLY set.
293 * (i.e. anything an IPv4 peer could connect to)
294 */
295 if (connp->conn_ipversion == IPV4_VERSION ||
296 (tcp->tcp_state <= TCPS_LISTEN &&
297 !connp->conn_ipv6_v6only &&
298 IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6))) {
299 if (connp->conn_ipversion == IPV6_VERSION) {
300 tce.tcpConnRemAddress = INADDR_ANY;
301 tce.tcpConnLocalAddress = INADDR_ANY;
302 } else {
303 tce.tcpConnRemAddress =
331 tcp->tcp_rnxt - tcp->tcp_rack;
332 tce.tcpConnEntryInfo.ce_rack = 0;
333 }
334
335 tce.tcpConnEntryInfo.ce_swnd = tcp->tcp_swnd;
336 tce.tcpConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
337 tce.tcpConnEntryInfo.ce_rto = tcp->tcp_rto;
338 tce.tcpConnEntryInfo.ce_mss = tcp->tcp_mss;
339 tce.tcpConnEntryInfo.ce_state =
340 tcp->tcp_state;
341
342 tce.tcpConnCreationProcess =
343 (connp->conn_cpid < 0) ?
344 MIB2_UNKNOWN_PROCESS :
345 connp->conn_cpid;
346 tce.tcpConnCreationTime = connp->conn_open_time;
347
348 (void) snmp_append_data2(mp_conn_ctl->b_cont,
349 &mp_conn_tail, (char *)&tce, tce_size);
350
351 mlp.tme_connidx = v4_conn_idx++;
352 if (needattr)
353 (void) snmp_append_data2(
354 mp_attr_ctl->b_cont,
355 &mp_attr_tail, (char *)&mlp,
356 sizeof (mlp));
357 }
358 }
359 }
360
361 tcp_sum_mib(tcps, &tcp_mib);
362
363 /* Fixed length structure for IPv4 and IPv6 counters */
364 SET_MIB(tcp_mib.tcpConnTableSize, tce_size);
365 SET_MIB(tcp_mib.tcp6ConnTableSize, tce6_size);
366
367 /*
368 * Synchronize 32- and 64-bit counters. Note that tcpInSegs and
369 * tcpOutSegs are not updated anywhere in TCP. The new 64 bits
370 * counters are used. Hence the old counters' values in tcp_sc_mib
400 qreply(q, mp_attr_ctl);
401
402 /* table of IPv6 connections... */
403 optp = (struct opthdr *)&mp6_conn_ctl->b_rptr[
404 sizeof (struct T_optmgmt_ack)];
405 optp->level = MIB2_TCP6;
406 optp->name = MIB2_TCP6_CONN;
407 optp->len = msgdsize(mp6_conn_ctl->b_cont);
408 qreply(q, mp6_conn_ctl);
409
410 /* table of IPv6 MLP attributes... */
411 optp = (struct opthdr *)&mp6_attr_ctl->b_rptr[
412 sizeof (struct T_optmgmt_ack)];
413 optp->level = MIB2_TCP6;
414 optp->name = EXPER_XPORT_MLP;
415 optp->len = msgdsize(mp6_attr_ctl->b_cont);
416 if (optp->len == 0)
417 freemsg(mp6_attr_ctl);
418 else
419 qreply(q, mp6_attr_ctl);
420 return (mp2ctl);
421 }
422
423 /* Return 0 if invalid set request, 1 otherwise, including non-tcp requests */
424 /* ARGSUSED */
425 int
426 tcp_snmp_set(queue_t *q, int level, int name, uchar_t *ptr, int len)
427 {
428 mib2_tcpConnEntry_t *tce = (mib2_tcpConnEntry_t *)ptr;
429
430 switch (level) {
431 case MIB2_TCP:
432 switch (name) {
433 case 13:
434 if (tce->tcpConnState != MIB2_TCP_deleteTCB)
435 return (0);
436 /* TODO: delete entry defined by tce */
437 return (1);
438 default:
439 return (0);
|
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011, Joyent Inc. All rights reserved.
25 */
26
27 #include <sys/types.h>
28 #include <sys/tihdr.h>
29 #include <sys/policy.h>
30 #include <sys/tsol/tnet.h>
31 #include <sys/kstat.h>
32
33 #include <sys/strsun.h>
34 #include <sys/stropts.h>
35 #include <sys/strsubr.h>
36 #include <sys/socket.h>
37 #include <sys/socketvar.h>
38 #include <sys/uio.h>
39
40 #include <inet/common.h>
41 #include <inet/ip.h>
42 #include <inet/tcp.h>
43 #include <inet/tcp_impl.h>
44 #include <inet/tcp_stats.h>
45 #include <inet/kstatcom.h>
46 #include <inet/snmpcom.h>
47
48 static int tcp_kstat_update(kstat_t *, int);
49 static int tcp_kstat2_update(kstat_t *, int);
50 static void tcp_sum_mib(tcp_stack_t *, mib2_tcp_t *);
51
52 static void tcp_add_mib(mib2_tcp_t *, mib2_tcp_t *);
53 static void tcp_add_stats(tcp_stat_counter_t *, tcp_stat_t *);
54 static void tcp_clr_stats(tcp_stat_t *);
55
56 tcp_g_stat_t tcp_g_statistics;
57 kstat_t *tcp_g_kstat;
58
59 /* Translate TCP state to MIB2 TCP state. */
87 case TCPS_FIN_WAIT_2:
88 return (MIB2_TCP_finWait2);
89 case TCPS_TIME_WAIT:
90 return (MIB2_TCP_timeWait);
91 default:
92 return (0);
93 }
94 }
95
96 /*
97 * Return SNMP stuff in buffer in mpdata.
98 */
99 mblk_t *
100 tcp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
101 {
102 mblk_t *mpdata;
103 mblk_t *mp_conn_ctl = NULL;
104 mblk_t *mp_conn_tail;
105 mblk_t *mp_attr_ctl = NULL;
106 mblk_t *mp_attr_tail;
107 mblk_t *mp_pidnode_ctl = NULL;
108 mblk_t *mp_pidnode_tail;
109 mblk_t *mp6_conn_ctl = NULL;
110 mblk_t *mp6_conn_tail;
111 mblk_t *mp6_attr_ctl = NULL;
112 mblk_t *mp6_attr_tail;
113 mblk_t *mp6_pidnode_ctl = NULL;
114 mblk_t *mp6_pidnode_tail;
115 struct opthdr *optp;
116 mib2_tcpConnEntry_t tce;
117 mib2_tcp6ConnEntry_t tce6;
118 mib2_transportMLPEntry_t mlp;
119 connf_t *connfp;
120 int i;
121 boolean_t ispriv;
122 zoneid_t zoneid;
123 int v4_conn_idx;
124 int v6_conn_idx;
125 conn_t *connp = Q_TO_CONN(q);
126 tcp_stack_t *tcps;
127 ip_stack_t *ipst;
128 mblk_t *mp2ctl;
129 mib2_tcp_t tcp_mib;
130 size_t tcp_mib_size, tce_size, tce6_size;
131
132 /*
133 * make a copy of the original message
134 */
135 mp2ctl = copymsg(mpctl);
136
137 if (mpctl == NULL ||
138 (mpdata = mpctl->b_cont) == NULL ||
139 (mp_conn_ctl = copymsg(mpctl)) == NULL ||
140 (mp_attr_ctl = copymsg(mpctl)) == NULL ||
141 (mp_pidnode_ctl = copymsg(mpctl)) == NULL ||
142 (mp6_conn_ctl = copymsg(mpctl)) == NULL ||
143 (mp6_attr_ctl = copymsg(mpctl)) == NULL ||
144 (mp6_pidnode_ctl = copymsg(mpctl)) == NULL) {
145 freemsg(mp_conn_ctl);
146 freemsg(mp_attr_ctl);
147 freemsg(mp_pidnode_ctl);
148 freemsg(mp6_conn_ctl);
149 freemsg(mp6_attr_ctl);
150 freemsg(mp6_pidnode_ctl);
151 freemsg(mpctl);
152 freemsg(mp2ctl);
153 return (NULL);
154 }
155
156 ipst = connp->conn_netstack->netstack_ip;
157 tcps = connp->conn_netstack->netstack_tcp;
158
159 if (legacy_req) {
160 tcp_mib_size = LEGACY_MIB_SIZE(&tcp_mib, mib2_tcp_t);
161 tce_size = LEGACY_MIB_SIZE(&tce, mib2_tcpConnEntry_t);
162 tce6_size = LEGACY_MIB_SIZE(&tce6, mib2_tcp6ConnEntry_t);
163 } else {
164 tcp_mib_size = sizeof (mib2_tcp_t);
165 tce_size = sizeof (mib2_tcpConnEntry_t);
166 tce6_size = sizeof (mib2_tcp6ConnEntry_t);
167 }
168
169 bzero(&tcp_mib, sizeof (tcp_mib));
170
171 /* build table of connections -- need count in fixed part */
172 SET_MIB(tcp_mib.tcpRtoAlgorithm, 4); /* vanj */
173 SET_MIB(tcp_mib.tcpRtoMin, tcps->tcps_rexmit_interval_min);
174 SET_MIB(tcp_mib.tcpRtoMax, tcps->tcps_rexmit_interval_max);
175 SET_MIB(tcp_mib.tcpMaxConn, -1);
176 SET_MIB(tcp_mib.tcpCurrEstab, 0);
177
178 ispriv =
179 secpolicy_ip_config((Q_TO_CONN(q))->conn_cred, B_TRUE) == 0;
180 zoneid = Q_TO_CONN(q)->conn_zoneid;
181
182 v4_conn_idx = v6_conn_idx = 0;
183 mp_conn_tail = mp_attr_tail = mp6_conn_tail = mp6_attr_tail = NULL;
184 mp_pidnode_tail = mp6_pidnode_tail = NULL;
185
186 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
187 ipst = tcps->tcps_netstack->netstack_ip;
188
189 connfp = &ipst->ips_ipcl_globalhash_fanout[i];
190
191 connp = NULL;
192
193 while ((connp =
194 ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
195 tcp_t *tcp;
196 boolean_t needattr;
197
198 if (connp->conn_zoneid != zoneid)
199 continue; /* not in this zone */
200
201 tcp = connp->conn_tcp;
202 TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
203 tcp->tcp_ibsegs = 0;
204 TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
280 tce6.tcp6ConnEntryInfo.ce_suna = 0;
281 tce6.tcp6ConnEntryInfo.ce_rnxt =
282 tcp->tcp_rnxt - tcp->tcp_rack;
283 tce6.tcp6ConnEntryInfo.ce_rack = 0;
284 }
285
286 tce6.tcp6ConnEntryInfo.ce_swnd = tcp->tcp_swnd;
287 tce6.tcp6ConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
288 tce6.tcp6ConnEntryInfo.ce_rto = tcp->tcp_rto;
289 tce6.tcp6ConnEntryInfo.ce_mss = tcp->tcp_mss;
290 tce6.tcp6ConnEntryInfo.ce_state = tcp->tcp_state;
291
292 tce6.tcp6ConnCreationProcess =
293 (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS :
294 connp->conn_cpid;
295 tce6.tcp6ConnCreationTime = connp->conn_open_time;
296
297 (void) snmp_append_data2(mp6_conn_ctl->b_cont,
298 &mp6_conn_tail, (char *)&tce6, tce6_size);
299
300 (void) snmp_append_data2(mp6_pidnode_ctl->b_cont,
301 &mp6_pidnode_tail, (char *)&tce6, tce6_size);
302
303 (void) snmp_append_mblk2(mp6_pidnode_ctl->b_cont,
304 &mp6_pidnode_tail, conn_get_pid_mblk(connp));
305
306 mlp.tme_connidx = v6_conn_idx++;
307 if (needattr)
308 (void) snmp_append_data2(mp6_attr_ctl->b_cont,
309 &mp6_attr_tail, (char *)&mlp, sizeof (mlp));
310 }
311 /*
312 * Create an IPv4 table entry for IPv4 entries and also
313 * for IPv6 entries which are bound to in6addr_any
314 * but don't have IPV6_V6ONLY set.
315 * (i.e. anything an IPv4 peer could connect to)
316 */
317 if (connp->conn_ipversion == IPV4_VERSION ||
318 (tcp->tcp_state <= TCPS_LISTEN &&
319 !connp->conn_ipv6_v6only &&
320 IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6))) {
321 if (connp->conn_ipversion == IPV6_VERSION) {
322 tce.tcpConnRemAddress = INADDR_ANY;
323 tce.tcpConnLocalAddress = INADDR_ANY;
324 } else {
325 tce.tcpConnRemAddress =
353 tcp->tcp_rnxt - tcp->tcp_rack;
354 tce.tcpConnEntryInfo.ce_rack = 0;
355 }
356
357 tce.tcpConnEntryInfo.ce_swnd = tcp->tcp_swnd;
358 tce.tcpConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
359 tce.tcpConnEntryInfo.ce_rto = tcp->tcp_rto;
360 tce.tcpConnEntryInfo.ce_mss = tcp->tcp_mss;
361 tce.tcpConnEntryInfo.ce_state =
362 tcp->tcp_state;
363
364 tce.tcpConnCreationProcess =
365 (connp->conn_cpid < 0) ?
366 MIB2_UNKNOWN_PROCESS :
367 connp->conn_cpid;
368 tce.tcpConnCreationTime = connp->conn_open_time;
369
370 (void) snmp_append_data2(mp_conn_ctl->b_cont,
371 &mp_conn_tail, (char *)&tce, tce_size);
372
373 (void) snmp_append_data2(mp_pidnode_ctl->b_cont,
374 &mp_pidnode_tail, (char *)&tce, tce_size);
375
376 (void) snmp_append_mblk2(mp_pidnode_ctl->b_cont,
377 &mp_pidnode_tail, conn_get_pid_mblk(connp));
378
379 mlp.tme_connidx = v4_conn_idx++;
380 if (needattr)
381 (void) snmp_append_data2(
382 mp_attr_ctl->b_cont,
383 &mp_attr_tail, (char *)&mlp,
384 sizeof (mlp));
385 }
386 }
387 }
388
389 tcp_sum_mib(tcps, &tcp_mib);
390
391 /* Fixed length structure for IPv4 and IPv6 counters */
392 SET_MIB(tcp_mib.tcpConnTableSize, tce_size);
393 SET_MIB(tcp_mib.tcp6ConnTableSize, tce6_size);
394
395 /*
396 * Synchronize 32- and 64-bit counters. Note that tcpInSegs and
397 * tcpOutSegs are not updated anywhere in TCP. The new 64 bits
398 * counters are used. Hence the old counters' values in tcp_sc_mib
428 qreply(q, mp_attr_ctl);
429
430 /* table of IPv6 connections... */
431 optp = (struct opthdr *)&mp6_conn_ctl->b_rptr[
432 sizeof (struct T_optmgmt_ack)];
433 optp->level = MIB2_TCP6;
434 optp->name = MIB2_TCP6_CONN;
435 optp->len = msgdsize(mp6_conn_ctl->b_cont);
436 qreply(q, mp6_conn_ctl);
437
438 /* table of IPv6 MLP attributes... */
439 optp = (struct opthdr *)&mp6_attr_ctl->b_rptr[
440 sizeof (struct T_optmgmt_ack)];
441 optp->level = MIB2_TCP6;
442 optp->name = EXPER_XPORT_MLP;
443 optp->len = msgdsize(mp6_attr_ctl->b_cont);
444 if (optp->len == 0)
445 freemsg(mp6_attr_ctl);
446 else
447 qreply(q, mp6_attr_ctl);
448
449 /* table of EXPER_XPORT_PROC_INFO ipv4 */
450 optp = (struct opthdr *)&mp_pidnode_ctl->b_rptr[
451 sizeof (struct T_optmgmt_ack)];
452 optp->level = MIB2_TCP;
453 optp->name = EXPER_XPORT_PROC_INFO;
454 optp->len = msgdsize(mp_pidnode_ctl->b_cont);
455 if (optp->len == 0)
456 freemsg(mp_pidnode_ctl);
457 else
458 qreply(q, mp_pidnode_ctl);
459
460 /* table of EXPER_XPORT_PROC_INFO ipv6 */
461 optp = (struct opthdr *)&mp6_pidnode_ctl->b_rptr[
462 sizeof (struct T_optmgmt_ack)];
463 optp->level = MIB2_TCP6;
464 optp->name = EXPER_XPORT_PROC_INFO;
465 optp->len = msgdsize(mp6_pidnode_ctl->b_cont);
466 if (optp->len == 0)
467 freemsg(mp6_pidnode_ctl);
468 else
469 qreply(q, mp6_pidnode_ctl);
470
471 return (mp2ctl);
472 }
473
474 /* Return 0 if invalid set request, 1 otherwise, including non-tcp requests */
475 /* ARGSUSED */
476 int
477 tcp_snmp_set(queue_t *q, int level, int name, uchar_t *ptr, int len)
478 {
479 mib2_tcpConnEntry_t *tce = (mib2_tcpConnEntry_t *)ptr;
480
481 switch (level) {
482 case MIB2_TCP:
483 switch (name) {
484 case 13:
485 if (tce->tcpConnState != MIB2_TCP_deleteTCB)
486 return (0);
487 /* TODO: delete entry defined by tce */
488 return (1);
489 default:
490 return (0);
|