parent
df4b043f08
commit
acd1e437be
15
misc/arpd.c
15
misc/arpd.c
|
|
@ -47,8 +47,7 @@ int ifnum;
|
||||||
int *ifvec;
|
int *ifvec;
|
||||||
char **ifnames;
|
char **ifnames;
|
||||||
|
|
||||||
struct dbkey
|
struct dbkey {
|
||||||
{
|
|
||||||
__u32 iface;
|
__u32 iface;
|
||||||
__u32 addr;
|
__u32 addr;
|
||||||
};
|
};
|
||||||
|
|
@ -96,8 +95,7 @@ int poll_timeout = 30000;
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: arpd [ -lkh? ] [ -a N ] [ -b dbase ] [ -B number ]"
|
"Usage: arpd [ -lkh? ] [ -a N ] [ -b dbase ] [ -B number ] [ -f file ] [ -n time ] [-p interval ] [ -R rate ] [ interfaces ]\n");
|
||||||
" [ -f file ] [ -n time ] [-p interval ] [ -R rate ] [ interfaces ]\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,6 +246,7 @@ static int queue_active_probe(int ifindex, __u32 addr)
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
if (prev.tv_sec) {
|
if (prev.tv_sec) {
|
||||||
int diff = (now.tv_sec-prev.tv_sec)*1000+(now.tv_usec-prev.tv_usec)/1000;
|
int diff = (now.tv_sec-prev.tv_sec)*1000+(now.tv_usec-prev.tv_usec)/1000;
|
||||||
|
|
||||||
buckets += diff;
|
buckets += diff;
|
||||||
} else {
|
} else {
|
||||||
buckets = broadcast_burst;
|
buckets = broadcast_burst;
|
||||||
|
|
@ -405,6 +404,7 @@ static int do_one_request(struct nlmsghdr *n)
|
||||||
!IS_NEG(dbdat.data) ||
|
!IS_NEG(dbdat.data) ||
|
||||||
!NEG_VALID(dbdat.data)) {
|
!NEG_VALID(dbdat.data)) {
|
||||||
__u8 ndata[6];
|
__u8 ndata[6];
|
||||||
|
|
||||||
stats.kern_neg++;
|
stats.kern_neg++;
|
||||||
prepare_neg_entry(ndata, time(NULL));
|
prepare_neg_entry(ndata, time(NULL));
|
||||||
dbdat.data = ndata;
|
dbdat.data = ndata;
|
||||||
|
|
@ -669,12 +669,13 @@ int main(int argc, char **argv)
|
||||||
if (ifnum) {
|
if (ifnum) {
|
||||||
int i;
|
int i;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
for (i = 0; i < ifnum; i++) {
|
for (i = 0; i < ifnum; i++) {
|
||||||
strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ);
|
strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ);
|
||||||
if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) {
|
if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) {
|
||||||
perror("ioctl(SIOCGIFINDEX)");
|
perror("ioctl(SIOCGIFINDEX)");
|
||||||
exit(-1);;
|
exit(-1);
|
||||||
}
|
}
|
||||||
ifvec[i] = ifr.ifr_ifindex;
|
ifvec[i] = ifr.ifr_ifindex;
|
||||||
}
|
}
|
||||||
|
|
@ -738,12 +739,15 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (do_list) {
|
if (do_list) {
|
||||||
DBT dbkey, dbdat;
|
DBT dbkey, dbdat;
|
||||||
|
|
||||||
printf("%-8s %-15s %s\n", "#Ifindex", "IP", "MAC");
|
printf("%-8s %-15s %s\n", "#Ifindex", "IP", "MAC");
|
||||||
while (dbase->seq(dbase, &dbkey, &dbdat, R_NEXT) == 0) {
|
while (dbase->seq(dbase, &dbkey, &dbdat, R_NEXT) == 0) {
|
||||||
struct dbkey *key = dbkey.data;
|
struct dbkey *key = dbkey.data;
|
||||||
|
|
||||||
if (handle_if(key->iface)) {
|
if (handle_if(key->iface)) {
|
||||||
if (!IS_NEG(dbdat.data)) {
|
if (!IS_NEG(dbdat.data)) {
|
||||||
char b1[18];
|
char b1[18];
|
||||||
|
|
||||||
printf("%-8d %-15s %s\n",
|
printf("%-8d %-15s %s\n",
|
||||||
key->iface,
|
key->iface,
|
||||||
inet_ntoa(*(struct in_addr *)&key->addr),
|
inet_ntoa(*(struct in_addr *)&key->addr),
|
||||||
|
|
@ -769,6 +773,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (1) {
|
if (1) {
|
||||||
struct sockaddr_ll sll;
|
struct sockaddr_ll sll;
|
||||||
|
|
||||||
memset(&sll, 0, sizeof(sll));
|
memset(&sll, 0, sizeof(sll));
|
||||||
sll.sll_family = AF_PACKET;
|
sll.sll_family = AF_PACKET;
|
||||||
sll.sll_protocol = htons(ETH_P_ARP);
|
sll.sll_protocol = htons(ETH_P_ARP);
|
||||||
|
|
|
||||||
|
|
@ -35,15 +35,15 @@
|
||||||
|
|
||||||
#include <SNAPSHOT.h>
|
#include <SNAPSHOT.h>
|
||||||
|
|
||||||
int dump_zeros = 0;
|
int dump_zeros;
|
||||||
int reset_history = 0;
|
int reset_history;
|
||||||
int ignore_history = 0;
|
int ignore_history;
|
||||||
int no_output = 0;
|
int no_output;
|
||||||
int json_output = 0;
|
int json_output;
|
||||||
int no_update = 0;
|
int no_update;
|
||||||
int scan_interval = 0;
|
int scan_interval;
|
||||||
int time_constant = 0;
|
int time_constant;
|
||||||
int show_errors = 0;
|
int show_errors;
|
||||||
int pretty;
|
int pretty;
|
||||||
double W;
|
double W;
|
||||||
char **patterns;
|
char **patterns;
|
||||||
|
|
@ -54,8 +54,7 @@ int source_mismatch;
|
||||||
|
|
||||||
#define MAXS (sizeof(struct rtnl_link_stats)/sizeof(__u32))
|
#define MAXS (sizeof(struct rtnl_link_stats)/sizeof(__u32))
|
||||||
|
|
||||||
struct ifstat_ent
|
struct ifstat_ent {
|
||||||
{
|
|
||||||
struct ifstat_ent *next;
|
struct ifstat_ent *next;
|
||||||
char *name;
|
char *name;
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
|
@ -210,7 +209,8 @@ static void load_raw_table(FILE *fp)
|
||||||
p = next;
|
p = next;
|
||||||
|
|
||||||
for (i = 0; i < MAXS; i++) {
|
for (i = 0; i < MAXS; i++) {
|
||||||
unsigned rate;
|
unsigned int rate;
|
||||||
|
|
||||||
if (!(next = strchr(p, ' ')))
|
if (!(next = strchr(p, ' ')))
|
||||||
abort();
|
abort();
|
||||||
*next++ = 0;
|
*next++ = 0;
|
||||||
|
|
@ -255,8 +255,10 @@ static void dump_raw_db(FILE *fp, int to_hist)
|
||||||
int i;
|
int i;
|
||||||
unsigned long long *vals = n->val;
|
unsigned long long *vals = n->val;
|
||||||
double *rates = n->rate;
|
double *rates = n->rate;
|
||||||
|
|
||||||
if (!match(n->name)) {
|
if (!match(n->name)) {
|
||||||
struct ifstat_ent *h1;
|
struct ifstat_ent *h1;
|
||||||
|
|
||||||
if (!to_hist)
|
if (!to_hist)
|
||||||
continue;
|
continue;
|
||||||
for (h1 = h; h1; h1 = h1->next) {
|
for (h1 = h; h1; h1 = h1->next) {
|
||||||
|
|
@ -280,7 +282,7 @@ static void dump_raw_db(FILE *fp, int to_hist)
|
||||||
fprintf(fp, "%d %s ", n->ifindex, n->name);
|
fprintf(fp, "%d %s ", n->ifindex, n->name);
|
||||||
for (i = 0; i < MAXS; i++)
|
for (i = 0; i < MAXS; i++)
|
||||||
fprintf(fp, "%llu %u ", vals[i],
|
fprintf(fp, "%llu %u ", vals[i],
|
||||||
(unsigned)rates[i]);
|
(unsigned int)rates[i]);
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -308,18 +310,19 @@ static void format_rate(FILE *fp, const unsigned long long *vals,
|
||||||
fprintf(fp, "%8llu ", vals[i]);
|
fprintf(fp, "%8llu ", vals[i]);
|
||||||
|
|
||||||
if (rates[i] > mega) {
|
if (rates[i] > mega) {
|
||||||
sprintf(temp, "%uM", (unsigned)(rates[i]/mega));
|
sprintf(temp, "%uM", (unsigned int)(rates[i]/mega));
|
||||||
fprintf(fp, "%-6s ", temp);
|
fprintf(fp, "%-6s ", temp);
|
||||||
} else if (rates[i] > kilo) {
|
} else if (rates[i] > kilo) {
|
||||||
sprintf(temp, "%uK", (unsigned)(rates[i]/kilo));
|
sprintf(temp, "%uK", (unsigned int)(rates[i]/kilo));
|
||||||
fprintf(fp, "%-6s ", temp);
|
fprintf(fp, "%-6s ", temp);
|
||||||
} else
|
} else
|
||||||
fprintf(fp, "%-6u ", (unsigned)rates[i]);
|
fprintf(fp, "%-6u ", (unsigned int)rates[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void format_pair(FILE *fp, const unsigned long long *vals, int i, int k)
|
static void format_pair(FILE *fp, const unsigned long long *vals, int i, int k)
|
||||||
{
|
{
|
||||||
char temp[64];
|
char temp[64];
|
||||||
|
|
||||||
if (vals[i] > giga)
|
if (vals[i] > giga)
|
||||||
fprintf(fp, "%7lluM ", vals[i]/mega);
|
fprintf(fp, "%7lluM ", vals[i]/mega);
|
||||||
else if (vals[i] > mega)
|
else if (vals[i] > mega)
|
||||||
|
|
@ -328,13 +331,13 @@ static void format_pair(FILE *fp, const unsigned long long *vals, int i, int k)
|
||||||
fprintf(fp, "%8llu ", vals[i]);
|
fprintf(fp, "%8llu ", vals[i]);
|
||||||
|
|
||||||
if (vals[k] > giga) {
|
if (vals[k] > giga) {
|
||||||
sprintf(temp, "%uM", (unsigned)(vals[k]/mega));
|
sprintf(temp, "%uM", (unsigned int)(vals[k]/mega));
|
||||||
fprintf(fp, "%-6s ", temp);
|
fprintf(fp, "%-6s ", temp);
|
||||||
} else if (vals[k] > mega) {
|
} else if (vals[k] > mega) {
|
||||||
sprintf(temp, "%uK", (unsigned)(vals[k]/kilo));
|
sprintf(temp, "%uK", (unsigned int)(vals[k]/kilo));
|
||||||
fprintf(fp, "%-6s ", temp);
|
fprintf(fp, "%-6s ", temp);
|
||||||
} else
|
} else
|
||||||
fprintf(fp, "%-6u ", (unsigned)vals[k]);
|
fprintf(fp, "%-6u ", (unsigned int)vals[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_head(FILE *fp)
|
static void print_head(FILE *fp)
|
||||||
|
|
@ -530,9 +533,11 @@ static void update_db(int interval)
|
||||||
|
|
||||||
for (n = kern_db; n; n = n->next) {
|
for (n = kern_db; n; n = n->next) {
|
||||||
struct ifstat_ent *h1;
|
struct ifstat_ent *h1;
|
||||||
|
|
||||||
for (h1 = h; h1; h1 = h1->next) {
|
for (h1 = h; h1; h1 = h1->next) {
|
||||||
if (h1->ifindex == n->ifindex) {
|
if (h1->ifindex == n->ifindex) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAXS; i++) {
|
for (i = 0; i < MAXS; i++) {
|
||||||
if ((long)(h1->ival[i] - n->ival[i]) < 0) {
|
if ((long)(h1->ival[i] - n->ival[i]) < 0) {
|
||||||
memset(n->ival, 0, sizeof(n->ival));
|
memset(n->ival, 0, sizeof(n->ival));
|
||||||
|
|
@ -542,6 +547,7 @@ static void update_db(int interval)
|
||||||
for (i = 0; i < MAXS; i++) {
|
for (i = 0; i < MAXS; i++) {
|
||||||
double sample;
|
double sample;
|
||||||
unsigned long incr = h1->ival[i] - n->ival[i];
|
unsigned long incr = h1->ival[i] - n->ival[i];
|
||||||
|
|
||||||
n->val[i] += incr;
|
n->val[i] += incr;
|
||||||
n->ival[i] = h1->ival[i];
|
n->ival[i] = h1->ival[i];
|
||||||
sample = (double)(incr*1000)/interval;
|
sample = (double)(incr*1000)/interval;
|
||||||
|
|
@ -552,6 +558,7 @@ static void update_db(int interval)
|
||||||
n->rate[i] = sample;
|
n->rate[i] = sample;
|
||||||
} else {
|
} else {
|
||||||
double w = W*(double)interval/scan_interval;
|
double w = W*(double)interval/scan_interval;
|
||||||
|
|
||||||
n->rate[i] += w*(sample-n->rate[i]);
|
n->rate[i] += w*(sample-n->rate[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -559,6 +566,7 @@ static void update_db(int interval)
|
||||||
|
|
||||||
while (h != h1) {
|
while (h != h1) {
|
||||||
struct ifstat_ent *tmp = h;
|
struct ifstat_ent *tmp = h;
|
||||||
|
|
||||||
h = h->next;
|
h = h->next;
|
||||||
free(tmp->name);
|
free(tmp->name);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|
@ -579,6 +587,7 @@ static void server_loop(int fd)
|
||||||
{
|
{
|
||||||
struct timeval snaptime = { 0 };
|
struct timeval snaptime = { 0 };
|
||||||
struct pollfd p;
|
struct pollfd p;
|
||||||
|
|
||||||
p.fd = fd;
|
p.fd = fd;
|
||||||
p.events = p.revents = POLLIN;
|
p.events = p.revents = POLLIN;
|
||||||
|
|
||||||
|
|
@ -603,8 +612,10 @@ static void server_loop(int fd)
|
||||||
if (poll(&p, 1, scan_interval - tdiff) > 0
|
if (poll(&p, 1, scan_interval - tdiff) > 0
|
||||||
&& (p.revents&POLLIN)) {
|
&& (p.revents&POLLIN)) {
|
||||||
int clnt = accept(fd, NULL, NULL);
|
int clnt = accept(fd, NULL, NULL);
|
||||||
|
|
||||||
if (clnt >= 0) {
|
if (clnt >= 0) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
if (children >= 5) {
|
if (children >= 5) {
|
||||||
close(clnt);
|
close(clnt);
|
||||||
} else if ((pid = fork()) != 0) {
|
} else if ((pid = fork()) != 0) {
|
||||||
|
|
@ -613,6 +624,7 @@ static void server_loop(int fd)
|
||||||
close(clnt);
|
close(clnt);
|
||||||
} else {
|
} else {
|
||||||
FILE *fp = fdopen(clnt, "w");
|
FILE *fp = fdopen(clnt, "w");
|
||||||
|
|
||||||
if (fp)
|
if (fp)
|
||||||
dump_raw_db(fp, 0);
|
dump_raw_db(fp, 0);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
@ -809,6 +821,7 @@ int main(int argc, char *argv[])
|
||||||
if (!ignore_history) {
|
if (!ignore_history) {
|
||||||
FILE *tfp;
|
FILE *tfp;
|
||||||
long uptime = -1;
|
long uptime = -1;
|
||||||
|
|
||||||
if ((tfp = fopen("/proc/uptime", "r")) != NULL) {
|
if ((tfp = fopen("/proc/uptime", "r")) != NULL) {
|
||||||
if (fscanf(tfp, "%ld", &uptime) != 1)
|
if (fscanf(tfp, "%ld", &uptime) != 1)
|
||||||
uptime = -1;
|
uptime = -1;
|
||||||
|
|
@ -833,6 +846,7 @@ int main(int argc, char *argv[])
|
||||||
connect(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) == 0))
|
connect(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) == 0))
|
||||||
&& verify_forging(fd) == 0) {
|
&& verify_forging(fd) == 0) {
|
||||||
FILE *sfp = fdopen(fd, "r");
|
FILE *sfp = fdopen(fd, "r");
|
||||||
|
|
||||||
load_raw_table(sfp);
|
load_raw_table(sfp);
|
||||||
if (hist_db && source_mismatch) {
|
if (hist_db && source_mismatch) {
|
||||||
fprintf(stderr, "ifstat: history is stale, ignoring it.\n");
|
fprintf(stderr, "ifstat: history is stale, ignoring it.\n");
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,8 @@ static struct option opts[] = {
|
||||||
static int usage(char *name, int exit_code)
|
static int usage(char *name, int exit_code)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s Version %s\n", name, LNSTAT_VERSION);
|
fprintf(stderr, "%s Version %s\n", name, LNSTAT_VERSION);
|
||||||
fprintf(stderr, "Copyright (C) 2004 by Harald Welte "
|
fprintf(stderr, "Copyright (C) 2004 by Harald Welte <laforge@gnumonks.org>\n");
|
||||||
"<laforge@gnumonks.org>\n");
|
fprintf(stderr, "This program is free software licensed under GNU GPLv2\nwith ABSOLUTELY NO WARRANTY.\n\n");
|
||||||
fprintf(stderr, "This program is free software licensed under GNU GPLv2"
|
|
||||||
"\nwith ABSOLUTELY NO WARRANTY.\n\n");
|
|
||||||
fprintf(stderr, "Parameters:\n");
|
fprintf(stderr, "Parameters:\n");
|
||||||
fprintf(stderr, "\t-V --version\t\tPrint Version of Program\n");
|
fprintf(stderr, "\t-V --version\t\tPrint Version of Program\n");
|
||||||
fprintf(stderr, "\t-c --count <count>\t"
|
fprintf(stderr, "\t-c --count <count>\t"
|
||||||
|
|
@ -145,8 +143,7 @@ static int map_field_params(struct lnstat_file *lnstat_files,
|
||||||
|
|
||||||
if (++j >= MAX_FIELDS - 1) {
|
if (++j >= MAX_FIELDS - 1) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"WARN: MAX_FIELDS (%d) reached,"
|
"WARN: MAX_FIELDS (%d) reached, truncating number of keys\n",
|
||||||
" truncating number of keys\n",
|
|
||||||
MAX_FIELDS);
|
MAX_FIELDS);
|
||||||
goto full;
|
goto full;
|
||||||
}
|
}
|
||||||
|
|
@ -303,8 +300,7 @@ int main(int argc, char **argv)
|
||||||
tok = strtok(NULL, ",")) {
|
tok = strtok(NULL, ",")) {
|
||||||
if (fp.num >= MAX_FIELDS) {
|
if (fp.num >= MAX_FIELDS) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"WARN: too many keys"
|
"WARN: too many keys requested: (%d max)\n",
|
||||||
" requested: (%d max)\n",
|
|
||||||
MAX_FIELDS);
|
MAX_FIELDS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ static int scan_lines(struct lnstat_file *lf, int i)
|
||||||
|
|
||||||
for (j = 0; j < lf->num_fields; j++) {
|
for (j = 0; j < lf->num_fields; j++) {
|
||||||
unsigned long f = strtoul(ptr, &ptr, 16);
|
unsigned long f = strtoul(ptr, &ptr, 16);
|
||||||
|
|
||||||
if (j == 0)
|
if (j == 0)
|
||||||
lf->fields[j].values[i] = f;
|
lf->fields[j].values[i] = f;
|
||||||
else
|
else
|
||||||
|
|
@ -158,6 +159,7 @@ static int lnstat_scan_compat_rtstat_fields(struct lnstat_file *lf)
|
||||||
static int name_in_array(const int num, const char **arr, const char *name)
|
static int name_in_array(const int num, const char **arr, const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
if (!strcmp(arr[i], name))
|
if (!strcmp(arr[i], name))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
41
misc/nstat.c
41
misc/nstat.c
|
|
@ -31,15 +31,15 @@
|
||||||
#include <json_writer.h>
|
#include <json_writer.h>
|
||||||
#include <SNAPSHOT.h>
|
#include <SNAPSHOT.h>
|
||||||
|
|
||||||
int dump_zeros = 0;
|
int dump_zeros;
|
||||||
int reset_history = 0;
|
int reset_history;
|
||||||
int ignore_history = 0;
|
int ignore_history;
|
||||||
int no_output = 0;
|
int no_output;
|
||||||
int json_output = 0;
|
int json_output;
|
||||||
int pretty = 0;
|
int pretty;
|
||||||
int no_update = 0;
|
int no_update;
|
||||||
int scan_interval = 0;
|
int scan_interval;
|
||||||
int time_constant = 0;
|
int time_constant;
|
||||||
double W;
|
double W;
|
||||||
char **patterns;
|
char **patterns;
|
||||||
int npatterns;
|
int npatterns;
|
||||||
|
|
@ -51,6 +51,7 @@ static int generic_proc_open(const char *env, char *name)
|
||||||
{
|
{
|
||||||
char store[128];
|
char store[128];
|
||||||
char *p = getenv(env);
|
char *p = getenv(env);
|
||||||
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
p = getenv("PROC_ROOT") ? : "/proc";
|
p = getenv("PROC_ROOT") ? : "/proc";
|
||||||
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
|
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
|
||||||
|
|
@ -74,8 +75,7 @@ static int net_snmp6_open(void)
|
||||||
return generic_proc_open("PROC_NET_SNMP6", "net/snmp6");
|
return generic_proc_open("PROC_NET_SNMP6", "net/snmp6");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nstat_ent
|
struct nstat_ent {
|
||||||
{
|
|
||||||
struct nstat_ent *next;
|
struct nstat_ent *next;
|
||||||
char *id;
|
char *id;
|
||||||
unsigned long long val;
|
unsigned long long val;
|
||||||
|
|
@ -94,6 +94,7 @@ static const char *useless_numbers[] = {
|
||||||
static int useless_number(const char *id)
|
static int useless_number(const char *id)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(useless_numbers)/sizeof(*useless_numbers); i++)
|
for (i = 0; i < sizeof(useless_numbers)/sizeof(*useless_numbers); i++)
|
||||||
if (strcmp(id, useless_numbers[i]) == 0)
|
if (strcmp(id, useless_numbers[i]) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -125,6 +126,7 @@ static void load_good_table(FILE *fp)
|
||||||
unsigned long long val;
|
unsigned long long val;
|
||||||
double rate;
|
double rate;
|
||||||
char idbuf[sizeof(buf)];
|
char idbuf[sizeof(buf)];
|
||||||
|
|
||||||
if (buf[0] == '#') {
|
if (buf[0] == '#') {
|
||||||
buf[strlen(buf)-1] = 0;
|
buf[strlen(buf)-1] = 0;
|
||||||
if (info_source[0] && strcmp(info_source, buf+1))
|
if (info_source[0] && strcmp(info_source, buf+1))
|
||||||
|
|
@ -192,6 +194,7 @@ static void load_ugly_table(FILE *fp)
|
||||||
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
char *next;
|
char *next;
|
||||||
|
|
||||||
if ((next = strchr(p, ' ')) != NULL)
|
if ((next = strchr(p, ' ')) != NULL)
|
||||||
*next++ = 0;
|
*next++ = 0;
|
||||||
else if ((next = strchr(p, '\n')) != NULL)
|
else if ((next = strchr(p, '\n')) != NULL)
|
||||||
|
|
@ -246,6 +249,7 @@ static void load_ugly_table(FILE *fp)
|
||||||
static void load_snmp(void)
|
static void load_snmp(void)
|
||||||
{
|
{
|
||||||
FILE *fp = fdopen(net_snmp_open(), "r");
|
FILE *fp = fdopen(net_snmp_open(), "r");
|
||||||
|
|
||||||
if (fp) {
|
if (fp) {
|
||||||
load_ugly_table(fp);
|
load_ugly_table(fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
@ -255,6 +259,7 @@ static void load_snmp(void)
|
||||||
static void load_snmp6(void)
|
static void load_snmp6(void)
|
||||||
{
|
{
|
||||||
FILE *fp = fdopen(net_snmp6_open(), "r");
|
FILE *fp = fdopen(net_snmp6_open(), "r");
|
||||||
|
|
||||||
if (fp) {
|
if (fp) {
|
||||||
load_good_table(fp);
|
load_good_table(fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
@ -264,6 +269,7 @@ static void load_snmp6(void)
|
||||||
static void load_netstat(void)
|
static void load_netstat(void)
|
||||||
{
|
{
|
||||||
FILE *fp = fdopen(net_netstat_open(), "r");
|
FILE *fp = fdopen(net_netstat_open(), "r");
|
||||||
|
|
||||||
if (fp) {
|
if (fp) {
|
||||||
load_ugly_table(fp);
|
load_ugly_table(fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
@ -286,10 +292,12 @@ static void dump_kern_db(FILE *fp, int to_hist)
|
||||||
|
|
||||||
for (n = kern_db; n; n = n->next) {
|
for (n = kern_db; n; n = n->next) {
|
||||||
unsigned long long val = n->val;
|
unsigned long long val = n->val;
|
||||||
|
|
||||||
if (!dump_zeros && !val && !n->rate)
|
if (!dump_zeros && !val && !n->rate)
|
||||||
continue;
|
continue;
|
||||||
if (!match(n->id)) {
|
if (!match(n->id)) {
|
||||||
struct nstat_ent *h1;
|
struct nstat_ent *h1;
|
||||||
|
|
||||||
if (!to_hist)
|
if (!to_hist)
|
||||||
continue;
|
continue;
|
||||||
for (h1 = h; h1; h1 = h1->next) {
|
for (h1 = h; h1; h1 = h1->next) {
|
||||||
|
|
@ -330,6 +338,7 @@ static void dump_incr_db(FILE *fp)
|
||||||
int ovfl = 0;
|
int ovfl = 0;
|
||||||
unsigned long long val = n->val;
|
unsigned long long val = n->val;
|
||||||
struct nstat_ent *h1;
|
struct nstat_ent *h1;
|
||||||
|
|
||||||
for (h1 = h; h1; h1 = h1->next) {
|
for (h1 = h; h1; h1 = h1->next) {
|
||||||
if (strcmp(h1->id, n->id) == 0) {
|
if (strcmp(h1->id, n->id) == 0) {
|
||||||
if (val < h1->val) {
|
if (val < h1->val) {
|
||||||
|
|
@ -381,6 +390,7 @@ static void update_db(int interval)
|
||||||
|
|
||||||
for (n = kern_db; n; n = n->next) {
|
for (n = kern_db; n; n = n->next) {
|
||||||
struct nstat_ent *h1;
|
struct nstat_ent *h1;
|
||||||
|
|
||||||
for (h1 = h; h1; h1 = h1->next) {
|
for (h1 = h; h1; h1 = h1->next) {
|
||||||
if (strcmp(h1->id, n->id) == 0) {
|
if (strcmp(h1->id, n->id) == 0) {
|
||||||
double sample;
|
double sample;
|
||||||
|
|
@ -395,12 +405,14 @@ static void update_db(int interval)
|
||||||
n->rate = sample;
|
n->rate = sample;
|
||||||
} else {
|
} else {
|
||||||
double w = W*(double)interval/scan_interval;
|
double w = W*(double)interval/scan_interval;
|
||||||
|
|
||||||
n->rate += w*(sample-n->rate);
|
n->rate += w*(sample-n->rate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (h != h1) {
|
while (h != h1) {
|
||||||
struct nstat_ent *tmp = h;
|
struct nstat_ent *tmp = h;
|
||||||
|
|
||||||
h = h->next;
|
h = h->next;
|
||||||
free(tmp->id);
|
free(tmp->id);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|
@ -421,6 +433,7 @@ static void server_loop(int fd)
|
||||||
{
|
{
|
||||||
struct timeval snaptime = { 0 };
|
struct timeval snaptime = { 0 };
|
||||||
struct pollfd p;
|
struct pollfd p;
|
||||||
|
|
||||||
p.fd = fd;
|
p.fd = fd;
|
||||||
p.events = p.revents = POLLIN;
|
p.events = p.revents = POLLIN;
|
||||||
|
|
||||||
|
|
@ -435,6 +448,7 @@ static void server_loop(int fd)
|
||||||
int status;
|
int status;
|
||||||
time_t tdiff;
|
time_t tdiff;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
tdiff = T_DIFF(now, snaptime);
|
tdiff = T_DIFF(now, snaptime);
|
||||||
if (tdiff >= scan_interval) {
|
if (tdiff >= scan_interval) {
|
||||||
|
|
@ -445,8 +459,10 @@ static void server_loop(int fd)
|
||||||
if (poll(&p, 1, scan_interval - tdiff) > 0
|
if (poll(&p, 1, scan_interval - tdiff) > 0
|
||||||
&& (p.revents&POLLIN)) {
|
&& (p.revents&POLLIN)) {
|
||||||
int clnt = accept(fd, NULL, NULL);
|
int clnt = accept(fd, NULL, NULL);
|
||||||
|
|
||||||
if (clnt >= 0) {
|
if (clnt >= 0) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
if (children >= 5) {
|
if (children >= 5) {
|
||||||
close(clnt);
|
close(clnt);
|
||||||
} else if ((pid = fork()) != 0) {
|
} else if ((pid = fork()) != 0) {
|
||||||
|
|
@ -455,6 +471,7 @@ static void server_loop(int fd)
|
||||||
close(clnt);
|
close(clnt);
|
||||||
} else {
|
} else {
|
||||||
FILE *fp = fdopen(clnt, "w");
|
FILE *fp = fdopen(clnt, "w");
|
||||||
|
|
||||||
if (fp)
|
if (fp)
|
||||||
dump_kern_db(fp, 0);
|
dump_kern_db(fp, 0);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
@ -639,6 +656,7 @@ int main(int argc, char *argv[])
|
||||||
if (!ignore_history) {
|
if (!ignore_history) {
|
||||||
FILE *tfp;
|
FILE *tfp;
|
||||||
long uptime = -1;
|
long uptime = -1;
|
||||||
|
|
||||||
if ((tfp = fopen("/proc/uptime", "r")) != NULL) {
|
if ((tfp = fopen("/proc/uptime", "r")) != NULL) {
|
||||||
if (fscanf(tfp, "%ld", &uptime) != 1)
|
if (fscanf(tfp, "%ld", &uptime) != 1)
|
||||||
uptime = -1;
|
uptime = -1;
|
||||||
|
|
@ -663,6 +681,7 @@ int main(int argc, char *argv[])
|
||||||
connect(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) == 0))
|
connect(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) == 0))
|
||||||
&& verify_forging(fd) == 0) {
|
&& verify_forging(fd) == 0) {
|
||||||
FILE *sfp = fdopen(fd, "r");
|
FILE *sfp = fdopen(fd, "r");
|
||||||
|
|
||||||
load_good_table(sfp);
|
load_good_table(sfp);
|
||||||
if (hist_db && source_mismatch) {
|
if (hist_db && source_mismatch) {
|
||||||
fprintf(stderr, "nstat: history is stale, ignoring it.\n");
|
fprintf(stderr, "nstat: history is stale, ignoring it.\n");
|
||||||
|
|
|
||||||
|
|
@ -33,20 +33,21 @@
|
||||||
|
|
||||||
#include <SNAPSHOT.h>
|
#include <SNAPSHOT.h>
|
||||||
|
|
||||||
int reset_history = 0;
|
int reset_history;
|
||||||
int ignore_history = 0;
|
int ignore_history;
|
||||||
int no_output = 0;
|
int no_output;
|
||||||
int no_update = 0;
|
int no_update;
|
||||||
int scan_interval = 0;
|
int scan_interval;
|
||||||
int time_constant = 0;
|
int time_constant;
|
||||||
int dump_zeros = 0;
|
int dump_zeros;
|
||||||
unsigned long magic_number = 0;
|
unsigned long magic_number;
|
||||||
double W;
|
double W;
|
||||||
|
|
||||||
static int generic_proc_open(const char *env, const char *name)
|
static int generic_proc_open(const char *env, const char *name)
|
||||||
{
|
{
|
||||||
char store[1024];
|
char store[1024];
|
||||||
char *p = getenv(env);
|
char *p = getenv(env);
|
||||||
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
p = getenv("PROC_ROOT") ? : "/proc";
|
p = getenv("PROC_ROOT") ? : "/proc";
|
||||||
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
|
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
|
||||||
|
|
@ -62,8 +63,7 @@ static int net_rtacct_open(void)
|
||||||
|
|
||||||
static __u32 rmap[256/4];
|
static __u32 rmap[256/4];
|
||||||
|
|
||||||
struct rtacct_data
|
struct rtacct_data {
|
||||||
{
|
|
||||||
__u32 ival[256*4];
|
__u32 ival[256*4];
|
||||||
|
|
||||||
unsigned long long val[256*4];
|
unsigned long long val[256*4];
|
||||||
|
|
@ -82,6 +82,7 @@ static void nread(int fd, char *buf, int tot)
|
||||||
|
|
||||||
while (count < tot) {
|
while (count < tot) {
|
||||||
int n = read(fd, buf+count, tot-count);
|
int n = read(fd, buf+count, tot-count);
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -134,13 +135,13 @@ static void format_rate(FILE *fp, double rate)
|
||||||
char temp[64];
|
char temp[64];
|
||||||
|
|
||||||
if (rate > 1024*1024) {
|
if (rate > 1024*1024) {
|
||||||
sprintf(temp, "%uM", (unsigned)rint(rate/(1024*1024)));
|
sprintf(temp, "%uM", (unsigned int)rint(rate/(1024*1024)));
|
||||||
fprintf(fp, " %-10s", temp);
|
fprintf(fp, " %-10s", temp);
|
||||||
} else if (rate > 1024) {
|
} else if (rate > 1024) {
|
||||||
sprintf(temp, "%uK", (unsigned)rint(rate/1024));
|
sprintf(temp, "%uK", (unsigned int)rint(rate/1024));
|
||||||
fprintf(fp, " %-10s", temp);
|
fprintf(fp, " %-10s", temp);
|
||||||
} else
|
} else
|
||||||
fprintf(fp, " %-10u", (unsigned)rate);
|
fprintf(fp, " %-10u", (unsigned int)rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void format_count(FILE *fp, unsigned long long val)
|
static void format_count(FILE *fp, unsigned long long val)
|
||||||
|
|
@ -161,20 +162,14 @@ static void dump_abs_db(FILE *fp)
|
||||||
if (!no_output) {
|
if (!no_output) {
|
||||||
fprintf(fp, "#%s\n", kern_db->signature);
|
fprintf(fp, "#%s\n", kern_db->signature);
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"%-10s "
|
"%-10s %-10s "
|
||||||
"%-10s "
|
"%-10s %-10s "
|
||||||
"%-10s "
|
"%-10s \n"
|
||||||
"%-10s "
|
|
||||||
"%-10s "
|
|
||||||
"\n"
|
|
||||||
, "Realm", "BytesTo", "PktsTo", "BytesFrom", "PktsFrom");
|
, "Realm", "BytesTo", "PktsTo", "BytesFrom", "PktsFrom");
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"%-10s "
|
"%-10s %-10s "
|
||||||
"%-10s "
|
"%-10s %-10s "
|
||||||
"%-10s "
|
"%-10s \n"
|
||||||
"%-10s "
|
|
||||||
"%-10s "
|
|
||||||
"\n"
|
|
||||||
, "", "BPSTo", "PPSTo", "BPSFrom", "PPSFrom");
|
, "", "BPSTo", "PPSTo", "BPSFrom", "PPSFrom");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -223,20 +218,14 @@ static void dump_incr_db(FILE *fp)
|
||||||
if (!no_output) {
|
if (!no_output) {
|
||||||
fprintf(fp, "#%s\n", kern_db->signature);
|
fprintf(fp, "#%s\n", kern_db->signature);
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"%-10s "
|
"%-10s %-10s "
|
||||||
"%-10s "
|
"%-10s %-10s "
|
||||||
"%-10s "
|
"%-10s \n"
|
||||||
"%-10s "
|
|
||||||
"%-10s "
|
|
||||||
"\n"
|
|
||||||
, "Realm", "BytesTo", "PktsTo", "BytesFrom", "PktsFrom");
|
, "Realm", "BytesTo", "PktsTo", "BytesFrom", "PktsFrom");
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"%-10s "
|
"%-10s %-10s "
|
||||||
"%-10s "
|
"%-10s %-10s "
|
||||||
"%-10s "
|
"%-10s \n"
|
||||||
"%-10s "
|
|
||||||
"%-10s "
|
|
||||||
"\n"
|
|
||||||
, "", "BPSTo", "PPSTo", "BPSFrom", "PPSFrom");
|
, "", "BPSTo", "PPSTo", "BPSFrom", "PPSFrom");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -324,6 +313,7 @@ static void update_db(int interval)
|
||||||
kern_db->rate[i] = sample;
|
kern_db->rate[i] = sample;
|
||||||
} else {
|
} else {
|
||||||
double w = W*(double)interval/scan_interval;
|
double w = W*(double)interval/scan_interval;
|
||||||
|
|
||||||
kern_db->rate[i] += w*(sample-kern_db->rate[i]);
|
kern_db->rate[i] += w*(sample-kern_db->rate[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -336,6 +326,7 @@ static void send_db(int fd)
|
||||||
|
|
||||||
while (tot < sizeof(*kern_db)) {
|
while (tot < sizeof(*kern_db)) {
|
||||||
int n = write(fd, ((char *)kern_db) + tot, sizeof(*kern_db)-tot);
|
int n = write(fd, ((char *)kern_db) + tot, sizeof(*kern_db)-tot);
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -353,6 +344,7 @@ static void send_db(int fd)
|
||||||
static void pad_kern_table(struct rtacct_data *dat, __u32 *ival)
|
static void pad_kern_table(struct rtacct_data *dat, __u32 *ival)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset(dat->rate, 0, sizeof(dat->rate));
|
memset(dat->rate, 0, sizeof(dat->rate));
|
||||||
if (dat->ival != ival)
|
if (dat->ival != ival)
|
||||||
memcpy(dat->ival, ival, sizeof(dat->ival));
|
memcpy(dat->ival, ival, sizeof(dat->ival));
|
||||||
|
|
@ -364,12 +356,13 @@ static void server_loop(int fd)
|
||||||
{
|
{
|
||||||
struct timeval snaptime = { 0 };
|
struct timeval snaptime = { 0 };
|
||||||
struct pollfd p;
|
struct pollfd p;
|
||||||
|
|
||||||
p.fd = fd;
|
p.fd = fd;
|
||||||
p.events = p.revents = POLLIN;
|
p.events = p.revents = POLLIN;
|
||||||
|
|
||||||
sprintf(kern_db->signature,
|
sprintf(kern_db->signature,
|
||||||
"%u.%lu sampling_interval=%d time_const=%d",
|
"%u.%lu sampling_interval=%d time_const=%d",
|
||||||
(unsigned) getpid(), (unsigned long)random(),
|
(unsigned int) getpid(), (unsigned long)random(),
|
||||||
scan_interval/1000, time_constant/1000);
|
scan_interval/1000, time_constant/1000);
|
||||||
|
|
||||||
pad_kern_table(kern_db, read_kern_table(kern_db->ival));
|
pad_kern_table(kern_db, read_kern_table(kern_db->ival));
|
||||||
|
|
@ -378,6 +371,7 @@ static void server_loop(int fd)
|
||||||
int status;
|
int status;
|
||||||
int tdiff;
|
int tdiff;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
tdiff = T_DIFF(now, snaptime);
|
tdiff = T_DIFF(now, snaptime);
|
||||||
if (tdiff >= scan_interval) {
|
if (tdiff >= scan_interval) {
|
||||||
|
|
@ -388,8 +382,10 @@ static void server_loop(int fd)
|
||||||
if (poll(&p, 1, tdiff + scan_interval) > 0
|
if (poll(&p, 1, tdiff + scan_interval) > 0
|
||||||
&& (p.revents&POLLIN)) {
|
&& (p.revents&POLLIN)) {
|
||||||
int clnt = accept(fd, NULL, NULL);
|
int clnt = accept(fd, NULL, NULL);
|
||||||
|
|
||||||
if (clnt >= 0) {
|
if (clnt >= 0) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
if (children >= 5) {
|
if (children >= 5) {
|
||||||
close(clnt);
|
close(clnt);
|
||||||
} else if ((pid = fork()) != 0) {
|
} else if ((pid = fork()) != 0) {
|
||||||
|
|
@ -489,6 +485,7 @@ int main(int argc, char *argv[])
|
||||||
if (argc) {
|
if (argc) {
|
||||||
while (argc > 0) {
|
while (argc > 0) {
|
||||||
__u32 realm;
|
__u32 realm;
|
||||||
|
|
||||||
if (rtnl_rtrealm_a2n(&realm, argv[0])) {
|
if (rtnl_rtrealm_a2n(&realm, argv[0])) {
|
||||||
fprintf(stderr, "Warning: realm \"%s\" does not exist.\n", argv[0]);
|
fprintf(stderr, "Warning: realm \"%s\" does not exist.\n", argv[0]);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|
@ -580,6 +577,7 @@ int main(int argc, char *argv[])
|
||||||
if (!ignore_history) {
|
if (!ignore_history) {
|
||||||
FILE *tfp;
|
FILE *tfp;
|
||||||
long uptime = -1;
|
long uptime = -1;
|
||||||
|
|
||||||
if ((tfp = fopen("/proc/uptime", "r")) != NULL) {
|
if ((tfp = fopen("/proc/uptime", "r")) != NULL) {
|
||||||
if (fscanf(tfp, "%ld", &uptime) != 1)
|
if (fscanf(tfp, "%ld", &uptime) != 1)
|
||||||
uptime = -1;
|
uptime = -1;
|
||||||
|
|
|
||||||
127
misc/ss.c
127
misc/ss.c
|
|
@ -86,20 +86,20 @@ static int security_get_initial_context(char *name, char **context)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int resolve_hosts = 0;
|
int resolve_hosts;
|
||||||
int resolve_services = 1;
|
int resolve_services = 1;
|
||||||
int preferred_family = AF_UNSPEC;
|
int preferred_family = AF_UNSPEC;
|
||||||
int show_options = 0;
|
int show_options;
|
||||||
int show_details = 0;
|
int show_details;
|
||||||
int show_users = 0;
|
int show_users;
|
||||||
int show_mem = 0;
|
int show_mem;
|
||||||
int show_tcpinfo = 0;
|
int show_tcpinfo;
|
||||||
int show_bpf = 0;
|
int show_bpf;
|
||||||
int show_proc_ctx = 0;
|
int show_proc_ctx;
|
||||||
int show_sock_ctx = 0;
|
int show_sock_ctx;
|
||||||
/* If show_users & show_proc_ctx only do user_ent_hash_build() once */
|
/* If show_users & show_proc_ctx only do user_ent_hash_build() once */
|
||||||
int user_ent_hash_build_init = 0;
|
int user_ent_hash_build_init;
|
||||||
int follow_events = 0;
|
int follow_events;
|
||||||
|
|
||||||
int netid_width;
|
int netid_width;
|
||||||
int state_width;
|
int state_width;
|
||||||
|
|
@ -111,10 +111,9 @@ int screen_width;
|
||||||
static const char *TCP_PROTO = "tcp";
|
static const char *TCP_PROTO = "tcp";
|
||||||
static const char *UDP_PROTO = "udp";
|
static const char *UDP_PROTO = "udp";
|
||||||
static const char *RAW_PROTO = "raw";
|
static const char *RAW_PROTO = "raw";
|
||||||
static const char *dg_proto = NULL;
|
static const char *dg_proto;
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
TCP_DB,
|
TCP_DB,
|
||||||
DCCP_DB,
|
DCCP_DB,
|
||||||
UDP_DB,
|
UDP_DB,
|
||||||
|
|
@ -154,8 +153,7 @@ enum {
|
||||||
|
|
||||||
#include "ssfilter.h"
|
#include "ssfilter.h"
|
||||||
|
|
||||||
struct filter
|
struct filter {
|
||||||
{
|
|
||||||
int dbs;
|
int dbs;
|
||||||
int states;
|
int states;
|
||||||
int families;
|
int families;
|
||||||
|
|
@ -551,7 +549,7 @@ enum entry_types {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ENTRY_BUF_SIZE 512
|
#define ENTRY_BUF_SIZE 512
|
||||||
static int find_entry(unsigned ino, char **buf, int type)
|
static int find_entry(unsigned int ino, char **buf, int type)
|
||||||
{
|
{
|
||||||
struct user_ent *p;
|
struct user_ent *p;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
@ -624,8 +622,7 @@ next:
|
||||||
|
|
||||||
/* Get stats from slab */
|
/* Get stats from slab */
|
||||||
|
|
||||||
struct slabstat
|
struct slabstat {
|
||||||
{
|
|
||||||
int socks;
|
int socks;
|
||||||
int tcp_ports;
|
int tcp_ports;
|
||||||
int tcp_tws;
|
int tcp_tws;
|
||||||
|
|
@ -635,8 +632,8 @@ struct slabstat
|
||||||
|
|
||||||
static struct slabstat slabstat;
|
static struct slabstat slabstat;
|
||||||
|
|
||||||
static const char *slabstat_ids[] =
|
static const char *slabstat_ids[] = {
|
||||||
{
|
|
||||||
"sock",
|
"sock",
|
||||||
"tcp_bind_bucket",
|
"tcp_bind_bucket",
|
||||||
"tcp_tw_bucket",
|
"tcp_tw_bucket",
|
||||||
|
|
@ -668,6 +665,7 @@ static int get_slabstat(struct slabstat *s)
|
||||||
}
|
}
|
||||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(slabstat_ids)/sizeof(slabstat_ids[0]); i++) {
|
for (i = 0; i < sizeof(slabstat_ids)/sizeof(slabstat_ids[0]); i++) {
|
||||||
if (memcmp(buf, slabstat_ids[i], strlen(slabstat_ids[i])) == 0) {
|
if (memcmp(buf, slabstat_ids[i], strlen(slabstat_ids[i])) == 0) {
|
||||||
sscanf(buf, "%*s%d", ((int *)s) + i);
|
sscanf(buf, "%*s%d", ((int *)s) + i);
|
||||||
|
|
@ -720,8 +718,7 @@ static const char *sstate_namel[] = {
|
||||||
[SS_CLOSING] = "closing",
|
[SS_CLOSING] = "closing",
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sockstat
|
struct sockstat {
|
||||||
{
|
|
||||||
struct sockstat *next;
|
struct sockstat *next;
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
uint16_t prot;
|
uint16_t prot;
|
||||||
|
|
@ -731,8 +728,8 @@ struct sockstat
|
||||||
int rport;
|
int rport;
|
||||||
int state;
|
int state;
|
||||||
int rq, wq;
|
int rq, wq;
|
||||||
unsigned ino;
|
unsigned int ino;
|
||||||
unsigned uid;
|
unsigned int uid;
|
||||||
int refcnt;
|
int refcnt;
|
||||||
unsigned int iface;
|
unsigned int iface;
|
||||||
unsigned long long sk;
|
unsigned long long sk;
|
||||||
|
|
@ -740,8 +737,7 @@ struct sockstat
|
||||||
char *peer_name;
|
char *peer_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dctcpstat
|
struct dctcpstat {
|
||||||
{
|
|
||||||
unsigned int ce_state;
|
unsigned int ce_state;
|
||||||
unsigned int alpha;
|
unsigned int alpha;
|
||||||
unsigned int ab_ecn;
|
unsigned int ab_ecn;
|
||||||
|
|
@ -749,8 +745,7 @@ struct dctcpstat
|
||||||
bool enabled;
|
bool enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tcpstat
|
struct tcpstat {
|
||||||
{
|
|
||||||
struct sockstat ss;
|
struct sockstat ss;
|
||||||
int timer;
|
int timer;
|
||||||
int timeout;
|
int timeout;
|
||||||
|
|
@ -816,8 +811,7 @@ static void sock_addr_print_width(int addr_len, const char *addr, char *delim,
|
||||||
if (ifname) {
|
if (ifname) {
|
||||||
printf("%*s%%%s%s%-*s ", addr_len, addr, ifname, delim,
|
printf("%*s%%%s%s%-*s ", addr_len, addr, ifname, delim,
|
||||||
port_len, port);
|
port_len, port);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
printf("%*s%s%-*s ", addr_len, addr, delim, port_len, port);
|
printf("%*s%s%-*s ", addr_len, addr, delim, port_len, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -841,6 +835,7 @@ static const char *print_ms_timer(int timeout)
|
||||||
{
|
{
|
||||||
static char buf[64];
|
static char buf[64];
|
||||||
int secs, msecs, minutes;
|
int secs, msecs, minutes;
|
||||||
|
|
||||||
if (timeout < 0)
|
if (timeout < 0)
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
secs = timeout/1000;
|
secs = timeout/1000;
|
||||||
|
|
@ -919,10 +914,11 @@ static void init_service_resolver(void)
|
||||||
*/
|
*/
|
||||||
static int is_ephemeral(int port)
|
static int is_ephemeral(int port)
|
||||||
{
|
{
|
||||||
static int min = 0, max = 0;
|
static int min = 0, max;
|
||||||
|
|
||||||
if (!min) {
|
if (!min) {
|
||||||
FILE *f = ephemeral_ports_open();
|
FILE *f = ephemeral_ports_open();
|
||||||
|
|
||||||
if (!f || fscanf(f, "%d %d", &min, &max) < 2) {
|
if (!f || fscanf(f, "%d %d", &min, &max) < 2) {
|
||||||
min = 1024;
|
min = 1024;
|
||||||
max = 4999;
|
max = 4999;
|
||||||
|
|
@ -946,6 +942,7 @@ static const char *__resolve_service(int port)
|
||||||
if (!is_ephemeral(port)) {
|
if (!is_ephemeral(port)) {
|
||||||
static int notfirst;
|
static int notfirst;
|
||||||
struct servent *se;
|
struct servent *se;
|
||||||
|
|
||||||
if (!notfirst) {
|
if (!notfirst) {
|
||||||
setservent(1);
|
setservent(1);
|
||||||
notfirst = 1;
|
notfirst = 1;
|
||||||
|
|
@ -1041,8 +1038,7 @@ static void inet_addr_print(const inet_prefix *a, int port, unsigned int ifindex
|
||||||
ifname);
|
ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct aafilter
|
struct aafilter {
|
||||||
{
|
|
||||||
inet_prefix addr;
|
inet_prefix addr;
|
||||||
int port;
|
int port;
|
||||||
struct aafilter *next;
|
struct aafilter *next;
|
||||||
|
|
@ -1061,6 +1057,7 @@ static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
|
||||||
if (a->data[0] == 0 && a->data[1] == 0 &&
|
if (a->data[0] == 0 && a->data[1] == 0 &&
|
||||||
a->data[2] == htonl(0xffff)) {
|
a->data[2] == htonl(0xffff)) {
|
||||||
inet_prefix tmp = *a;
|
inet_prefix tmp = *a;
|
||||||
|
|
||||||
tmp.data[0] = a->data[3];
|
tmp.data[0] = a->data[3];
|
||||||
return inet_addr_match(&tmp, p, plen);
|
return inet_addr_match(&tmp, p, plen);
|
||||||
}
|
}
|
||||||
|
|
@ -1071,6 +1068,7 @@ static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
|
||||||
static int unix_match(const inet_prefix *a, const inet_prefix *p)
|
static int unix_match(const inet_prefix *a, const inet_prefix *p)
|
||||||
{
|
{
|
||||||
char *addr, *pattern;
|
char *addr, *pattern;
|
||||||
|
|
||||||
memcpy(&addr, a->data, sizeof(addr));
|
memcpy(&addr, a->data, sizeof(addr));
|
||||||
memcpy(&pattern, p->data, sizeof(pattern));
|
memcpy(&pattern, p->data, sizeof(pattern));
|
||||||
if (pattern == NULL)
|
if (pattern == NULL)
|
||||||
|
|
@ -1087,6 +1085,7 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
|
||||||
{
|
{
|
||||||
if (s->local.family == AF_UNIX) {
|
if (s->local.family == AF_UNIX) {
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
memcpy(&p, s->local.data, sizeof(p));
|
memcpy(&p, s->local.data, sizeof(p));
|
||||||
return p == NULL || (p[0] == '@' && strlen(p) == 6 &&
|
return p == NULL || (p[0] == '@' && strlen(p) == 6 &&
|
||||||
strspn(p+1, "0123456789abcdef") == 5);
|
strspn(p+1, "0123456789abcdef") == 5);
|
||||||
|
|
@ -1101,6 +1100,7 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
|
||||||
case SSF_DCOND:
|
case SSF_DCOND:
|
||||||
{
|
{
|
||||||
struct aafilter *a = (void *)f->pred;
|
struct aafilter *a = (void *)f->pred;
|
||||||
|
|
||||||
if (a->addr.family == AF_UNIX)
|
if (a->addr.family == AF_UNIX)
|
||||||
return unix_match(&s->remote, &a->addr);
|
return unix_match(&s->remote, &a->addr);
|
||||||
if (a->port != -1 && a->port != s->rport)
|
if (a->port != -1 && a->port != s->rport)
|
||||||
|
|
@ -1117,6 +1117,7 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
|
||||||
case SSF_SCOND:
|
case SSF_SCOND:
|
||||||
{
|
{
|
||||||
struct aafilter *a = (void *)f->pred;
|
struct aafilter *a = (void *)f->pred;
|
||||||
|
|
||||||
if (a->addr.family == AF_UNIX)
|
if (a->addr.family == AF_UNIX)
|
||||||
return unix_match(&s->local, &a->addr);
|
return unix_match(&s->local, &a->addr);
|
||||||
if (a->port != -1 && a->port != s->lport)
|
if (a->port != -1 && a->port != s->lport)
|
||||||
|
|
@ -1133,21 +1134,25 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
|
||||||
case SSF_D_GE:
|
case SSF_D_GE:
|
||||||
{
|
{
|
||||||
struct aafilter *a = (void *)f->pred;
|
struct aafilter *a = (void *)f->pred;
|
||||||
|
|
||||||
return s->rport >= a->port;
|
return s->rport >= a->port;
|
||||||
}
|
}
|
||||||
case SSF_D_LE:
|
case SSF_D_LE:
|
||||||
{
|
{
|
||||||
struct aafilter *a = (void *)f->pred;
|
struct aafilter *a = (void *)f->pred;
|
||||||
|
|
||||||
return s->rport <= a->port;
|
return s->rport <= a->port;
|
||||||
}
|
}
|
||||||
case SSF_S_GE:
|
case SSF_S_GE:
|
||||||
{
|
{
|
||||||
struct aafilter *a = (void *)f->pred;
|
struct aafilter *a = (void *)f->pred;
|
||||||
|
|
||||||
return s->lport >= a->port;
|
return s->lport >= a->port;
|
||||||
}
|
}
|
||||||
case SSF_S_LE:
|
case SSF_S_LE:
|
||||||
{
|
{
|
||||||
struct aafilter *a = (void *)f->pred;
|
struct aafilter *a = (void *)f->pred;
|
||||||
|
|
||||||
return s->lport <= a->port;
|
return s->lport <= a->port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1168,6 +1173,7 @@ static void ssfilter_patch(char *a, int len, int reloc)
|
||||||
{
|
{
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)a;
|
struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)a;
|
||||||
|
|
||||||
if (op->no == len+4)
|
if (op->no == len+4)
|
||||||
op->no += reloc;
|
op->no += reloc;
|
||||||
len -= op->yes;
|
len -= op->yes;
|
||||||
|
|
@ -1229,6 +1235,7 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
|
||||||
case SSF_D_GE:
|
case SSF_D_GE:
|
||||||
{
|
{
|
||||||
struct aafilter *x = (void *)f->pred;
|
struct aafilter *x = (void *)f->pred;
|
||||||
|
|
||||||
if (!(*bytecode = malloc(8))) abort();
|
if (!(*bytecode = malloc(8))) abort();
|
||||||
((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_GE, 8, 12 };
|
((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_GE, 8, 12 };
|
||||||
((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
|
((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
|
||||||
|
|
@ -1237,6 +1244,7 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
|
||||||
case SSF_D_LE:
|
case SSF_D_LE:
|
||||||
{
|
{
|
||||||
struct aafilter *x = (void *)f->pred;
|
struct aafilter *x = (void *)f->pred;
|
||||||
|
|
||||||
if (!(*bytecode = malloc(8))) abort();
|
if (!(*bytecode = malloc(8))) abort();
|
||||||
((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_LE, 8, 12 };
|
((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_LE, 8, 12 };
|
||||||
((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
|
((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
|
||||||
|
|
@ -1245,6 +1253,7 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
|
||||||
case SSF_S_GE:
|
case SSF_S_GE:
|
||||||
{
|
{
|
||||||
struct aafilter *x = (void *)f->pred;
|
struct aafilter *x = (void *)f->pred;
|
||||||
|
|
||||||
if (!(*bytecode = malloc(8))) abort();
|
if (!(*bytecode = malloc(8))) abort();
|
||||||
((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_GE, 8, 12 };
|
((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_GE, 8, 12 };
|
||||||
((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
|
((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
|
||||||
|
|
@ -1253,6 +1262,7 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
|
||||||
case SSF_S_LE:
|
case SSF_S_LE:
|
||||||
{
|
{
|
||||||
struct aafilter *x = (void *)f->pred;
|
struct aafilter *x = (void *)f->pred;
|
||||||
|
|
||||||
if (!(*bytecode = malloc(8))) abort();
|
if (!(*bytecode = malloc(8))) abort();
|
||||||
((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_LE, 8, 12 };
|
((struct inet_diag_bc_op *)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_LE, 8, 12 };
|
||||||
((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
|
((struct inet_diag_bc_op *)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port };
|
||||||
|
|
@ -1263,6 +1273,7 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
|
||||||
{
|
{
|
||||||
char *a1, *a2, *a;
|
char *a1, *a2, *a;
|
||||||
int l1, l2;
|
int l1, l2;
|
||||||
|
|
||||||
l1 = ssfilter_bytecompile(f->pred, &a1);
|
l1 = ssfilter_bytecompile(f->pred, &a1);
|
||||||
l2 = ssfilter_bytecompile(f->post, &a2);
|
l2 = ssfilter_bytecompile(f->post, &a2);
|
||||||
if (!(a = malloc(l1+l2))) abort();
|
if (!(a = malloc(l1+l2))) abort();
|
||||||
|
|
@ -1277,6 +1288,7 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
|
||||||
{
|
{
|
||||||
char *a1, *a2, *a;
|
char *a1, *a2, *a;
|
||||||
int l1, l2;
|
int l1, l2;
|
||||||
|
|
||||||
l1 = ssfilter_bytecompile(f->pred, &a1);
|
l1 = ssfilter_bytecompile(f->pred, &a1);
|
||||||
l2 = ssfilter_bytecompile(f->post, &a2);
|
l2 = ssfilter_bytecompile(f->post, &a2);
|
||||||
if (!(a = malloc(l1+l2+4))) abort();
|
if (!(a = malloc(l1+l2+4))) abort();
|
||||||
|
|
@ -1291,6 +1303,7 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
|
||||||
{
|
{
|
||||||
char *a1, *a;
|
char *a1, *a;
|
||||||
int l1;
|
int l1;
|
||||||
|
|
||||||
l1 = ssfilter_bytecompile(f->pred, &a1);
|
l1 = ssfilter_bytecompile(f->pred, &a1);
|
||||||
if (!(a = malloc(l1+4))) abort();
|
if (!(a = malloc(l1+4))) abort();
|
||||||
memcpy(a, a1, l1);
|
memcpy(a, a1, l1);
|
||||||
|
|
@ -1319,6 +1332,7 @@ static int remember_he(struct aafilter *a, struct hostent *he)
|
||||||
|
|
||||||
while (*ptr) {
|
while (*ptr) {
|
||||||
struct aafilter *b = a;
|
struct aafilter *b = a;
|
||||||
|
|
||||||
if (a->addr.bitlen) {
|
if (a->addr.bitlen) {
|
||||||
if ((b = malloc(sizeof(*b))) == NULL)
|
if ((b = malloc(sizeof(*b))) == NULL)
|
||||||
return cnt;
|
return cnt;
|
||||||
|
|
@ -1358,11 +1372,12 @@ static int get_dns_host(struct aafilter *a, const char *addr, int fam)
|
||||||
return !cnt;
|
return !cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xll_initted = 0;
|
static int xll_initted;
|
||||||
|
|
||||||
static void xll_init(void)
|
static void xll_init(void)
|
||||||
{
|
{
|
||||||
struct rtnl_handle rth;
|
struct rtnl_handle rth;
|
||||||
|
|
||||||
if (rtnl_open(&rth, 0) < 0)
|
if (rtnl_open(&rth, 0) < 0)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
|
|
@ -1395,6 +1410,7 @@ void *parse_hostcond(char *addr, bool is_port)
|
||||||
|
|
||||||
if (fam == AF_UNIX || strncmp(addr, "unix:", 5) == 0) {
|
if (fam == AF_UNIX || strncmp(addr, "unix:", 5) == 0) {
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
a.addr.family = AF_UNIX;
|
a.addr.family = AF_UNIX;
|
||||||
if (strncmp(addr, "unix:", 5) == 0)
|
if (strncmp(addr, "unix:", 5) == 0)
|
||||||
addr += 5;
|
addr += 5;
|
||||||
|
|
@ -1422,6 +1438,7 @@ void *parse_hostcond(char *addr, bool is_port)
|
||||||
}
|
}
|
||||||
if (addr[0] && strcmp(addr, "*")) {
|
if (addr[0] && strcmp(addr, "*")) {
|
||||||
unsigned short tmp;
|
unsigned short tmp;
|
||||||
|
|
||||||
a.addr.bitlen = 32;
|
a.addr.bitlen = 32;
|
||||||
if (ll_proto_a2n(&tmp, addr))
|
if (ll_proto_a2n(&tmp, addr))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1490,6 +1507,7 @@ void *parse_hostcond(char *addr, bool is_port)
|
||||||
if (get_integer(&a.port, port, 0)) {
|
if (get_integer(&a.port, port, 0)) {
|
||||||
struct servent *se1 = NULL;
|
struct servent *se1 = NULL;
|
||||||
struct servent *se2 = NULL;
|
struct servent *se2 = NULL;
|
||||||
|
|
||||||
if (current_filter.dbs&(1<<UDP_DB))
|
if (current_filter.dbs&(1<<UDP_DB))
|
||||||
se1 = getservbyname(port, UDP_PROTO);
|
se1 = getservbyname(port, UDP_PROTO);
|
||||||
if (current_filter.dbs&(1<<TCP_DB))
|
if (current_filter.dbs&(1<<TCP_DB))
|
||||||
|
|
@ -1504,6 +1522,7 @@ void *parse_hostcond(char *addr, bool is_port)
|
||||||
a.port = ntohs(se1->s_port);
|
a.port = ntohs(se1->s_port);
|
||||||
} else {
|
} else {
|
||||||
struct scache *s;
|
struct scache *s;
|
||||||
|
|
||||||
for (s = rlist; s; s = s->next) {
|
for (s = rlist; s; s = s->next) {
|
||||||
if ((s->proto == UDP_PROTO &&
|
if ((s->proto == UDP_PROTO &&
|
||||||
(current_filter.dbs&(1<<UDP_DB))) ||
|
(current_filter.dbs&(1<<UDP_DB))) ||
|
||||||
|
|
@ -1770,6 +1789,7 @@ static int tcp_show_line(char *line, const struct filter *f, int family)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0');
|
int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0');
|
||||||
|
|
||||||
if (!(f->states & (1 << state)))
|
if (!(f->states & (1 << state)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -1833,6 +1853,7 @@ static int generic_record_read(FILE *fp,
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||||
int n = strlen(line);
|
int n = strlen(line);
|
||||||
|
|
||||||
if (n == 0 || line[n-1] != '\n') {
|
if (n == 0 || line[n-1] != '\n') {
|
||||||
errno = -EINVAL;
|
errno = -EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -2053,11 +2074,13 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
|
||||||
sock_details_print(&s);
|
sock_details_print(&s);
|
||||||
if (s.local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY]) {
|
if (s.local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY]) {
|
||||||
unsigned char v6only;
|
unsigned char v6only;
|
||||||
|
|
||||||
v6only = *(__u8 *)RTA_DATA(tb[INET_DIAG_SKV6ONLY]);
|
v6only = *(__u8 *)RTA_DATA(tb[INET_DIAG_SKV6ONLY]);
|
||||||
printf(" v6only:%u", v6only);
|
printf(" v6only:%u", v6only);
|
||||||
}
|
}
|
||||||
if (tb[INET_DIAG_SHUTDOWN]) {
|
if (tb[INET_DIAG_SHUTDOWN]) {
|
||||||
unsigned char mask;
|
unsigned char mask;
|
||||||
|
|
||||||
mask = *(__u8 *)RTA_DATA(tb[INET_DIAG_SHUTDOWN]);
|
mask = *(__u8 *)RTA_DATA(tb[INET_DIAG_SHUTDOWN]);
|
||||||
printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
|
printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
|
||||||
}
|
}
|
||||||
|
|
@ -2144,6 +2167,7 @@ static int tcpdiag_send(int fd, int protocol, struct filter *f)
|
||||||
static int sockdiag_send(int family, int fd, int protocol, struct filter *f)
|
static int sockdiag_send(int family, int fd, int protocol, struct filter *f)
|
||||||
{
|
{
|
||||||
struct sockaddr_nl nladdr;
|
struct sockaddr_nl nladdr;
|
||||||
|
|
||||||
DIAG_REQUEST(req, struct inet_diag_req_v2 r);
|
DIAG_REQUEST(req, struct inet_diag_req_v2 r);
|
||||||
char *bc = NULL;
|
char *bc = NULL;
|
||||||
int bclen;
|
int bclen;
|
||||||
|
|
@ -2212,6 +2236,7 @@ static int kill_inet_sock(const struct sockaddr_nl *addr,
|
||||||
struct inet_diag_msg *d = NLMSG_DATA(h);
|
struct inet_diag_msg *d = NLMSG_DATA(h);
|
||||||
struct inet_diag_arg *diag_arg = arg;
|
struct inet_diag_arg *diag_arg = arg;
|
||||||
struct rtnl_handle *rth = diag_arg->rth;
|
struct rtnl_handle *rth = diag_arg->rth;
|
||||||
|
|
||||||
DIAG_REQUEST(req, struct inet_diag_req_v2 r);
|
DIAG_REQUEST(req, struct inet_diag_req_v2 r);
|
||||||
|
|
||||||
req.nlh.nlmsg_type = SOCK_DESTROY;
|
req.nlh.nlmsg_type = SOCK_DESTROY;
|
||||||
|
|
@ -2335,6 +2360,7 @@ static int tcp_show_netlink_file(struct filter *f)
|
||||||
|
|
||||||
if (h->nlmsg_type == NLMSG_ERROR) {
|
if (h->nlmsg_type == NLMSG_ERROR) {
|
||||||
struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(h);
|
struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(h);
|
||||||
|
|
||||||
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
|
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
|
||||||
fprintf(stderr, "ERROR truncated\n");
|
fprintf(stderr, "ERROR truncated\n");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2381,6 +2407,7 @@ static int tcp_show(struct filter *f, int socktype)
|
||||||
get_slabstat(&slabstat);
|
get_slabstat(&slabstat);
|
||||||
|
|
||||||
int guess = slabstat.socks+slabstat.tcp_syns;
|
int guess = slabstat.socks+slabstat.tcp_syns;
|
||||||
|
|
||||||
if (f->states&(1<<SS_TIME_WAIT))
|
if (f->states&(1<<SS_TIME_WAIT))
|
||||||
guess += slabstat.tcp_tws;
|
guess += slabstat.tcp_tws;
|
||||||
if (guess > (16*1024*1024)/128)
|
if (guess > (16*1024*1024)/128)
|
||||||
|
|
@ -2423,6 +2450,7 @@ static int tcp_show(struct filter *f, int socktype)
|
||||||
outerr:
|
outerr:
|
||||||
do {
|
do {
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
if (fp)
|
if (fp)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
@ -2443,6 +2471,7 @@ static int dgram_show_line(char *line, const struct filter *f, int family)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0');
|
int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0');
|
||||||
|
|
||||||
if (!(f->states & (1 << state)))
|
if (!(f->states & (1 << state)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -2501,6 +2530,7 @@ static int udp_show(struct filter *f)
|
||||||
outerr:
|
outerr:
|
||||||
do {
|
do {
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
|
|
||||||
if (fp)
|
if (fp)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
|
|
@ -2536,6 +2566,7 @@ static int raw_show(struct filter *f)
|
||||||
outerr:
|
outerr:
|
||||||
do {
|
do {
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
|
|
||||||
if (fp)
|
if (fp)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
|
|
@ -2629,6 +2660,7 @@ static void unix_stats_print(struct sockstat *list, struct filter *f)
|
||||||
|
|
||||||
if (use_proc && f->f) {
|
if (use_proc && f->f) {
|
||||||
struct sockstat st;
|
struct sockstat st;
|
||||||
|
|
||||||
st.local.family = AF_UNIX;
|
st.local.family = AF_UNIX;
|
||||||
st.remote.family = AF_UNIX;
|
st.remote.family = AF_UNIX;
|
||||||
memcpy(st.local.data, &s->name, sizeof(s->name));
|
memcpy(st.local.data, &s->name, sizeof(s->name));
|
||||||
|
|
@ -2686,6 +2718,7 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
||||||
|
|
||||||
if (tb[UNIX_DIAG_RQLEN]) {
|
if (tb[UNIX_DIAG_RQLEN]) {
|
||||||
struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]);
|
struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]);
|
||||||
|
|
||||||
stat.rq = rql->udiag_rqueue;
|
stat.rq = rql->udiag_rqueue;
|
||||||
stat.wq = rql->udiag_wqueue;
|
stat.wq = rql->udiag_wqueue;
|
||||||
}
|
}
|
||||||
|
|
@ -2714,6 +2747,7 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
||||||
if (show_details) {
|
if (show_details) {
|
||||||
if (tb[UNIX_DIAG_SHUTDOWN]) {
|
if (tb[UNIX_DIAG_SHUTDOWN]) {
|
||||||
unsigned char mask;
|
unsigned char mask;
|
||||||
|
|
||||||
mask = *(__u8 *)RTA_DATA(tb[UNIX_DIAG_SHUTDOWN]);
|
mask = *(__u8 *)RTA_DATA(tb[UNIX_DIAG_SHUTDOWN]);
|
||||||
printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
|
printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
|
||||||
}
|
}
|
||||||
|
|
@ -2937,6 +2971,7 @@ static int packet_show_sock(const struct sockaddr_nl *addr,
|
||||||
|
|
||||||
if (tb[PACKET_DIAG_MEMINFO]) {
|
if (tb[PACKET_DIAG_MEMINFO]) {
|
||||||
__u32 *skmeminfo = RTA_DATA(tb[PACKET_DIAG_MEMINFO]);
|
__u32 *skmeminfo = RTA_DATA(tb[PACKET_DIAG_MEMINFO]);
|
||||||
|
|
||||||
stat.rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
|
stat.rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3100,12 +3135,13 @@ static int packet_show(struct filter *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int netlink_show_one(struct filter *f,
|
static int netlink_show_one(struct filter *f,
|
||||||
int prot, int pid, unsigned groups,
|
int prot, int pid, unsigned int groups,
|
||||||
int state, int dst_pid, unsigned dst_group,
|
int state, int dst_pid, unsigned int dst_group,
|
||||||
int rq, int wq,
|
int rq, int wq,
|
||||||
unsigned long long sk, unsigned long long cb)
|
unsigned long long sk, unsigned long long cb)
|
||||||
{
|
{
|
||||||
struct sockstat st;
|
struct sockstat st;
|
||||||
|
|
||||||
SPRINT_BUF(prot_buf) = {};
|
SPRINT_BUF(prot_buf) = {};
|
||||||
const char *prot_name;
|
const char *prot_name;
|
||||||
char procname[64] = {};
|
char procname[64] = {};
|
||||||
|
|
@ -3135,11 +3171,13 @@ static int netlink_show_one(struct filter *f,
|
||||||
procname[0] = '*';
|
procname[0] = '*';
|
||||||
} else if (resolve_services) {
|
} else if (resolve_services) {
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
done = 1;
|
done = 1;
|
||||||
strncpy(procname, "kernel", 6);
|
strncpy(procname, "kernel", 6);
|
||||||
} else if (pid > 0) {
|
} else if (pid > 0) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
snprintf(procname, sizeof(procname), "%s/%d/stat",
|
snprintf(procname, sizeof(procname), "%s/%d/stat",
|
||||||
getenv("PROC_ROOT") ? : "/proc", pid);
|
getenv("PROC_ROOT") ? : "/proc", pid);
|
||||||
if ((fp = fopen(procname, "r")) != NULL) {
|
if ((fp = fopen(procname, "r")) != NULL) {
|
||||||
|
|
@ -3163,6 +3201,7 @@ static int netlink_show_one(struct filter *f,
|
||||||
if (state == NETLINK_CONNECTED) {
|
if (state == NETLINK_CONNECTED) {
|
||||||
char dst_group_buf[30];
|
char dst_group_buf[30];
|
||||||
char dst_pid_buf[30];
|
char dst_pid_buf[30];
|
||||||
|
|
||||||
sock_addr_print(int_to_str(dst_group, dst_group_buf), ":",
|
sock_addr_print(int_to_str(dst_group, dst_group_buf), ":",
|
||||||
int_to_str(dst_pid, dst_pid_buf), NULL);
|
int_to_str(dst_pid, dst_pid_buf), NULL);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3170,6 +3209,7 @@ static int netlink_show_one(struct filter *f,
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pid_context = NULL;
|
char *pid_context = NULL;
|
||||||
|
|
||||||
if (show_proc_ctx) {
|
if (show_proc_ctx) {
|
||||||
/* The pid value will either be:
|
/* The pid value will either be:
|
||||||
* 0 if destination kernel - show kernel initial context.
|
* 0 if destination kernel - show kernel initial context.
|
||||||
|
|
@ -3215,6 +3255,7 @@ static int netlink_show_sock(const struct sockaddr_nl *addr,
|
||||||
|
|
||||||
if (tb[NETLINK_DIAG_MEMINFO]) {
|
if (tb[NETLINK_DIAG_MEMINFO]) {
|
||||||
const __u32 *skmeminfo;
|
const __u32 *skmeminfo;
|
||||||
|
|
||||||
skmeminfo = RTA_DATA(tb[NETLINK_DIAG_MEMINFO]);
|
skmeminfo = RTA_DATA(tb[NETLINK_DIAG_MEMINFO]);
|
||||||
|
|
||||||
rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
|
rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
|
||||||
|
|
@ -3252,7 +3293,7 @@ static int netlink_show(struct filter *f)
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
int prot, pid;
|
int prot, pid;
|
||||||
unsigned groups;
|
unsigned int groups;
|
||||||
int rq, wq, rc;
|
int rq, wq, rc;
|
||||||
unsigned long long sk, cb;
|
unsigned long long sk, cb;
|
||||||
|
|
||||||
|
|
@ -3340,8 +3381,7 @@ Exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct snmpstat
|
struct snmpstat {
|
||||||
{
|
|
||||||
int tcp_estab;
|
int tcp_estab;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -3360,6 +3400,7 @@ static int get_snmp_int(char *proto, char *key, int *result)
|
||||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
if (memcmp(buf, proto, protolen))
|
if (memcmp(buf, proto, protolen))
|
||||||
continue;
|
continue;
|
||||||
while ((p = strchr(p, ' ')) != NULL) {
|
while ((p = strchr(p, ' ')) != NULL) {
|
||||||
|
|
@ -3392,8 +3433,7 @@ static int get_snmp_int(char *proto, char *key, int *result)
|
||||||
|
|
||||||
/* Get stats from sockstat */
|
/* Get stats from sockstat */
|
||||||
|
|
||||||
struct ssummary
|
struct ssummary {
|
||||||
{
|
|
||||||
int socks;
|
int socks;
|
||||||
int tcp_mem;
|
int tcp_mem;
|
||||||
int tcp_total;
|
int tcp_total;
|
||||||
|
|
@ -3572,6 +3612,7 @@ static void usage(void)
|
||||||
static int scan_state(const char *state)
|
static int scan_state(const char *state)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (strcasecmp(state, "close") == 0 ||
|
if (strcasecmp(state, "close") == 0 ||
|
||||||
strcasecmp(state, "closed") == 0)
|
strcasecmp(state, "closed") == 0)
|
||||||
return (1<<SS_CLOSE);
|
return (1<<SS_CLOSE);
|
||||||
|
|
@ -3729,6 +3770,7 @@ int main(int argc, char *argv[])
|
||||||
case 'A':
|
case 'A':
|
||||||
{
|
{
|
||||||
char *p, *p1;
|
char *p, *p1;
|
||||||
|
|
||||||
if (!saw_query) {
|
if (!saw_query) {
|
||||||
current_filter.dbs = 0;
|
current_filter.dbs = 0;
|
||||||
state_filter = state_filter ?
|
state_filter = state_filter ?
|
||||||
|
|
@ -3893,6 +3935,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (dump_tcpdiag) {
|
if (dump_tcpdiag) {
|
||||||
FILE *dump_fp = stdout;
|
FILE *dump_fp = stdout;
|
||||||
|
|
||||||
if (!(current_filter.dbs & (1<<TCP_DB))) {
|
if (!(current_filter.dbs & (1<<TCP_DB))) {
|
||||||
fprintf(stderr, "ss: tcpdiag dump requested and no tcp in filter.\n");
|
fprintf(stderr, "ss: tcpdiag dump requested and no tcp in filter.\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue