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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
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 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright 2012 David Hoeppner. All rights reserved.
29 */
30
31 /*
32 * Functions related to MIB-II and kstat.
33 */
34
35 #include <sys/types.h>
36 #include <sys/tihdr.h>
37 #include <sys/policy.h>
38 #include <sys/tsol/tnet.h>
39
40 #include <inet/common.h>
41 #include <inet/ip.h>
42 #include <inet/kstatcom.h>
43 #include <inet/snmpcom.h>
44
45 #include <sys/cmn_err.h>
46
47 #include "dccp_impl.h"
48
49 static int dccp_snmp_state(dccp_t *);
50
51 static int
52 dccp_snmp_state(dccp_t *dccp)
53 {
54 if (dccp == NULL) {
55 return (0);
56 }
57
58 switch(dccp->dccp_state) {
59 case DCCPS_CLOSED:
60 return (MIB2_DCCP_closed);
61 default:
62 return (0);
63 }
64 }
65
66 /*
67 * Get the MIB-II stats.
68 */
69 mblk_t *
70 dccp_snmp_get(queue_t *q, mblk_t *mpctl)
71 {
72 conn_t *connp = Q_TO_CONN(q);
73 connf_t *connfp;
74 ip_stack_t *ips;
75 dccp_stack_t *dccps;
76 struct opthdr *optp;
77 mblk_t *mp2ctl;
78 mblk_t *mpdata;
79 mblk_t *mp_conn_ctl = NULL;
80 mblk_t *mp_conn_tail;
81 mblk_t *mp_attr_ctl = NULL;
82 mblk_t *mp_attr_tail;
83 size_t dccp_mib_size;
84 size_t dce_size;
85 zoneid_t zoneid;
86 int i;
87 mib2_dccpConnEntry_t dce;
88
89 mp2ctl = copymsg(mpctl);
90
91 if (mpctl == NULL ||
92 (mpdata = mpctl->b_cont) == NULL ||
93 (mp_conn_ctl = copymsg(mpctl)) == NULL ||
94 (mp_attr_ctl = copymsg(mpctl)) == NULL) {
95 freemsg(mp_conn_ctl);
96 freemsg(mp_attr_ctl);
97 freemsg(mpctl);
98 freemsg(mp2ctl);
99 return (NULL);
100 }
101
102 ips = connp->conn_netstack->netstack_ip;
103 dccps = connp->conn_netstack->netstack_dccp;
104 dce_size = sizeof (mib2_dccpConnEntry_t);
105 zoneid = Q_TO_CONN(q)->conn_zoneid;
106
107 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
108 ips = dccps->dccps_netstack->netstack_ip;
109
110 connfp = &ips->ips_ipcl_globalhash_fanout[i];
111 connp = NULL;
112
113 while ((connp = ipcl_get_next_conn(connfp, connp,
114 IPCL_DCCPCONN)) != NULL) {
115 dccp_t *dccp;
116
117 if (connp->conn_zoneid != zoneid) {
118 continue;
119 }
120
121 dccp = connp->conn_dccp;
122
123 dce.dccpConnState = dccp_snmp_state(dccp);
124
125 if (connp->conn_ipversion == IPV4_VERSION ||
126 (dccp->dccp_state <= DCCPS_LISTEN)) {
127 dce.dccpConnRemAddress =
128 connp->conn_faddr_v4;
129 dce.dccpConnLocalAddress =
130 connp->conn_laddr_v4;
131 }
132
133 dce.dccpConnLocalPort = ntohs(connp->conn_lport);
134 dce.dccpConnRemPort = ntohs(connp->conn_fport);
135
136 dce.dccpConnCreationProcess = (connp->conn_cpid < 0) ?
137 MIB2_UNKNOWN_PROCESS : connp->conn_cpid;
138 dce.dccpConnCreationTime = connp->conn_open_time;
139
140 (void) snmp_append_data2(mp_conn_ctl->b_cont,
141 &mp_conn_tail, (char *)&dce, dce_size);
142 }
143 }
144
145 optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
146 sizeof (struct T_optmgmt_ack)];
147 optp->level = MIB2_DCCP;
148 optp->name = MIB2_DCCP_CONN;
149 optp->len = msgdsize(mp_conn_ctl->b_cont);
150 qreply(q, mp_conn_ctl);
151
152 return (mp2ctl);
153 }