[packages/apinger] - add srcip option to target configuration, allows specifying source ip used to monitor target
hawk
hawk at pld-linux.org
Thu Jul 26 11:27:56 CEST 2012
commit c3818ac3f72ca34aede34b60010682b0af20549f
Author: Marcin Krol <hawk at tld-linux.org>
Date: Thu Jul 26 09:28:02 2012 +0000
- add srcip option to target configuration, allows specifying source ip
used to monitor target
apinger-srcip.patch | 520 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 520 insertions(+)
---
diff --git a/apinger-srcip.patch b/apinger-srcip.patch
new file mode 100644
index 0000000..68fc916
--- /dev/null
+++ b/apinger-srcip.patch
@@ -0,0 +1,520 @@
+diff -ur apinger-0.6.1.orig//src/apinger.c apinger-0.6.1/src/apinger.c
+--- apinger-0.6.1.orig//src/apinger.c 2012-07-25 17:46:59.421182293 +0000
++++ apinger-0.6.1/src/apinger.c 2012-07-25 17:44:41.642064536 +0000
+@@ -646,7 +646,7 @@
+ struct target *t,*pt,*nt;
+ struct target_cfg *tc;
+ struct active_alarm_list *al,*nal;
+-union addr addr;
++union addr addr, srcaddr;
+ int r;
+ int l;
+
+@@ -666,6 +666,8 @@
+ nal=al->next;
+ free(al);
+ }
++ if (t->socket)
++ close(t->socket);
+ free(t->queue);
+ free(t->rbuf);
+ free(t->name);
+@@ -684,11 +686,6 @@
+ memset(&addr,0,sizeof(addr));
+ r=inet_pton(AF_INET,tc->name,&addr.addr4.sin_addr);
+ if (r){
+- if (icmp_sock<0){
+- logit("Sorry, IPv4 is not available\n");
+- logit("Ignoring target %s\n",tc->name);
+- continue;
+- }
+ addr.addr.sa_family=AF_INET;
+ }else{
+ #ifdef HAVE_IPV6
+@@ -708,12 +705,38 @@
+ addr.addr.sa_family=AF_INET6;
+ #endif
+ }
++ memset(&srcaddr,0,sizeof(srcaddr));
++ debug("Converting srcip %s", tc->srcip);
++ r=inet_pton(AF_INET,tc->srcip,&srcaddr.addr4.sin_addr);
++ if (r){
++ srcaddr.addr.sa_family=AF_INET;
++ }else{
++#ifdef HAVE_IPV6
++ r=inet_pton(AF_INET6,tc->srcip,&srcaddr.addr6.sin6_addr);
++ if (r==0){
++#endif
++ logit("Bad srcip address %s for target %s\n", tc->srcip, tc->name);
++ logit("Ignoring target %s\n",tc->name);
++ continue;
++#ifdef HAVE_IPV6
++ }
++ if (icmp6_sock<0){
++ logit("Sorry, IPv6 is not available\n");
++ logit("Ignoring target %s\n",tc->name);
++ continue;
++ }
++ srcaddr.addr.sa_family=AF_INET6;
++#endif
++ }
+ t=NEW(struct target,1);
+ memset(t,0,sizeof(struct target));
+ t->name=strdup(tc->name);
+ t->description=strdup(tc->description);
+ t->addr=addr;
++ t->ifaddr=srcaddr;
+ t->next=targets;
++ if(t->addr.addr.sa_family==AF_INET) make_icmp_socket(t);
++ if(t->addr.addr.sa_family==AF_INET6) make_icmp6_socket(t);
+ targets=t;
+ }
+ t->config=tc;
+@@ -733,6 +756,7 @@
+ assert(t->rbuf!=NULL);
+ memset(t->rbuf,0,l);
+ }
++
+ if (targets==NULL){
+ logit("No usable targets found, exiting");
+ exit(1);
+@@ -753,6 +777,8 @@
+ nal=al->next;
+ free(al);
+ }
++ if (t->socket)
++ close(t->socket);
+ free(t->queue);
+ free(t->rbuf);
+ free(t->name);
+@@ -865,7 +891,7 @@
+ void main_loop(void){
+ struct target *t;
+ struct timeval cur_time,next_status={0,0},tv,next_report={0,0},next_rrd_update={0,0};
+-struct pollfd pfd[2];
++struct pollfd pfd[1024];
+ int timeout;
+ int npfd=0;
+ int i;
+@@ -876,16 +902,8 @@
+ struct alarm_cfg *a;
+
+ configure_targets();
+- if (icmp_sock){
+- pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
+- pfd[npfd].revents=0;
+- pfd[npfd++].fd=icmp_sock;
+- }
+- if (icmp6_sock){
+- pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
+- pfd[npfd++].fd=icmp6_sock;
+- pfd[npfd].revents=0;
+- }
++ memset(&pfd, '\0', sizeof pfd);
++
+ if (config->status_interval){
+ gettimeofday(&cur_time,NULL);
+ tv.tv_sec=config->status_interval/1000;
+@@ -893,10 +911,16 @@
+ timeradd(&cur_time,&tv,&next_status);
+ }
+ while(!interrupted_by){
++ npfd = 0;
+ gettimeofday(&cur_time,NULL);
+ if ( !timercmp(&next_probe,&cur_time,>) )
+ timerclear(&next_probe);
+ for(t=targets;t;t=t->next){
++ if (t->socket){
++ pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
++ pfd[npfd].revents=0;
++ pfd[npfd++].fd=t->socket;
++ }
+ for(al=t->config->alarms;al;al=nal){
+ a=al->alarm;
+ nal=al->next;
+@@ -972,8 +996,20 @@
+ poll(pfd,npfd,timeout);
+ for(i=0;i<npfd;i++){
+ if (!pfd[i].revents&POLLIN) continue;
+- if (pfd[i].fd==icmp_sock) recv_icmp();
+- else if (pfd[i].fd==icmp6_sock) recv_icmp6();
++ for(t=targets;t;t=t->next){
++ if (t->addr.addr.sa_family==AF_INET) {
++ if (t->socket == pfd[i].fd) {
++ recv_icmp(t);
++ break;
++ }
++ }
++ if (t->addr.addr.sa_family==AF_INET6) {
++ if (t->socket == pfd[i].fd) {
++ recv_icmp6(t);
++ break;
++ }
++ }
++ }
+ pfd[i].revents=0;
+ }
+ if (status_request){
+diff -ur apinger-0.6.1.orig//src/apinger.h apinger-0.6.1/src/apinger.h
+--- apinger-0.6.1.orig//src/apinger.h 2012-07-25 17:46:59.422189729 +0000
++++ apinger-0.6.1/src/apinger.h 2012-07-25 17:44:41.642064536 +0000
+@@ -47,6 +47,8 @@
+ #endif
+ #include "conf.h"
+
++#include <ifaddrs.h>
++
+ union addr {
+ struct sockaddr addr;
+ struct sockaddr_in addr4;
+@@ -67,10 +69,11 @@
+ char *description; /* description */
+
+ union addr addr; /* target address */
+-
++
+ char *queue; /*
+ contains info about recently sent packets
+ "1" means it was received */
++ int socket;
+ int last_sent; /* sequence number of the last ping sent */
+ int last_received; /* sequence number of the last ping received */
+ struct timeval last_received_tv; /* timestamp of the last ping received */
+@@ -90,6 +93,7 @@
+ struct target_cfg *config;
+
+ struct target *next;
++ union addr ifaddr; /* iface address */
+ };
+
+ #define AVG_DELAY_KNOWN(t) (t->upsent >= t->config->avg_delay_samples)
+@@ -111,16 +115,16 @@
+
+ extern int icmp_sock;
+ extern int icmp6_sock;
+-extern int ident;
++extern uint16_t ident;
+
+ extern struct timeval next_probe;
+
+-int make_icmp_socket(void);
+-void recv_icmp(void);
++int make_icmp_socket(struct target *t);
++void recv_icmp(struct target *t);
+ void send_icmp_probe(struct target *t,int seq);
+
+-int make_icmp6_socket(void);
+-void recv_icmp6(void);
++int make_icmp6_socket(struct target *t);
++void recv_icmp6(struct target *t);
+ void send_icmp6_probe(struct target *t,int seq);
+
+ void analyze_reply(struct timeval time_recv,int seq,struct trace_info *ti);
+diff -ur apinger-0.6.1.orig//src/cfgparser1.y apinger-0.6.1/src/cfgparser1.y
+--- apinger-0.6.1.orig//src/cfgparser1.y 2003-03-26 11:27:47.000000000 +0000
++++ apinger-0.6.1/src/cfgparser1.y 2012-07-25 17:44:41.643063909 +0000
+@@ -97,6 +97,7 @@
+ %token DELAY_HIGH
+
+ %token DESCRIPTION
++%token SRCIP
+ %token ALARMS
+ %token INTERVAL
+ %token AVG_DELAY_SAMPLES
+@@ -248,6 +249,8 @@
+ targetcfg: /* */
+ | DESCRIPTION string
+ { cur_target->description=$2; }
++ | SRCIP string
++ { cur_target->srcip = $2; }
+ | ALARMS alarmlist
+ { cur_target->alarms=$2; }
+ | ALARMS OVERRIDE alarmlist
+diff -ur apinger-0.6.1.orig//src/cfgparser2.l apinger-0.6.1/src/cfgparser2.l
+--- apinger-0.6.1.orig//src/cfgparser2.l 2003-03-26 11:27:47.000000000 +0000
++++ apinger-0.6.1/src/cfgparser2.l 2012-07-25 17:44:41.643063909 +0000
+@@ -82,6 +82,7 @@
+ delay_high { LOC; LOCINC; return DELAY_HIGH; }
+ delay_low { LOC; LOCINC; return DELAY_LOW; }
+ description { LOC; LOCINC; return DESCRIPTION; }
++srcip { LOC; LOCINC; return SRCIP; }
+ down { LOC; LOCINC; return DOWN; }
+ false { LOC; LOCINC; return FALSE; }
+ file { LOC; LOCINC; return FILE_; }
+diff -ur apinger-0.6.1.orig//src/conf.h apinger-0.6.1/src/conf.h
+--- apinger-0.6.1.orig//src/conf.h 2003-03-26 11:27:47.000000000 +0000
++++ apinger-0.6.1/src/conf.h 2012-07-25 17:44:41.643063909 +0000
+@@ -72,6 +72,7 @@
+ struct target_cfg {
+ char *name;
+ char *description;
++ char *srcip;
+ int interval;
+ int avg_delay_samples;
+ int avg_loss_delay_samples;
+diff -ur apinger-0.6.1.orig//src/icmp.c apinger-0.6.1/src/icmp.c
+--- apinger-0.6.1.orig//src/icmp.c 2012-07-25 17:46:59.422189729 +0000
++++ apinger-0.6.1/src/icmp.c 2012-07-25 17:44:41.644063862 +0000
+@@ -151,14 +151,14 @@
+ size=sizeof(*p)+sizeof(ti);
+
+ p->icmp_cksum = in_cksum((u_short *)p,size,0);
+- ret=sendto(icmp_sock,p,size,MSG_DONTWAIT,
++ ret=sendto(t->socket,p,size,MSG_DONTWAIT,
+ (struct sockaddr *)&t->addr.addr4,sizeof(t->addr.addr4));
+ if (ret<0){
+ if (config->debug) myperror("sendto");
+ }
+ }
+
+-void recv_icmp(void){
++void recv_icmp(struct target *t){
+ int len,hlen,icmplen,datalen;
+ char buf[1024];
+ struct sockaddr_in from;
+@@ -171,6 +171,7 @@
+ struct iovec iov;
+ struct msghdr msg;
+ struct cmsghdr *c;
++reloophack:
+
+ iov.iov_base=buf;
+ iov.iov_len=1000;
+@@ -180,12 +181,13 @@
+ msg.msg_iovlen=1;
+ msg.msg_control=ans_data;
+ msg.msg_controllen=sizeof(ans_data);
+- len=recvmsg(icmp_sock, &msg, MSG_DONTWAIT);
++ len=recvmsg(t->socket, &msg, MSG_DONTWAIT);
+ #else
+ socklen_t sl;
++reloophack:
+
+ sl=sizeof(from);
+- len=recvfrom(icmp_sock,buf,1024,MSG_DONTWAIT,(struct sockaddr *)&from,&sl);
++ len=recvfrom(t->socket,buf,1024,MSG_DONTWAIT,(struct sockaddr *)&from,&sl);
+ #endif
+ if (len<0){
+ if (errno==EAGAIN) return;
+@@ -197,7 +199,7 @@
+ debug("checking CMSG...");
+ for (c = CMSG_FIRSTHDR(&msg); c; c = CMSG_NXTHDR(&msg, c)) {
+ debug("CMSG level: %i type: %i",c->cmsg_level,c->cmsg_type);
+- if (c->cmsg_level != SOL_SOCKET || c->cmsg_type != SO_TIMESTAMP)
++ if (c->cmsg_level != SOL_SOCKET || c->cmsg_type != SCM_TIMESTAMP)
+ continue;
+ if (c->cmsg_len < CMSG_LEN(sizeof(struct timeval)))
+ continue;
+@@ -207,7 +209,7 @@
+ #endif
+ if (time_recvp==NULL){
+ #ifdef SIOCGSTAMP
+- if (!ioctl(icmp_sock, SIOCGSTAMP, &time_recv)){
++ if (!ioctl(t->socket, SIOCGSTAMP, &time_recv)){
+ debug("Got timestampt from ioctl()");
+ }else
+ #endif
+@@ -227,7 +229,8 @@
+ return;
+ }
+ if (icmp->icmp_id != ident){
+- debug("Alien echo-reply received");
++ debug("Alien echo-reply received from %s. Expected %i, received %i",inet_ntoa(from.sin_addr), ident, icmp->icmp_id);
++ goto reloophack;
+ return;
+ }
+ debug("Ping reply from %s",inet_ntoa(from.sin_addr));
+@@ -239,19 +242,23 @@
+ analyze_reply(*time_recvp,icmp->icmp_seq,(struct trace_info*)(icmp+1));
+ }
+
+-int make_icmp_socket(void){
++int make_icmp_socket(struct target *t){
+ int on;
+
+- icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+- if (icmp_sock<0)
++ t->socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
++ if (t->socket < 0)
+ myperror("socket");
+ #ifdef SO_TIMESTAMP
+- else{
++ else {
+ on=1;
+- if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
++ if (setsockopt(t->socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
+ myperror("setsockopt(SO_TIMESTAMP)");
+ }
+ #endif
+- return icmp_sock;
++
++ if (bind(t->socket, (struct sockaddr *)&t->ifaddr.addr4, sizeof(t->ifaddr.addr4)) < 0)
++ myperror("bind socket");
++
++ return t->socket;
+ }
+
+diff -ur apinger-0.6.1.orig//src/icmp6.c apinger-0.6.1/src/icmp6.c
+--- apinger-0.6.1.orig//src/icmp6.c 2012-07-25 17:46:59.422189729 +0000
++++ apinger-0.6.1/src/icmp6.c 2012-07-25 17:44:41.644063862 +0000
+@@ -113,14 +113,14 @@
+ memcpy(p+1,&ti,sizeof(ti));
+ size=sizeof(*p)+sizeof(ti);
+
+- ret=sendto(icmp6_sock,p,size,MSG_DONTWAIT,
++ ret=sendto(t->socket,p,size,MSG_DONTWAIT,
+ (struct sockaddr *)&t->addr.addr6,sizeof(t->addr.addr6));
+ if (ret<0){
+ if (config->debug) myperror("sendto");
+ }
+ }
+
+-void recv_icmp6(void){
++void recv_icmp6(struct target *t){
+ int len,icmplen,datalen;
+ char buf[1024];
+ char abuf[100];
+@@ -134,6 +134,7 @@
+ struct iovec iov;
+ struct msghdr msg;
+ struct cmsghdr *c;
++reloophack6:
+
+ iov.iov_base=buf;
+ iov.iov_len=1000;
+@@ -143,12 +144,13 @@
+ msg.msg_iovlen=1;
+ msg.msg_control=ans_data;
+ msg.msg_controllen=sizeof(ans_data);
+- len=recvmsg(icmp6_sock, &msg, MSG_DONTWAIT);
++ len=recvmsg(t->socket, &msg, MSG_DONTWAIT);
+ #else
+ socklen_t sl;
++reloophack6:
+
+ sl=sizeof(from);
+- len=recvfrom(icmp6_sock,buf,1024,0,(struct sockaddr *)&from,&sl);
++ len=recvfrom(t->socket,buf,1024,0,(struct sockaddr *)&from,&sl);
+ #endif
+ if (len<0){
+ if (errno==EAGAIN) return;
+@@ -170,7 +172,7 @@
+ #endif
+ if (time_recvp==NULL){
+ #ifdef SIOCGSTAMP
+- if (!ioctl(icmp6_sock, SIOCGSTAMP, &time_recv)){
++ if (!ioctl(t->socket, SIOCGSTAMP, &time_recv)){
+ debug("Got timestamp from ioctl()");
+ }else
+ #endif
+@@ -183,8 +185,11 @@
+ icmplen=len;
+ icmp=(struct icmp6_hdr *)buf;
+ if (icmp->icmp6_type != ICMP6_ECHO_REPLY) return;
+- if (icmp->icmp6_id != ident) return;
+-
++ if (icmp->icmp6_id != ident){
++ debug("Alien echo-reply received from xxx. Expected %i, received %i", ident, icmp->icmp6_id);
++ goto reloophack6;
++ return;
++ }
+ name=inet_ntop(AF_INET6,&from.sin6_addr,abuf,100);
+ debug("Ping reply from %s",name);
+ datalen=icmplen-sizeof(*icmp);
+@@ -196,33 +201,36 @@
+ }
+
+
+-int make_icmp6_socket(void){
++int make_icmp6_socket(struct target *t){
+ int opt;
+
+- icmp6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+- if (icmp6_sock<0)
++ t->socket = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
++ if (t->socket <0)
+ myperror("socket");
+ else {
+ opt=2;
+ #if defined(SOL_RAW) && defined(IPV6_CHECKSUM)
+- if (setsockopt(icmp6_sock, SOL_RAW, IPV6_CHECKSUM, &opt, sizeof(int)))
++ if (setsockopt(t->socket, SOL_RAW, IPV6_CHECKSUM, &opt, sizeof(int)))
+ myperror("setsockopt(IPV6_CHECKSUM)");
+ #endif
+ #ifdef SO_TIMESTAMP
+ opt=1;
+- if (setsockopt(icmp6_sock, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)))
++ if (setsockopt(t->socket, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)))
+ myperror("setsockopt(SO_TIMESTAMP)");
+ #endif
+ /*install_filter6();*/
+ }
+- return icmp6_sock;
++ if (bind(t->socket, (struct sockaddr *)&t->ifaddr.addr6, sizeof(t->ifaddr.addr6)) < 0)
++ myperror("bind socket");
++
++ return t->socket;
+ }
+
+ #else /*HAVE_IPV6*/
+ #include "apinger.h"
+
+-int make_icmp6_socket(void){ return -1; }
+-void recv_icmp6(void){}
++int make_icmp6_socket(struct target *t){ return -1; }
++void recv_icmp6(struct target *t){}
+ void send_icmp6_probe(struct target *t,int seq){}
+
+ #endif /*HAVE_IPV6*/
+diff -ur apinger-0.6.1.orig//src/main.c apinger-0.6.1/src/main.c
+--- apinger-0.6.1.orig//src/main.c 2012-07-25 17:46:59.423189376 +0000
++++ apinger-0.6.1/src/main.c 2012-07-25 17:49:53.167255387 +0000
+@@ -72,6 +72,7 @@
+ { /* target defaults */
+ "default", /* name */
+ "", /* description */
++ "", /* interface */
+ 1000, /* interval */
+ 20, /* avg_delay_samples */
+ 5, /* avg_loss_delay_samples */
+@@ -96,7 +97,7 @@
+
+ int icmp_sock;
+ int icmp6_sock;
+-int ident;
++uint16_t ident;
+
+ struct timeval next_probe={0,0};
+
+@@ -204,12 +205,6 @@
+ }
+ }
+
+- make_icmp_socket();
+- make_icmp6_socket();
+- if (icmp6_sock<0 && icmp_sock<0){
+- return 1;
+- }
+-
+ pw=getpwnam(config->user);
+ if (!pw) {
+ debug("getpwnam(\"%s\") failed.",config->user);
+@@ -264,15 +259,15 @@
+ return 1;
+ }
+
+- ident=getpid();
++ ident=getpid() & 0xFFFF;
+ signal(SIGTERM,signal_handler);
+ signal(SIGINT,signal_handler);
+ signal(SIGHUP,signal_handler);
+ signal(SIGUSR1,signal_handler);
+ signal(SIGPIPE,signal_handler);
++ logit("Starting Alarm Pinger, apinger(%i)", ident);
++
+ main_loop();
+- if (icmp_sock>=0) close(icmp_sock);
+- if (icmp6_sock>=0) close(icmp6_sock);
+
+ logit("Exiting on signal %i.",interrupted_by);
+
More information about the pld-cvs-commit
mailing list