version 1.18, 2020/01/17 09:49:47 |
version 1.19, 2020/01/17 10:03:39 |
|
|
#include <string.h> |
#include <string.h> |
#include <time.h> |
#include <time.h> |
#include <unistd.h> |
#include <unistd.h> |
|
#include <util.h> |
|
|
#include "smi.h" |
#include "smi.h" |
#include "snmp.h" |
#include "snmp.h" |
|
|
int snmpc_walk(int, char *[]); |
int snmpc_walk(int, char *[]); |
int snmpc_set(int, char *[]); |
int snmpc_set(int, char *[]); |
int snmpc_trap(int, char *[]); |
int snmpc_trap(int, char *[]); |
|
int snmpc_df(int, char *[]); |
int snmpc_mibtree(int, char *[]); |
int snmpc_mibtree(int, char *[]); |
struct snmp_agent *snmpc_connect(char *, char *); |
struct snmp_agent *snmpc_connect(char *, char *); |
int snmpc_parseagent(char *, char *); |
int snmpc_parseagent(char *, char *); |
|
|
{ "bulkwalk", 1, "C:", "[-C cipn<nonrep>r<maxrep>] agent [oid]", snmpc_walk }, |
{ "bulkwalk", 1, "C:", "[-C cipn<nonrep>r<maxrep>] agent [oid]", snmpc_walk }, |
{ "set", 1, NULL, "agent oid type value [oid type value] ...", snmpc_set }, |
{ "set", 1, NULL, "agent oid type value [oid type value] ...", snmpc_set }, |
{ "trap", 1, NULL, "agent uptime oid [oid type value] ...", snmpc_trap }, |
{ "trap", 1, NULL, "agent uptime oid [oid type value] ...", snmpc_trap }, |
|
{ "df", 1, "C:", "[-Ch] agent", snmpc_df }, |
{ "mibtree", 0, "O:", "[-O fnS]", snmpc_mibtree } |
{ "mibtree", 0, "O:", "[-O fnS]", snmpc_mibtree } |
}; |
}; |
struct snmp_app *snmp_app = NULL; |
struct snmp_app *snmp_app = NULL; |
|
|
int print_varbind_only = 0; |
int print_varbind_only = 0; |
int print_summary = 0; |
int print_summary = 0; |
int print_time = 0; |
int print_time = 0; |
|
int print_human = 0; |
int walk_check_increase = 1; |
int walk_check_increase = 1; |
int walk_fallback_oid = 1; |
int walk_fallback_oid = 1; |
int walk_include_oid = 0; |
int walk_include_oid = 0; |
|
|
usage(); |
usage(); |
walk_check_increase = 0; |
walk_check_increase = 0; |
break; |
break; |
|
case 'h': |
|
if (strcmp(snmp_app->name, "df")) |
|
usage(); |
|
print_human = 1; |
|
break; |
case 'i': |
case 'i': |
if (strcmp(snmp_app->name, "walk") && |
if (strcmp(snmp_app->name, "walk") && |
strcmp(snmp_app->name, "bulkwalk")) |
strcmp(snmp_app->name, "bulkwalk")) |
|
|
break; |
break; |
case 'r': |
case 'r': |
if (strcmp(snmp_app->name, "bulkget") && |
if (strcmp(snmp_app->name, "bulkget") && |
strcmp(snmp_app->name, "bulkwalk")) |
strcmp(snmp_app->name, "bulkwalk") && |
|
strcmp(snmp_app->name, "df")) |
usage(); |
usage(); |
errno = 0; |
errno = 0; |
max_repetitions = strtol(&optarg[i + 1], |
max_repetitions = strtol(&optarg[i + 1], |
|
|
if (!snmpc_print(varbind)) |
if (!snmpc_print(varbind)) |
err(1, "Can't print response"); |
err(1, "Can't print response"); |
} |
} |
|
sleep(10); |
ober_free_elements(pdu); |
ober_free_elements(pdu); |
snmp_free_agent(agent); |
snmp_free_agent(agent); |
return 0; |
return 0; |
|
|
argv += 3; |
argv += 3; |
|
|
snmp_trap(agent, &ts, &trapoid, snmpc_varbindparse(argc, argv)); |
snmp_trap(agent, &ts, &trapoid, snmpc_varbindparse(argc, argv)); |
|
|
|
return 0; |
|
} |
|
|
|
#define INCR_NEXTTAB(x) ((x + 8) & ~7) |
|
#define NEXTTAB(x) (8 - (x & 7)) |
|
int |
|
snmpc_df(int argc, char *argv[]) |
|
{ |
|
struct snmpc_df { |
|
uint32_t index; |
|
/* DisplayString is 255a DISPLAY-HINT */ |
|
char descr[256]; |
|
/* Theoretical maximum for 2 32 bit values multiplied */ |
|
char size[21]; |
|
char used[21]; |
|
char avail[21]; |
|
char proc[5]; |
|
} *df = NULL; |
|
struct ber_oid descroid = {{ 1, 3, 6, 1, 2, 1, 25, 2, 3, 1, 3 }, 11}; |
|
struct ber_oid unitsoid = {{ 1, 3, 6, 1, 2, 1, 25, 2, 3, 1, 4 }, 11}; |
|
struct ber_oid sizeoid = {{ 1, 3, 6, 1, 2, 1, 25, 2, 3, 1, 5 }, 11}; |
|
struct ber_oid usedoid = {{ 1, 3, 6, 1, 2, 1, 25, 2, 3, 1, 6 }, 11}; |
|
struct ber_oid oid, *reqoid; |
|
struct ber_element *pdu, *varbind; |
|
struct snmp_agent *agent; |
|
int errorstatus, errorindex; |
|
int class; |
|
size_t i, j, rows = 0; |
|
unsigned type; |
|
char *string; |
|
int descrlen = 0, sizelen = 0, usedlen = 0, availlen = 0, proclen = 0; |
|
int len; |
|
long long units, size, used; |
|
int fmtret; |
|
|
|
if (argc != 1) |
|
usage(); |
|
|
|
if ((agent = snmpc_connect(argv[0], "161")) == NULL) |
|
err(1, "%s", snmp_app->name); |
|
agent->timeout = timeout; |
|
agent->retries = retries; |
|
|
|
if (pledge("stdio", NULL) == -1) |
|
err(1, "pledge"); |
|
|
|
descrlen = sizeof("Description") - 1; |
|
sizelen = sizeof("Size") - 1; |
|
usedlen = sizeof("Used") - 1; |
|
availlen = sizeof("Available") - 1; |
|
proclen = sizeof("Used%") - 1; |
|
|
|
bcopy(&descroid, &oid, sizeof(descroid)); |
|
|
|
i = 0; |
|
while(1) { |
|
if (version < SNMP_V2C) { |
|
if ((pdu = snmp_getnext(agent, &oid, 1)) == NULL) |
|
err(1, "df"); |
|
} else { |
|
if ((pdu = snmp_getbulk(agent, &oid, 1, 0, |
|
max_repetitions)) == NULL) |
|
err(1, "df"); |
|
} |
|
|
|
(void) ober_scanf_elements(pdu, "t{Sdd{e", &class, &type, |
|
&errorstatus, &errorindex, &varbind); |
|
if (errorstatus != 0) |
|
snmpc_printerror((enum snmp_error) errorstatus, varbind, |
|
errorindex, NULL); |
|
|
|
if (class == BER_CLASS_CONTEXT && type == SNMP_C_REPORT) { |
|
printf("Received report:\n"); |
|
for (; varbind != NULL; varbind = varbind->be_next) { |
|
if (!snmpc_print(varbind)) |
|
err(1, "Can't print response"); |
|
} |
|
return 1; |
|
} |
|
for (; varbind != NULL; varbind = varbind->be_next) { |
|
(void) ober_scanf_elements(varbind, "{oS", &oid); |
|
if (ober_oid_cmp(&descroid, &oid) != 2) |
|
break; |
|
rows++; |
|
} |
|
if ((df = reallocarray(df, rows, sizeof(*df))) == NULL) |
|
err(1, "malloc"); |
|
(void) ober_scanf_elements(pdu, "{SSS{e", &varbind); |
|
for (; i < rows; varbind = varbind->be_next, i++) { |
|
if (ober_scanf_elements(varbind, "{os", &oid, |
|
&string) == -1) { |
|
i--; |
|
rows--; |
|
continue; |
|
} |
|
df[i].index = oid.bo_id[oid.bo_n - 1]; |
|
len = strlcpy(df[i].descr, string, |
|
sizeof(df[i].descr)); |
|
if (len > (int) sizeof(df[i].descr)) |
|
len = (int) sizeof(df[i].descr) - 1; |
|
if (len > descrlen) |
|
descrlen = len; |
|
} |
|
ober_free_elements(pdu); |
|
if (varbind != NULL) |
|
break; |
|
} |
|
|
|
if (max_repetitions < 3) |
|
max_repetitions = 3; |
|
if ((reqoid = reallocarray(NULL, max_repetitions, sizeof(*reqoid))) == NULL) |
|
err(1, "malloc"); |
|
for (i = 0; i < rows;) { |
|
for (j = 0; i + j < rows && j < (size_t)max_repetitions / 3; |
|
j++) { |
|
bcopy(&unitsoid, &(reqoid[(j * 3) + 0]), |
|
sizeof(unitsoid)); |
|
reqoid[(j * 3) + 0].bo_id[ |
|
reqoid[(j * 3) + 0].bo_n++] = df[i + j].index; |
|
bcopy(&sizeoid, &(reqoid[(j * 3) + 1]), |
|
sizeof(sizeoid)); |
|
reqoid[(j * 3) + 1].bo_id[ |
|
reqoid[(j * 3) + 1].bo_n++] = df[i + j].index; |
|
bcopy(&usedoid, &(reqoid[(j * 3) + 2]), |
|
sizeof(usedoid)); |
|
reqoid[(j * 3) + 2].bo_id[ |
|
reqoid[(j * 3) + 2].bo_n++] = df[i + j].index; |
|
} |
|
if ((pdu = snmp_get(agent, reqoid, j * 3)) == NULL) |
|
err(1, "df"); |
|
(void) ober_scanf_elements(pdu, "t{Sdd{e", &class, &type, |
|
&errorstatus, &errorindex, &varbind); |
|
if (errorstatus != 0) |
|
snmpc_printerror((enum snmp_error) errorstatus, varbind, |
|
errorindex, NULL); |
|
if (class == BER_CLASS_CONTEXT && type == SNMP_C_REPORT) { |
|
printf("Received report:\n"); |
|
for (; varbind != NULL; varbind = varbind->be_next) { |
|
if (!snmpc_print(varbind)) |
|
err(1, "Can't print response"); |
|
} |
|
} |
|
for (j = 0; varbind != NULL; i++) { |
|
if (ober_scanf_elements(varbind, "{oi}{oi}{oi}", |
|
&(reqoid[0]), &units, &(reqoid[1]), &size, |
|
&(reqoid[2]), &used, &varbind) == -1) { |
|
break; |
|
} |
|
varbind = varbind->be_next->be_next->be_next; |
|
|
|
unitsoid.bo_id[unitsoid.bo_n++] = df[i].index; |
|
if (ober_oid_cmp(&unitsoid, &(reqoid[0])) != 0) { |
|
warnx("df: received invalid object"); |
|
break; |
|
} |
|
unitsoid.bo_n--; |
|
sizeoid.bo_id[sizeoid.bo_n++] = df[i].index; |
|
if (ober_oid_cmp(&sizeoid, &(reqoid[1])) != 0) { |
|
warnx("df: received invalid object"); |
|
break; |
|
} |
|
sizeoid.bo_n--; |
|
usedoid.bo_id[usedoid.bo_n++] = df[i].index; |
|
if (ober_oid_cmp(&usedoid, &(reqoid[2])) != 0) { |
|
warnx("df: received invalid object"); |
|
break; |
|
} |
|
usedoid.bo_n--; |
|
if (print_human) |
|
fmtret = fmt_scaled((units * size), df[i].size); |
|
if (!print_human || fmtret == -1) |
|
snprintf(df[i].size, sizeof(df[i].size), "%lld", |
|
(units * size) / 1024); |
|
len = (int) strlen(df[i].size); |
|
if (len > sizelen) |
|
sizelen = len; |
|
if (print_human) |
|
fmtret = fmt_scaled(units * used, df[i].used); |
|
if (!print_human || fmtret == -1) |
|
snprintf(df[i].used, sizeof(df[i].used), "%lld", |
|
(units * used) / 1024); |
|
len = (int) strlen(df[i].used); |
|
if (len > usedlen) |
|
usedlen = len; |
|
if (print_human) |
|
fmtret = fmt_scaled(units * (size - used), |
|
df[i].avail); |
|
if (!print_human || fmtret == -1) |
|
snprintf(df[i].avail, sizeof(df[i].avail), |
|
"%lld", (units * (size - used)) / 1024); |
|
len = (int) strlen(df[i].avail); |
|
if (len > usedlen) |
|
availlen = len; |
|
if (size == 0) |
|
strlcpy(df[i].proc, "0%", sizeof(df[i].proc)); |
|
else { |
|
snprintf(df[i].proc, sizeof(df[i].proc), |
|
"%lld%%", (used * 100) / size); |
|
} |
|
len = (int) strlen(df[i].proc); |
|
if (len > proclen) |
|
proclen = len; |
|
j++; |
|
} |
|
if (j == 0) { |
|
warnx("Failed to retrieve information for %s", |
|
df[i].descr); |
|
memmove(df + i, df + i + 1, |
|
(rows - i - 1) * sizeof(*df)); |
|
rows--; |
|
i--; |
|
} |
|
} |
|
|
|
printf("%-*s%*s%*s%*s%*s\n", |
|
descrlen, "Description", |
|
NEXTTAB(descrlen) + sizelen, "Size", |
|
NEXTTAB(sizelen) + usedlen, "Used", |
|
NEXTTAB(usedlen) + availlen, "Available", |
|
NEXTTAB(availlen) + proclen, "Used%"); |
|
for (i = 0; i < rows; i++) { |
|
printf("%-*s%*s%*s%*s%*s\n", |
|
descrlen, df[i].descr, |
|
NEXTTAB(descrlen) + sizelen, df[i].size, |
|
NEXTTAB(sizelen) + usedlen, df[i].used, |
|
NEXTTAB(usedlen) + availlen, df[i].avail, |
|
NEXTTAB(availlen) + proclen, df[i].proc); |
|
} |
|
|
return 0; |
return 0; |
} |
} |