int sigar_os_close(sigar_t *sigar) { kstat_close(sigar->kc); if (sigar->mib2.sd != -1) { close_mib2(&sigar->mib2); } if (sigar->ks.lcpu) { free(sigar->ks.cpu); free(sigar->ks.cpu_info); free(sigar->ks.cpuid); } if (sigar->pinfo) { free(sigar->pinfo); } if (sigar->cpulist.size != 0) { sigar_cpu_list_destroy(sigar, &sigar->cpulist); } if (sigar->plib) { dlclose(sigar->plib); } if (sigar->pargs) { sigar_cache_destroy(sigar->pargs); } free(sigar); return SIGAR_OK; }
int sigar_net_connection_walk(sigar_net_connection_walker_t *walker) { sigar_t *sigar = walker->sigar; int flags = walker->flags; int status; int want_tcp = flags & SIGAR_NETCONN_TCP; int want_udp = flags & SIGAR_NETCONN_UDP; char *data; int len; int rc; struct opthdr *op; while ((rc = get_mib2(&sigar->mib2, &op, &data, &len)) == GET_MIB2_OK) { if ((op->level == MIB2_TCP) && (op->name == MIB2_TCP_13) && want_tcp) { status = tcp_connection_get(walker, (struct mib2_tcpConnEntry *)data, len); } else if ((op->level == MIB2_UDP) && (op->name == MIB2_UDP_5) && want_udp) { status = udp_connection_get(walker, (struct mib2_udpEntry *)data, len); } else { status = SIGAR_OK; } if (status != SIGAR_OK) { break; } } if (rc != GET_MIB2_EOD) { close_mib2(&sigar->mib2); return SIGAR_EMIB2; } return SIGAR_OK; }
int get_mib2(solaris_mib2_t *mib2, struct opthdr **opt, char **data, int *datalen) { struct strbuf d; /* streams data buffer */ int err; /* error code */ int f; /* flags */ int rc; /* reply code */ /* * If MIB2 access isn't open, open it and issue the preliminary stream * messages. */ if (mib2->sd < 0) { /* * Open access. Return on error. */ if ((err = open_mib2(mib2))) { return(err); } /* * Set up message request and option. */ mib2->req = (struct T_optmgmt_req *)mib2->smb; mib2->op = (struct opthdr *)&mib2->smb[sizeof(struct T_optmgmt_req)]; mib2->req->PRIM_type = T_OPTMGMT_REQ; mib2->req->OPT_offset = sizeof(struct T_optmgmt_req); mib2->req->OPT_length = sizeof(struct opthdr); #if defined(MI_T_CURRENT) mib2->req->MGMT_flags = MI_T_CURRENT; #else /* !defined(MI_T_CURRENT) */ # if defined(T_CURRENT) mib2->req->MGMT_flags = T_CURRENT; # else /* !defined(T_CURRENT) */ #error "Neither MI_T_CURRENT nor T_CURRENT are defined." # endif /* defined(T_CURRENT) */ #endif /* defined(MI_T_CURRENT) */ mib2->op->level = MIB2_IP; mib2->op->name = mib2->op->len = 0; mib2->ctlbuf.buf = mib2->smb; mib2->ctlbuf.len = mib2->req->OPT_offset + mib2->req->OPT_length; /* * Put the message. */ if (putmsg(mib2->sd, &mib2->ctlbuf, (struct strbuf *)NULL, 0) == -1) { (void) sprintf(mib2->errmsg, "get_mib2: putmsg request: %s", strerror(errno)); return(GET_MIB2_ERR_PUTMSG); } /* * Set up to process replies. */ mib2->op_ack = (struct T_optmgmt_ack *)mib2->smb; mib2->ctlbuf.maxlen = mib2->smb_len; mib2->err_ack = (struct T_error_ack *)mib2->smb; mib2->op = (struct opthdr *)&mib2->smb[sizeof(struct T_optmgmt_ack)]; } /* * Get the next (first) reply message. */ f = 0; if ((rc = getmsg(mib2->sd, &mib2->ctlbuf, NULL, &f)) < 0) { (void) sprintf(mib2->errmsg, "get_mib2: getmsg(reply): %s", strerror(errno)); return(GET_MIB2_ERR_GETMSGR); } /* * Check for end of data. */ if (rc == 0 && mib2->ctlbuf.len >= sizeof(struct T_optmgmt_ack) && mib2->op_ack->PRIM_type == T_OPTMGMT_ACK && mib2->op_ack->MGMT_flags == T_SUCCESS && mib2->op->len == 0) { err = close_mib2(mib2); if (err) { return(err); } return(GET_MIB2_EOD); } /* * Check for error. */ if (mib2->ctlbuf.len >= sizeof(struct T_error_ack) && mib2->err_ack->PRIM_type == T_ERROR_ACK) { (void) sprintf(mib2->errmsg, "get_mib2: T_ERROR_ACK: len=%d, TLI=%#x, UNIX=%#x", mib2->ctlbuf.len, (int)mib2->err_ack->TLI_error, (int)mib2->err_ack->UNIX_error); return(GET_MIB2_ERR_ACK); } /* * Check for no data. */ if (rc != MOREDATA || mib2->ctlbuf.len < sizeof(struct T_optmgmt_ack) || mib2->op_ack->PRIM_type != T_OPTMGMT_ACK || mib2->op_ack->MGMT_flags != T_SUCCESS) { (void) sprintf(mib2->errmsg, "get_mib2: T_OPTMGMT_ACK: " "rc=%d len=%d type=%#x flags=%#x", rc, mib2->ctlbuf.len, (int)mib2->op_ack->PRIM_type, (int)mib2->op_ack->MGMT_flags); return(GET_MIB2_ERR_NODATA); } /* * Allocate (or enlarge) the data buffer. */ if (mib2->op->len >= mib2->db_len) { mib2->db_len = mib2->op->len; if (mib2->db == NULL) { mib2->db = (char *)malloc(mib2->db_len); } else { mib2->db = (char *)realloc(mib2->db, mib2->db_len); } if (mib2->db == NULL) { (void) sprintf(mib2->errmsg, "get_mib2: no space for %d byte data buffer", mib2->db_len); return(GET_MIB2_ERR_NOSPC); } } /* * Get the data part of the message -- the MIB2 part. */ d.maxlen = mib2->op->len; d.buf = mib2->db; d.len = 0; f = 0; if ((rc = getmsg(mib2->sd, NULL, &d, &f)) < 0) { (void) sprintf(mib2->errmsg, "get_mib2: getmsg(data): %s", strerror(errno)); return(GET_MIB2_ERR_GETMSGD); } if (rc) { (void) sprintf(mib2->errmsg, "get_mib2: getmsg(data): rc=%d maxlen=%d len=%d: %s", rc, d.maxlen, d.len, strerror(errno)); return(GET_MIB2_ERR_GETMSGD); } /* * Compose a successful return. */ *opt = mib2->op; *data = mib2->db; *datalen = d.len; return(GET_MIB2_OK); }