From 8fd27c0026f5ffd6cea68fda876fbbed7e2a73b3 Mon Sep 17 00:00:00 2001 From: Phil Date: Sat, 22 Mar 2008 19:06:09 +0000 Subject: [PATCH] make default gateway information accessible * gw_iface prints the interface having a default gateway * gw_ip prints the gatway's ip * if_gw jumps if no default gateway exists * when there are multiple gateways, gw_iface and gw_ip only print "multiple" when they are different (allows basic debugging of ones networking setup) git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@1031 7f574dfc-610e-0410-a909-a81674777703 --- doc/conky.1 | 12 ++++++++++ doc/variables.xml | 27 ++++++++++++++++++++++ src/common.c | 3 +++ src/conky.c | 41 +++++++++++++++++++++++++++++++++ src/conky.h | 10 ++++++++ src/linux.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+) diff --git a/doc/conky.1 b/doc/conky.1 index 103443a7..1ecf54ca 100644 --- a/doc/conky.1 +++ b/doc/conky.1 @@ -756,6 +756,14 @@ File system used space \fB\*(T<\fBgoto\fR\*(T>\fR \*(T<\fBx\fR\*(T> The next element will be printed at position 'x'. +.TP +\fB\*(T<\fBgw_iface\fR\*(T>\fR +Displays the default route's interface or "multiple"/"none" accordingly. + +.TP +\fB\*(T<\fBgw_ip\fR\*(T>\fR +Displays the default gateway's IP or "multiple"/"none" accordingly. + .TP \fB\*(T<\fBhddtemp\fR\*(T>\fR \*(T<\fBdev, (host,(port))\fR\*(T> Displays temperature of a selected hard disk drive as reported by the hddtemp daemon running on host:port. @@ -861,6 +869,10 @@ if PROCESS is running, display everything $if_running and the matching $endif \fB\*(T<\fBif_existing\fR\*(T>\fR \*(T<\fBfile (string)\fR\*(T> if FILE exists, display everything between if_existing and the matching $endif. The optional second paramater checks for FILE containing the specified string and prints everything between $if_existing and the matching $endif. +.TP +\fB\*(T<\fBif_gw\fR\*(T>\fR +if at least one default gateway exists, display everything between $if_gw and the matching $endif + .TP \fB\*(T<\fBif_mounted\fR\*(T>\fR \*(T<\fB(mountpoint)\fR\*(T> if MOUNTPOINT is mounted, display everything between $if_mounted and the matching $endif diff --git a/doc/variables.xml b/doc/variables.xml index dbd7ade6..7a45988d 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -839,6 +839,24 @@ + + + + + + Displays the default route's interface or "multiple"/"none" accordingly. + + + + + + + + + Displays the default gateway's IP or "multiple"/"none" accordingly. + + + @@ -1071,6 +1089,15 @@ + + + + + + if there is at least one default gateway, display everything between $if_gw and the matching $endif + + + diff --git a/src/common.c b/src/common.c index 2893a4fc..c783d6be 100644 --- a/src/common.c +++ b/src/common.c @@ -311,6 +311,9 @@ void update_stuff() if (NEED(INFO_USERS)) { update_users(); } + if (NEED(INFO_GW)) { + update_gateway_info(); + } } int round_to_int(float f) diff --git a/src/conky.c b/src/conky.c index c72c0f77..29273851 100644 --- a/src/conky.c +++ b/src/conky.c @@ -1144,6 +1144,9 @@ enum text_object_type { OBJ_ibm_volume, OBJ_ibm_brightness, OBJ_if_up, + OBJ_if_gw, + OBJ_gw_iface, + OBJ_gw_ip, OBJ_pb_battery, OBJ_voltage_mv, OBJ_voltage_v, @@ -2047,6 +2050,20 @@ static void free_text_objects(unsigned int count, struct text_object *objs) free(objs[i].data.ifblock.s); free(objs[i].data.ifblock.str); break; + case OBJ_if_gw: + free(objs[i].data.ifblock.s); + free(objs[i].data.ifblock.str); + case OBJ_gw_iface: + case OBJ_gw_ip: + if (info.gw_info.iface) { + free(info.gw_info.iface); + info.gw_info.iface = 0; + } + if (info.gw_info.ip) { + free(info.gw_info.ip); + info.gw_info.ip = 0; + } + break; #endif #ifdef XMMS2 case OBJ_xmms2_artist: @@ -2452,6 +2469,13 @@ static struct text_object *construct_text_object(const char *s, blockstart[blockdepth] = object_count; obj->data.ifblock.pos = object_count + 2; blockdepth++; + END OBJ(if_gw, 0) + if (blockdepth >= MAX_IF_BLOCK_DEPTH) { + CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded"); + } + blockstart[blockdepth] = object_count; + obj->data.ifblock.pos = object_count + 2; + blockdepth++; END OBJ(pb_battery, 0) if (arg && strcmp(arg, "status") == 0) { obj->data.i = PB_BATT_STATUS; @@ -3455,6 +3479,9 @@ static struct text_object *construct_text_object(const char *s, END OBJ(user_times, INFO_USERS) END OBJ(user_terms, INFO_USERS) END OBJ(user_number, INFO_USERS) + END OBJ(gw_iface, INFO_GW) + END OBJ(gw_ip, INFO_GW) + END OBJ(if_gw, INFO_GW) #ifndef __OpenBSD__ END OBJ(adt746xcpu, 0) END OBJ(adt746xfan, 0) @@ -4387,6 +4414,20 @@ static void generate_text_internal(char *p, int p_max_size, if_jumped = 0; } } + OBJ(if_gw) { + if (!cur->gw_info.count) { + i = obj->data.ifblock.pos; + if_jumped = 1; + } else { + if_jumped = 0; + } + } + OBJ(gw_iface) { + snprintf(p, p_max_size, "%s", cur->gw_info.iface); + } + OBJ(gw_ip) { + snprintf(p, p_max_size, "%s", cur->gw_info.ip); + } OBJ(pb_battery) { get_powerbook_batt_info(p, p_max_size, obj->data.i); } diff --git a/src/conky.h b/src/conky.h index 3347fdb0..85e191c4 100644 --- a/src/conky.h +++ b/src/conky.h @@ -252,6 +252,12 @@ struct usr_info { int number; }; +struct gateway_info { + char *iface; + char *ip; + int count; +}; + #ifdef TCP_PORT_MONITOR #include "libtcp-portmon.h" #define MAX_PORT_MONITOR_CONNECTIONS_DEFAULT 256 @@ -299,6 +305,7 @@ enum { INFO_SMAPI = 25, #endif INFO_USERS = 26, + INFO_GW = 27 }; /* get_battery_stuff() item selector */ @@ -361,6 +368,7 @@ struct information { struct bmpx_s bmpx; #endif struct usr_info users; + struct gateway_info gw_info; struct process *cpu[10]; struct process *memu[10]; struct process *first_process; @@ -537,6 +545,8 @@ char get_voltage(char *, size_t, char *, int, unsigned int); /* ptarjan */ void update_load_average(); int interface_up(const char *dev); +void update_gateway_info(void); + int open_sysfs_sensor(const char *dir, const char *dev, const char *type, int n, int *div, char *devtype); diff --git a/src/linux.c b/src/linux.c index a6eb0cc1..64a25425 100644 --- a/src/linux.c +++ b/src/linux.c @@ -51,6 +51,8 @@ #include #include #include +#include +#include #include #ifdef HAVE_IWLIB @@ -188,6 +190,62 @@ int interface_up(const char *dev) return 0; } +#define COND_FREE(x) if(x) free(x); x = 0 +#define SAVE_SET_STRING(x, y) \ + if (x && strcmp((char *)x, (char *)y)) { \ + free(x); \ + x = strdup("multiple"); \ + } else if (!x) { \ + x = strdup(y); \ + } + +void update_gateway_info() +{ + FILE *fp; + struct in_addr ina; + char iface[64]; + unsigned long dest, gate, mask; + unsigned int flags; + short ref, use, metric, mtu, win, irtt; + + struct gateway_info *gw_info = &info.gw_info; + + COND_FREE(gw_info->iface); + COND_FREE(gw_info->ip); + gw_info->count = 0; + + if ((fp = fopen("/proc/net/route", "r")) == NULL) { + perror("fopen()"); + goto FAIL; + } + if (fscanf(fp, "%*[^\n]\n") == EOF) { + perror("fscanf()"); + goto CLOSE_FAIL; + } + while (!feof(fp)) { + // Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT + if(fscanf(fp, "%63s %lx %lx %x %hd %hd %hd %lx %hd %hd %hd\n", + iface, &dest, &gate, &flags, &ref, &use, + &metric, &mask, &mtu, &win, &irtt) != 11) { + perror("fscanf()"); + goto CLOSE_FAIL; + } + if (flags & RTF_GATEWAY && dest == 0 && mask == 0) { + gw_info->count++; + SAVE_SET_STRING(gw_info->iface, iface) + ina.s_addr = gate; + SAVE_SET_STRING(gw_info->ip, inet_ntoa(ina)) + } + } + fclose(fp); + return; +CLOSE_FAIL: + fclose(fp); +FAIL: + info.gw_info.iface = info.gw_info.ip = strdup("failed"); + return; +} + inline void update_net_stats() { FILE *net_dev_fp;