Print this page
XXXX adding PID information to netstat output


  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         conn_pid_node_list_hdr_t        *cph;
 133 
 134         /*
 135          * make a copy of the original message
 136          */
 137         mp2ctl = copymsg(mpctl);
 138 
 139         if (mpctl == NULL ||
 140             (mpdata = mpctl->b_cont) == NULL ||
 141             (mp_conn_ctl = copymsg(mpctl)) == NULL ||
 142             (mp_attr_ctl = copymsg(mpctl)) == NULL ||
 143             (mp_pidnode_ctl = copymsg(mpctl)) == NULL ||
 144             (mp6_conn_ctl = copymsg(mpctl)) == NULL ||
 145             (mp6_attr_ctl = copymsg(mpctl)) == NULL ||
 146             (mp6_pidnode_ctl = copymsg(mpctl)) == NULL) {
 147                 freemsg(mp_conn_ctl);
 148                 freemsg(mp_attr_ctl);
 149                 freemsg(mp_pidnode_ctl);
 150                 freemsg(mp6_conn_ctl);
 151                 freemsg(mp6_attr_ctl);
 152                 freemsg(mp6_pidnode_ctl);
 153                 freemsg(mpctl);
 154                 freemsg(mp2ctl);
 155                 return (NULL);
 156         }
 157 
 158         ipst = connp->conn_netstack->netstack_ip;
 159         tcps = connp->conn_netstack->netstack_tcp;
 160 
 161         if (legacy_req) {
 162                 tcp_mib_size = LEGACY_MIB_SIZE(&tcp_mib, mib2_tcp_t);
 163                 tce_size = LEGACY_MIB_SIZE(&tce, mib2_tcpConnEntry_t);
 164                 tce6_size = LEGACY_MIB_SIZE(&tce6, mib2_tcp6ConnEntry_t);
 165         } else {
 166                 tcp_mib_size = sizeof (mib2_tcp_t);
 167                 tce_size = sizeof (mib2_tcpConnEntry_t);
 168                 tce6_size = sizeof (mib2_tcp6ConnEntry_t);
 169         }
 170 
 171         bzero(&tcp_mib, sizeof (tcp_mib));
 172 
 173         /* build table of connections -- need count in fixed part */
 174         SET_MIB(tcp_mib.tcpRtoAlgorithm, 4);   /* vanj */
 175         SET_MIB(tcp_mib.tcpRtoMin, tcps->tcps_rexmit_interval_min);
 176         SET_MIB(tcp_mib.tcpRtoMax, tcps->tcps_rexmit_interval_max);
 177         SET_MIB(tcp_mib.tcpMaxConn, -1);
 178         SET_MIB(tcp_mib.tcpCurrEstab, 0);
 179 
 180         ispriv =
 181             secpolicy_ip_config((Q_TO_CONN(q))->conn_cred, B_TRUE) == 0;
 182         zoneid = Q_TO_CONN(q)->conn_zoneid;
 183 
 184         v4_conn_idx = v6_conn_idx = 0;
 185         mp_conn_tail = mp_attr_tail = mp6_conn_tail = mp6_attr_tail = NULL;
 186         mp_pidnode_tail = mp6_pidnode_tail = NULL;
 187 
 188         for (i = 0; i < CONN_G_HASH_SIZE; i++) {
 189                 ipst = tcps->tcps_netstack->netstack_ip;
 190 
 191                 connfp = &ipst->ips_ipcl_globalhash_fanout[i];
 192 
 193                 connp = NULL;
 194 
 195                 while ((connp =
 196                     ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
 197                         tcp_t *tcp;
 198                         boolean_t needattr;
 199 
 200                         if (connp->conn_zoneid != zoneid)
 201                                 continue;       /* not in this zone */
 202 
 203                         tcp = connp->conn_tcp;
 204                         TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
 205                         tcp->tcp_ibsegs = 0;
 206                         TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);


 282                                 tce6.tcp6ConnEntryInfo.ce_suna = 0;
 283                                 tce6.tcp6ConnEntryInfo.ce_rnxt =
 284                                     tcp->tcp_rnxt - tcp->tcp_rack;
 285                                 tce6.tcp6ConnEntryInfo.ce_rack = 0;
 286                         }
 287 
 288                         tce6.tcp6ConnEntryInfo.ce_swnd = tcp->tcp_swnd;
 289                         tce6.tcp6ConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
 290                         tce6.tcp6ConnEntryInfo.ce_rto =  tcp->tcp_rto;
 291                         tce6.tcp6ConnEntryInfo.ce_mss =  tcp->tcp_mss;
 292                         tce6.tcp6ConnEntryInfo.ce_state = tcp->tcp_state;
 293 
 294                         tce6.tcp6ConnCreationProcess =
 295                             (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS :
 296                             connp->conn_cpid;
 297                         tce6.tcp6ConnCreationTime = connp->conn_open_time;
 298 
 299                         (void) snmp_append_data2(mp6_conn_ctl->b_cont,
 300                             &mp6_conn_tail, (char *)&tce6, tce6_size);
 301 
 302                         /* my data */
 303                         /* push connt_t */
 304                         (void) snmp_append_data2(mp6_pidnode_ctl->b_cont,
 305                                 &mp6_pidnode_tail, (char *)&tce6, tce6_size);
 306 
 307                         cph = conn_get_pid_list(connp);
 308 
 309                         /* push the header + conn pid nodes */
 310                         (void) snmp_append_data2(mp6_pidnode_ctl->b_cont,
 311                             &mp6_pidnode_tail,
 312                             (char *)cph, cph->cph_tot_size);
 313 
 314                         kmem_free(cph, cph->cph_tot_size);
 315                         /* end of my  data */
 316 
 317                         mlp.tme_connidx = v6_conn_idx++;
 318                         if (needattr)
 319                                 (void) snmp_append_data2(mp6_attr_ctl->b_cont,
 320                                     &mp6_attr_tail, (char *)&mlp, sizeof (mlp));
 321                         }
 322                         /*
 323                          * Create an IPv4 table entry for IPv4 entries and also
 324                          * for IPv6 entries which are bound to in6addr_any
 325                          * but don't have IPV6_V6ONLY set.
 326                          * (i.e. anything an IPv4 peer could connect to)
 327                          */
 328                         if (connp->conn_ipversion == IPV4_VERSION ||
 329                             (tcp->tcp_state <= TCPS_LISTEN &&
 330                             !connp->conn_ipv6_v6only &&
 331                             IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6))) {
 332                                 if (connp->conn_ipversion == IPV6_VERSION) {
 333                                         tce.tcpConnRemAddress = INADDR_ANY;
 334                                         tce.tcpConnLocalAddress = INADDR_ANY;
 335                                 } else {
 336                                         tce.tcpConnRemAddress =


 364                                             tcp->tcp_rnxt - tcp->tcp_rack;
 365                                         tce.tcpConnEntryInfo.ce_rack = 0;
 366                                 }
 367 
 368                                 tce.tcpConnEntryInfo.ce_swnd = tcp->tcp_swnd;
 369                                 tce.tcpConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
 370                                 tce.tcpConnEntryInfo.ce_rto =  tcp->tcp_rto;
 371                                 tce.tcpConnEntryInfo.ce_mss =  tcp->tcp_mss;
 372                                 tce.tcpConnEntryInfo.ce_state =
 373                                     tcp->tcp_state;
 374 
 375                                 tce.tcpConnCreationProcess =
 376                                     (connp->conn_cpid < 0) ?
 377                                     MIB2_UNKNOWN_PROCESS :
 378                                     connp->conn_cpid;
 379                                 tce.tcpConnCreationTime = connp->conn_open_time;
 380 
 381                                 (void) snmp_append_data2(mp_conn_ctl->b_cont,
 382                                     &mp_conn_tail, (char *)&tce, tce_size);
 383 
 384                                 /* my data */
 385                                 /* push connt_t */
 386                                 (void) snmp_append_data2(mp_pidnode_ctl->b_cont,
 387                                     &mp_pidnode_tail, (char *)&tce, tce_size);
 388 
 389                                 cph = conn_get_pid_list(connp);
 390 
 391                                 /* push the header + conn pid nodes */
 392                                 (void) snmp_append_data2(mp_pidnode_ctl->b_cont,
 393                                         &mp_pidnode_tail, (char *)cph,
 394                                         cph->cph_tot_size);
 395 
 396                                 kmem_free(cph, cph->cph_tot_size);
 397                                 /* end of my code */
 398 
 399                                 mlp.tme_connidx = v4_conn_idx++;
 400                                 if (needattr)
 401                                         (void) snmp_append_data2(
 402                                             mp_attr_ctl->b_cont,
 403                                             &mp_attr_tail, (char *)&mlp,
 404                                             sizeof (mlp));
 405                         }
 406                 }
 407         }
 408 
 409         tcp_sum_mib(tcps, &tcp_mib);
 410 
 411         /* Fixed length structure for IPv4 and IPv6 counters */
 412         SET_MIB(tcp_mib.tcpConnTableSize, tce_size);
 413         SET_MIB(tcp_mib.tcp6ConnTableSize, tce6_size);
 414 
 415         /*
 416          * Synchronize 32- and 64-bit counters.  Note that tcpInSegs and
 417          * tcpOutSegs are not updated anywhere in TCP.  The new 64 bits
 418          * counters are used.  Hence the old counters' values in tcp_sc_mib


 448                 qreply(q, mp_attr_ctl);
 449 
 450         /* table of IPv6 connections... */
 451         optp = (struct opthdr *)&mp6_conn_ctl->b_rptr[
 452             sizeof (struct T_optmgmt_ack)];
 453         optp->level = MIB2_TCP6;
 454         optp->name = MIB2_TCP6_CONN;
 455         optp->len = msgdsize(mp6_conn_ctl->b_cont);
 456         qreply(q, mp6_conn_ctl);
 457 
 458         /* table of IPv6 MLP attributes... */
 459         optp = (struct opthdr *)&mp6_attr_ctl->b_rptr[
 460             sizeof (struct T_optmgmt_ack)];
 461         optp->level = MIB2_TCP6;
 462         optp->name = EXPER_XPORT_MLP;
 463         optp->len = msgdsize(mp6_attr_ctl->b_cont);
 464         if (optp->len == 0)
 465                 freemsg(mp6_attr_ctl);
 466         else
 467                 qreply(q, mp6_attr_ctl);
 468 
 469 
 470         /* table of EXPER_XPORT_PROC_INFO  ipv4 */
 471         optp = (struct opthdr *)&mp_pidnode_ctl->b_rptr[
 472                 sizeof (struct T_optmgmt_ack)];
 473         optp->level = MIB2_TCP;
 474         optp->name = EXPER_XPORT_PROC_INFO;
 475         optp->len = msgdsize(mp_pidnode_ctl->b_cont);
 476         if (optp->len == 0)
 477                 freemsg(mp_pidnode_ctl);
 478         else
 479                 qreply(q, mp_pidnode_ctl);
 480 
 481         /* table of EXPER_XPORT_PROC_INFO  ipv6 */
 482         optp = (struct opthdr *)&mp6_pidnode_ctl->b_rptr[
 483                 sizeof (struct T_optmgmt_ack)];
 484         optp->level = MIB2_TCP6;
 485         optp->name = EXPER_XPORT_PROC_INFO;
 486         optp->len = msgdsize(mp6_pidnode_ctl->b_cont);
 487         if (optp->len == 0)
 488                 freemsg(mp6_pidnode_ctl);
 489         else
 490                 qreply(q, mp6_pidnode_ctl);
 491 
 492         return (mp2ctl);
 493 }
 494 
 495 /* Return 0 if invalid set request, 1 otherwise, including non-tcp requests  */
 496 /* ARGSUSED */
 497 int
 498 tcp_snmp_set(queue_t *q, int level, int name, uchar_t *ptr, int len)
 499 {
 500         mib2_tcpConnEntry_t     *tce = (mib2_tcpConnEntry_t *)ptr;
 501 
 502         switch (level) {
 503         case MIB2_TCP:
 504                 switch (name) {
 505                 case 13:
 506                         if (tce->tcpConnState != MIB2_TCP_deleteTCB)
 507                                 return (0);
 508                         /* TODO: delete entry defined by tce */
 509                         return (1);
 510                 default:
 511                         return (0);