--- /dev/null
+--- net-snmp-5.4.2.1/apps/snmpnetstat/inet.c 2006-04-21 15:30:47.000000000 +0300
++++ /home/glen/inet.c 2009-01-22 17:39:57.754383000 +0200
+@@ -110,8 +110,10 @@
+ tcpprotopr(const char *name)
+ {
+ netsnmp_variable_list *var, *vp;
+- oid tcpConnState_oid[] = { 1,3,6,1,2,1,6,13,1,1 };
+- size_t tcpConnState_len = OID_LENGTH( tcpConnState_oid );
++ netsnmp_pdu *pdu, *response;
++ oid tcpConnState_mib[] = { 1,3,6,1,2,1,6,13,1,1 };
++ oid tcpConnState_oid[MAX_OID_LEN];
++ size_t tcpConnState_len;
+ int state, width;
+ union {
+ struct in_addr addr;
+@@ -121,61 +123,126 @@
+ struct in_addr localAddr, remoteAddr;
+ char *cp;
+ int first = 1;
++ int running = 1;
++ int status;
++
++
++ /*
++ * setup initial object name
++ */
++ memmove(tcpConnState_oid, tcpConnState_mib, sizeof(tcpConnState_mib));
++ tcpConnState_len = sizeof(tcpConnState_mib) / sizeof(oid);
+
+ /*
+ * Walking the tcpConnState column will provide all
+ * the necessary information.
+ */
+- var = NULL;
+- snmp_varlist_add_variable( &var, tcpConnState_oid, tcpConnState_len,
+- ASN_NULL, NULL, 0);
+- if (!var)
+- return;
+- if (netsnmp_query_walk( var, ss ) != SNMP_ERR_NOERROR)
+- return;
+-
+- for (vp = var; vp ; vp=vp->next_variable) {
+- state = *vp->val.integer;
+- if (!aflag && state == MIB_TCPCONNSTATE_LISTEN)
+- continue;
++ while (running) {
++ /*
++ * create PDU for GETBULK request and add object name to request
++ */
++ pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
++ pdu->non_repeaters = 0;
++ pdu->max_repetitions = 1024; /* fill the packet */
++ snmp_add_null_var(pdu, tcpConnState_oid, tcpConnState_len);
+
+- if (first) {
+- printf("Active Internet (%s) Connections", name);
+- if (aflag)
+- printf(" (including servers)");
+- putchar('\n');
+- width = Aflag ? 18 : 22;
+- printf("%-5.5s %*.*s %*.*s %s\n",
+- "Proto", -width, width, "Local Address",
+- -width, width, "Remote Address", "(state)");
+- first=0;
++ /*
++ * do the request
++ */
++ status = snmp_synch_response(ss, pdu, &response);
++ if (status == STAT_SUCCESS) {
++ if (response->errstat == SNMP_ERR_NOERROR) {
++ for (vp = response->variables; vp ; vp=vp->next_variable) {
++
++ if ((vp->name_length < sizeof(tcpConnState_mib) / sizeof(oid)) ||
++ (memcmp(tcpConnState_mib, vp->name, sizeof(tcpConnState_mib)) != 0)) {
++ /*
++ * not part of this subtree
++ */
++ running = 0;
++ continue;
++ }
++
++ state = *vp->val.integer;
++ if (!aflag && state == MIB_TCPCONNSTATE_LISTEN) {
++ continue;
++ }
++
++ if (first) {
++ printf("Active Internet (%s) Connections", name);
++ if (aflag)
++ printf(" (including servers)");
++ putchar('\n');
++ width = Aflag ? 18 : 22;
++ printf("%-5.5s %*.*s %*.*s %s\n",
++ "Proto", -width, width, "Local Address",
++ -width, width, "Remote Address", "(state)");
++ first = 0;
++ }
++
++ /* Extract the local/remote information from the index values */
++ cp = tmpAddr.data;
++ cp[0] = vp->name[ 10 ] & 0xff;
++ cp[1] = vp->name[ 11 ] & 0xff;
++ cp[2] = vp->name[ 12 ] & 0xff;
++ cp[3] = vp->name[ 13 ] & 0xff;
++ localAddr.s_addr = tmpAddr.addr.s_addr;
++ localPort = ntohs(vp->name[ 14 ]);
++ cp = tmpAddr.data;
++ cp[0] = vp->name[ 15 ] & 0xff;
++ cp[1] = vp->name[ 16 ] & 0xff;
++ cp[2] = vp->name[ 17 ] & 0xff;
++ cp[3] = vp->name[ 18 ] & 0xff;
++ remoteAddr.s_addr = tmpAddr.addr.s_addr;
++ remotePort = ntohs(vp->name[ 19 ]);
++
++ printf("%-5.5s", name);
++ inetprint(&localAddr, localPort, name, 1);
++ inetprint(&remoteAddr, remotePort, name, 0);
++ if (state < 1 || state > TCP_NSTATES) {
++ printf("%d\n", state );
++ } else {
++ printf("%s\n", tcpstates[state]);
++ }
++
++ if ((vp->type != SNMP_ENDOFMIBVIEW) &&
++ (vp->type != SNMP_NOSUCHOBJECT) &&
++ (vp->type != SNMP_NOSUCHINSTANCE)) {
++ /*
++ * Check if last variable, and if so, save for next request.
++ */
++ if (vp->next_variable == NULL) {
++// printf("old: "); fprint_objid(stdout, tcpConnState_oid, tcpConnState_len);
++
++ memmove(tcpConnState_oid, vp->name,
++ vp->name_length * sizeof(oid));
++ tcpConnState_len = vp->name_length;
++
++// printf("new: "); fprint_objid(stdout, tcpConnState_oid, tcpConnState_len);
++ }
++ } else {
++ /*
++ * an exception value, so stop
++ */
++ running = 0;
++ }
++ }
++ } else {
++ /*
++ * error in response, print it
++ */
++ running = 0;
++ }
++ } else if (status == STAT_TIMEOUT) {
++ running = 0;
++ } else { /* status == STAT_ERROR */
++ running = 0;
+ }
+-
+- /* Extract the local/remote information from the index values */
+- cp = tmpAddr.data;
+- cp[0] = vp->name[ 10 ] & 0xff;
+- cp[1] = vp->name[ 11 ] & 0xff;
+- cp[2] = vp->name[ 12 ] & 0xff;
+- cp[3] = vp->name[ 13 ] & 0xff;
+- localAddr.s_addr = tmpAddr.addr.s_addr;
+- localPort = ntohs(vp->name[ 14 ]);
+- cp = tmpAddr.data;
+- cp[0] = vp->name[ 15 ] & 0xff;
+- cp[1] = vp->name[ 16 ] & 0xff;
+- cp[2] = vp->name[ 17 ] & 0xff;
+- cp[3] = vp->name[ 18 ] & 0xff;
+- remoteAddr.s_addr = tmpAddr.addr.s_addr;
+- remotePort = ntohs(vp->name[ 19 ]);
+
+- printf("%-5.5s", name);
+- inetprint(&localAddr, localPort, name, 1);
+- inetprint(&remoteAddr, remotePort, name, 0);
+- if ( state < 1 || state > TCP_NSTATES )
+- printf("%d\n", state );
+- else
+- printf("%s\n", tcpstates[ state ]);
+- }
+- snmp_free_varbind( var );
++ if (response) {
++ snmp_free_pdu(response);
++ }
++ }
+ }
+
+ /*