X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=interface.c;h=f9445cb8aba1a01948dc50beb25aed0445146ae3;hb=adad2fc62f159c7e43c36af0ad4f9bf9f6b3efc7;hp=0df520f9af5852bfc8129a752a51719a6a8b0b24;hpb=a30740affdb9342dee394ffdc77591ec9bc75ae7;p=~andy%2Ffetchmail diff --git a/interface.c b/interface.c index 0df520f9..f9445cb8 100644 --- a/interface.c +++ b/interface.c @@ -9,24 +9,23 @@ * FreeBSD specific portions written by and Copyright (c) 1999 * Andy Doran . * - * This is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation; version 2, or (at your option) any later version. + * For license terms, see the file COPYING in this directory. */ + +#include "fetchmail.h" +#ifdef CAN_MONITOR + #include #include -#if (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__) +#if defined(linux) +#include +#endif -#include "config.h" #include #include -#if defined(STDC_HEADERS) #include -#endif -#if defined(HAVE_UNISTD_H) #include -#endif #include #include #include @@ -34,22 +33,18 @@ #include #if defined(__FreeBSD__) #if defined __FreeBSD_USE_KVM - #if __FreeBSD_version >= 300001 - #include - #endif - #include - #include - #include -#else - #include - #include - #include -#endif -#endif -#include "config.h" -#include "fetchmail.h" +#include +#include +#include +#include +#else /* !defined __FreeBSD_USE_KVM */ +#include +#include +#include +#endif /* defined __FreeBSD_USE_KVM */ +#endif /* defined __FreeBSD__ */ #include "socket.h" -#include "i18n.h" +#include "gettext.h" #include "tunable.h" typedef struct { @@ -62,8 +57,6 @@ struct interface_pair_s { struct in_addr interface_mask; } *interface_pair; -static char *netdevfmt; - /* * Count of packets to see on an interface before monitor considers it up. * Needed because when pppd shuts down the link, the packet counts go up @@ -72,31 +65,33 @@ static char *netdevfmt; */ #define MONITOR_SLOP 5 -#if defined(linux) +#ifdef linux +#define have_interface_init + +static const char *netdevfmt; void interface_init(void) -/* figure out which /proc/dev/net format to use */ +/* figure out which /proc/net/dev format to use */ { - FILE *fp = popen("uname -r", "r"); /* still wins if /proc is out */ + struct utsname utsname; - /* pre-linux-2.2 format -- transmit packet count in 8th field */ - netdevfmt = "%d %d %*d %*d %*d %d %*d %d %*d %*d %*d %*d %d"; + /* Linux 2.2 -- transmit packet count in 10th field */ + netdevfmt = "%d %d %*d %*d %*d %d %*d %*d %*d %d %*d %*d %d"; - if (!fp) - return; + if (uname(&utsname) < 0) + return; else { int major, minor; - if (fscanf(fp, "%d.%d.%*d", &major, &minor) >= 2 - && major >= 2 && minor >= 2) - /* Linux 2.2 -- transmit packet count in 10th field */ - netdevfmt = "%d %d %*d %*d %*d %d %*d %*d %*d %d %*d %*d %d"; - pclose(fp); + if (sscanf(utsname.release, "%d.%d.%*d", &major, &minor) >= 2 + && (major < 2 || (major == 2 && minor < 2))) + /* pre-linux-2.2 format -- transmit packet count in 8th field */ + netdevfmt = "%d %d %*d %*d %*d %d %*d %d %*d %*d %*d %*d %d"; } } -static int _get_ifinfo_(int socket_fd, FILE *stats_file, const char *ifname, +static int _get_ifinfoGT_(int socket_fd, FILE *stats_file, const char *ifname, ifinfo_t *ifinfo) /* get active network interface information - return non-zero upon success */ { @@ -172,16 +167,16 @@ static int get_ifinfo(const char *ifname, ifinfo_t *ifinfo) result = FALSE; else { - char *sp = strchr(ifname, '/'); - + char *tmp = xstrdup(ifname); + char *sp = strchr(tmp, '/'); + /* hide slash and trailing info from ifname */ if (sp) *sp = '\0'; - result = _get_ifinfo_(socket_fd, stats_file, ifname, ifinfo); - if (sp) - *sp = '/'; + result = _get_ifinfoGT_(socket_fd, stats_file, tmp, ifinfo); + free(tmp); } if (socket_fd >= 0) - SockClose(close(socket_fd)); + SockClose(socket_fd); if (stats_file) fclose(stats_file); /* not checking should be safe, mode was "r" */ return(result); @@ -226,24 +221,21 @@ openkvm(void) static int get_ifinfo(const char *ifname, ifinfo_t *ifinfo) { - char tname[16]; + char tname[16]; char iname[16]; - struct ifnet ifnet; + struct ifnet ifnet; unsigned long ifnet_addr = ifnet_savedaddr; -#if __FreeBSD_version >= 300001 struct ifnethead ifnethead; struct ifaddrhead ifaddrhead; -#endif struct ifaddr ifaddr; unsigned long ifaddr_addr; struct sockaddr sa; - unsigned long sa_addr; uint i; if (if_egid) setegid(if_egid); - for (i = 0; ifname[i] && ifname[i] != '/'; i++) + for (i = 0; ifname[i] && ifname[i] != '/' && i < sizeof(iname) - 1; i++) iname[i] = ifname[i]; iname[i] = '\0'; @@ -252,25 +244,21 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) { if (!openkvm()) { - report(stderr, 0, _("Unable to open kvm interface. Make sure fetchmail is SGID kmem.")); + report(stderr, 0, GT_("Unable to open kvm interface. Make sure fetchmail is SGID kmem.")); if (if_egid) setegid(if_rgid); exit(1); } } -#if __FreeBSD_version >= 300001 kvm_read(kvmfd, ifnet_savedaddr, (char *) &ifnethead, sizeof ifnethead); ifnet_addr = (u_long) ifnethead.tqh_first; -#else - ifnet_addr = ifnet_savedaddr; -#endif while (ifnet_addr) { kvm_read(kvmfd, ifnet_addr, &ifnet, sizeof(ifnet)); kvm_read(kvmfd, (unsigned long) ifnet.if_name, tname, sizeof tname); - snprintf(tname, sizeof tname - 1, "%s%d", tname, ifnet.if_unit); + snprintf(tname + strlen(tname), sizeof(tname) - strlen(tname), "%d", ifnet.if_unit); if (!strcmp(tname, iname)) { @@ -284,11 +272,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) ifinfo->rx_packets = ifnet.if_ipackets; ifinfo->tx_packets = ifnet.if_opackets; -#if __FreeBSD_version >= 300001 ifaddr_addr = (u_long) ifnet.if_addrhead.tqh_first; -#else - ifaddr_addr = (u_long) ifnet.if_addrlist; -#endif while(ifaddr_addr) { @@ -297,11 +281,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) if (sa.sa_family != AF_INET) { -#if __FreeBSD_version >= 300001 ifaddr_addr = (u_long) ifaddr.ifa_link.tqe_next; -#else - ifaddr_addr = (u_long) ifaddr.ifa_next; -#endif continue; } @@ -323,11 +303,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) return 0; } -#if __FreeBSD_version >= 300001 ifnet_addr = (u_long) ifnet.if_link.tqe_next; -#else - ifnet_addr = (unsigned long) ifnet.if_next; -#endif } if (if_egid) @@ -383,7 +359,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) char iname[16]; int mib[6]; - memset(ifinfo, 0, sizeof(ifinfo)); + memset(ifinfo, 0, sizeof(*ifinfo)); /* trim interface name */ @@ -392,7 +368,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) if (i == 0 || i == sizeof(iname)) { - report(stderr, _("Unable to parse interface name from %s"), ifname); + report(stderr, GT_("Unable to parse interface name from %s"), ifname); return 0; } @@ -414,19 +390,19 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) { report(stderr, - _("get_ifinfo: sysctl (iflist estimate) failed")); + GT_("get_ifinfo: sysctl (iflist estimate) failed")); exit(1); } - if ((buf = malloc(needed)) == NULL) + if ((buf = (char *)malloc(needed)) == NULL) { report(stderr, - _("get_ifinfo: malloc failed")); + GT_("get_ifinfo: malloc failed")); exit(1); } if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) { report(stderr, - _("get_ifinfo: sysctl (iflist) failed")); + GT_("get_ifinfo: sysctl (iflist) failed")); exit(1); } @@ -444,7 +420,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) if (ifm->ifm_version != RTM_VERSION) { report(stderr, - _("Routing message version %d not understood."), + GT_("Routing message version %d not understood."), ifm->ifm_version); exit(1); } @@ -476,7 +452,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) if (ifindex < 0) { /* we did not find an interface with a matching name */ - report(stderr, _("No interface found with name %s"), iname); + report(stderr, GT_("No interface found with name %s"), iname); goto get_ifinfo_end; } @@ -513,7 +489,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) } sin = (struct sockaddr_in *)info.rti_info[RTAX_NETMASK]; - if (!sin) + if (sin) { ifinfo->netmask = sin->sin_addr; } @@ -523,7 +499,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) * of non point-to-point link */ sin = (struct sockaddr_in *)info.rti_info[RTAX_BRD]; - if (!sin) + if (sin) { ifinfo->dstaddr = sin->sin_addr; } @@ -534,7 +510,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) if (rc == 0) { - report(stderr, _("No IP address found for %s"), iname); + report(stderr, GT_("No IP address found for %s"), iname); } get_ifinfo_end: @@ -544,8 +520,7 @@ get_ifinfo_end: #endif /* __FREEBSD_USE_SYSCTL_GET_IFFINFO */ -#endif /* defined __FreeBSD__ */ - +#endif #ifndef HAVE_INET_ATON /* @@ -579,6 +554,7 @@ void interface_parse(char *buf, struct hostdata *hp) /* parse 'interface' specification */ { char *cp1, *cp2; + char mask1[] = "255.255.255.255"; hp->interface = xstrdup(buf); @@ -586,14 +562,14 @@ void interface_parse(char *buf, struct hostdata *hp) if (!(cp1 = strchr(buf, '/'))) { (void) report(stderr, - _("missing IP interface address\n")); + GT_("missing IP interface address\n")); exit(PS_SYNTAX); } *cp1++ = '\000'; /* find and isolate just the netmask */ if (!(cp2 = strchr(cp1, '/'))) - cp2 = "255.255.255.255"; + cp2 = mask1; else *cp2++ = '\000'; @@ -602,13 +578,13 @@ void interface_parse(char *buf, struct hostdata *hp) if (!inet_aton(cp1, &hp->interface_pair->interface_address)) { (void) report(stderr, - _("invalid IP interface address\n")); + GT_("invalid IP interface address\n")); exit(PS_SYNTAX); } if (!inet_aton(cp2, &hp->interface_pair->interface_mask)) { (void) report(stderr, - _("invalid IP interface mask\n")); + GT_("invalid IP interface mask\n")); exit(PS_SYNTAX); } /* apply the mask now to the IP address (range) required */ @@ -647,7 +623,7 @@ void interface_note_activity(struct hostdata *hp) #ifdef ACTIVITY_DEBUG (void) report(stdout, - _("activity on %s -noted- as %d\n"), + GT_("activity on %s -noted- as %d\n"), hp->monitor, hp->monitor_io); #endif } @@ -662,7 +638,7 @@ int interface_approve(struct hostdata *hp, flag domonitor) /* get interface info */ if (!get_ifinfo(hp->interface, &ifinfo)) { (void) report(stdout, - _("skipping poll of %s, %s down\n"), + GT_("skipping poll of %s, %s down\n"), hp->pollname, hp->interface); return(FALSE); } @@ -681,7 +657,7 @@ int interface_approve(struct hostdata *hp, flag domonitor) ) ) { (void) report(stdout, - _("skipping poll of %s, %s IP address excluded\n"), + GT_("skipping poll of %s, %s IP address excluded\n"), hp->pollname, hp->interface); return(FALSE); } @@ -693,7 +669,7 @@ int interface_approve(struct hostdata *hp, flag domonitor) #ifdef ACTIVITY_DEBUG (void) report(stdout, - _("activity on %s checked as %d\n"), + GT_("activity on %s checked as %d\n"), hp->monitor, hp->monitor_io); #endif /* if monitoring, check link for activity if it is up */ @@ -719,18 +695,22 @@ int interface_approve(struct hostdata *hp, flag domonitor) if (diff >= 0 && diff <= MONITOR_SLOP) { (void) report(stdout, - _("skipping poll of %s, %s inactive\n"), + GT_("skipping poll of %s, %s inactive\n"), hp->pollname, hp->monitor); return(FALSE); } } #ifdef ACTIVITY_DEBUG - report(stdout, _("activity on %s was %d, is %d\n"), + report(stdout, GT_("activity on %s was %d, is %d\n"), hp->monitor, hp->monitor_io, ifinfo.rx_packets + ifinfo.tx_packets); #endif return(TRUE); } -#endif /* (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__) */ +#endif /* CAN_MONITOR */ + +#ifndef have_interface_init +void interface_init(void) {} +#endif