1 diff -ur apinger-0.6.1.orig//src/apinger.c apinger-0.6.1/src/apinger.c
2 --- apinger-0.6.1.orig//src/apinger.c 2012-07-25 17:46:59.421182293 +0000
3 +++ apinger-0.6.1/src/apinger.c 2012-07-25 17:44:41.642064536 +0000
9 + values[n]=t->config->srcip;
12 values[n]=t->description;
16 fprintf(f,"alarm canceled: %s\n",a->name);
17 fprintf(f,"Target: %s\n",t->name);
18 + fprintf(f,"Source: %s\n",t->config->srcip);
19 fprintf(f,"Description: %s\n",t->description);
20 fprintf(f,"Probes sent: %i\n",t->last_sent+1);
21 fprintf(f,"Replies received: %i\n",t->received);
23 struct target *t,*pt,*nt;
24 struct target_cfg *tc;
25 struct active_alarm_list *al,*nal;
27 +union addr addr, srcaddr;
42 if (t==NULL) { /* new target */
43 memset(&addr,0,sizeof(addr));
44 + logit("Checking target IP %s", tc->srcip);
45 r=inet_pton(AF_INET,tc->name,&addr.addr4.sin_addr);
48 - logit("Sorry, IPv4 is not available\n");
49 - logit("Ignoring target %s\n",tc->name);
52 addr.addr.sa_family=AF_INET;
55 r=inet_pton(AF_INET6,tc->name,&addr.addr6.sin6_addr);
58 - logit("Bad host address: %s\n",tc->name);
59 + logit("Bad target IP address: %s\n",tc->name);
60 logit("Ignoring target %s\n",tc->name);
64 addr.addr.sa_family=AF_INET6;
67 + memset(&srcaddr,0,sizeof(srcaddr));
68 + logit("Checking source IP %s", tc->srcip);
69 + r=inet_pton(AF_INET,tc->srcip,&srcaddr.addr4.sin_addr);
71 + srcaddr.addr.sa_family=AF_INET;
74 + r=inet_pton(AF_INET6,tc->srcip,&srcaddr.addr6.sin6_addr);
77 + logit("Bad source IP address %s for target %s\n", tc->srcip, tc->name);
78 + logit("Ignoring target %s\n",tc->name);
83 + logit("Sorry, IPv6 is not available\n");
84 + logit("Ignoring target %s\n",tc->name);
87 + srcaddr.addr.sa_family=AF_INET6;
90 t=NEW(struct target,1);
91 memset(t,0,sizeof(struct target));
92 t->name=strdup(tc->name);
93 t->description=strdup(tc->description);
97 + if(t->addr.addr.sa_family==AF_INET) make_icmp_socket(t);
98 + if(t->addr.addr.sa_family==AF_INET6) make_icmp6_socket(t);
103 assert(t->rbuf!=NULL);
108 logit("No usable targets found, exiting");
120 fprintf(f,"%s\n",ctime(&tm));
121 for(t=targets;t;t=t->next){
122 fprintf(f,"Target: %s\n",t->name);
123 + fprintf(f,"Source: %s\n",t->config->srcip);
124 fprintf(f,"Description: %s\n",t->description);
125 fprintf(f,"Last reply received: #%i %s",t->last_received,
126 ctime(&t->last_received_tv.tv_sec));
128 void main_loop(void){
130 struct timeval cur_time,next_status={0,0},tv,next_report={0,0},next_rrd_update={0,0};
131 -struct pollfd pfd[2];
132 +struct pollfd pfd[1024];
141 - pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
142 - pfd[npfd].revents=0;
143 - pfd[npfd++].fd=icmp_sock;
146 - pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
147 - pfd[npfd++].fd=icmp6_sock;
148 - pfd[npfd].revents=0;
150 + memset(&pfd, '\0', sizeof pfd);
152 if (config->status_interval){
153 gettimeofday(&cur_time,NULL);
154 tv.tv_sec=config->status_interval/1000;
155 @@ -893,10 +917,16 @@
156 timeradd(&cur_time,&tv,&next_status);
158 while(!interrupted_by){
160 gettimeofday(&cur_time,NULL);
161 if ( !timercmp(&next_probe,&cur_time,>) )
162 timerclear(&next_probe);
163 for(t=targets;t;t=t->next){
165 + pfd[npfd].events=POLLIN|POLLERR|POLLHUP|POLLNVAL;
166 + pfd[npfd].revents=0;
167 + pfd[npfd++].fd=t->socket;
169 for(al=t->config->alarms;al;al=nal){
172 @@ -972,8 +1002,20 @@
173 poll(pfd,npfd,timeout);
175 if (!pfd[i].revents&POLLIN) continue;
176 - if (pfd[i].fd==icmp_sock) recv_icmp();
177 - else if (pfd[i].fd==icmp6_sock) recv_icmp6();
178 + for(t=targets;t;t=t->next){
179 + if (t->addr.addr.sa_family==AF_INET) {
180 + if (t->socket == pfd[i].fd) {
185 + if (t->addr.addr.sa_family==AF_INET6) {
186 + if (t->socket == pfd[i].fd) {
195 diff -ur apinger-0.6.1.orig//src/apinger.conf apinger-0.6.1/src/apinger.conf
196 --- apinger-0.6.1.orig//src/apinger.conf 2012-07-26 11:14:05.000000000 +0000
197 +++ apinger-0.6.1/src/apinger.conf 2012-07-26 11:21:50.624064932 +0000
200 ## Following "macros" may be used in options below:
201 ## %t - target name (address)
202 + ## %i - source name (address)
203 ## %T - target description
205 ## %A - alarm type ("down"/"loss"/"delay")
206 diff -ur apinger-0.6.1.orig//src/apinger.h apinger-0.6.1/src/apinger.h
207 --- apinger-0.6.1.orig//src/apinger.h 2012-07-25 17:46:59.422189729 +0000
208 +++ apinger-0.6.1/src/apinger.h 2012-07-25 17:44:41.642064536 +0000
213 +#include <ifaddrs.h>
216 struct sockaddr addr;
217 struct sockaddr_in addr4;
219 char *description; /* description */
221 union addr addr; /* target address */
225 contains info about recently sent packets
226 "1" means it was received */
228 int last_sent; /* sequence number of the last ping sent */
229 int last_received; /* sequence number of the last ping received */
230 struct timeval last_received_tv; /* timestamp of the last ping received */
232 struct target_cfg *config;
235 + union addr ifaddr; /* iface address */
238 #define AVG_DELAY_KNOWN(t) (t->upsent >= t->config->avg_delay_samples)
239 @@ -111,16 +115,16 @@
241 extern int icmp_sock;
242 extern int icmp6_sock;
244 +extern uint16_t ident;
246 extern struct timeval next_probe;
248 -int make_icmp_socket(void);
249 -void recv_icmp(void);
250 +int make_icmp_socket(struct target *t);
251 +void recv_icmp(struct target *t);
252 void send_icmp_probe(struct target *t,int seq);
254 -int make_icmp6_socket(void);
255 -void recv_icmp6(void);
256 +int make_icmp6_socket(struct target *t);
257 +void recv_icmp6(struct target *t);
258 void send_icmp6_probe(struct target *t,int seq);
260 void analyze_reply(struct timeval time_recv,int seq,struct trace_info *ti);
261 diff -ur apinger-0.6.1.orig//src/cfgparser1.y apinger-0.6.1/src/cfgparser1.y
262 --- apinger-0.6.1.orig//src/cfgparser1.y 2003-03-26 11:27:47.000000000 +0000
263 +++ apinger-0.6.1/src/cfgparser1.y 2012-07-25 17:44:41.643063909 +0000
271 %token AVG_DELAY_SAMPLES
275 { cur_target->description=$2; }
277 + { cur_target->srcip = $2; }
279 { cur_target->alarms=$2; }
280 | ALARMS OVERRIDE alarmlist
281 diff -ur apinger-0.6.1.orig//src/cfgparser2.l apinger-0.6.1/src/cfgparser2.l
282 --- apinger-0.6.1.orig//src/cfgparser2.l 2003-03-26 11:27:47.000000000 +0000
283 +++ apinger-0.6.1/src/cfgparser2.l 2012-07-25 17:44:41.643063909 +0000
285 delay_high { LOC; LOCINC; return DELAY_HIGH; }
286 delay_low { LOC; LOCINC; return DELAY_LOW; }
287 description { LOC; LOCINC; return DESCRIPTION; }
288 +srcip { LOC; LOCINC; return SRCIP; }
289 down { LOC; LOCINC; return DOWN; }
290 false { LOC; LOCINC; return FALSE; }
291 file { LOC; LOCINC; return FILE_; }
292 diff -ur apinger-0.6.1.orig//src/conf.c apinger-0.6.1/src/conf.c
293 --- apinger-0.6.1.orig//src/conf.c 2003-03-26 11:27:47.000000000 +0000
294 +++ apinger-0.6.1/src/conf.c 2012-07-27 10:54:53.563251145 +0000
298 for(t=cur_config.targets;t;t=t->next){
299 + if (t->name==NULL || strlen(t->name)==0){
300 + logit("Target name can't be empty.");
303 + else if (t->srcip==NULL){
304 + logit("No source IP defined for target \"%s\".", t->name);
307 if (t->description==NULL)
308 t->description=cur_config.target_defaults.description;
310 diff -ur apinger-0.6.1.orig//src/conf.h apinger-0.6.1/src/conf.h
311 --- apinger-0.6.1.orig//src/conf.h 2003-03-26 11:27:47.000000000 +0000
312 +++ apinger-0.6.1/src/conf.h 2012-07-25 17:44:41.643063909 +0000
319 int avg_delay_samples;
320 int avg_loss_delay_samples;
321 diff -ur apinger-0.6.1.orig//src/icmp.c apinger-0.6.1/src/icmp.c
322 --- apinger-0.6.1.orig//src/icmp.c 2012-07-25 17:46:59.422189729 +0000
323 +++ apinger-0.6.1/src/icmp.c 2012-07-25 17:44:41.644063862 +0000
324 @@ -151,14 +151,14 @@
325 size=sizeof(*p)+sizeof(ti);
327 p->icmp_cksum = in_cksum((u_short *)p,size,0);
328 - ret=sendto(icmp_sock,p,size,MSG_DONTWAIT,
329 + ret=sendto(t->socket,p,size,MSG_DONTWAIT,
330 (struct sockaddr *)&t->addr.addr4,sizeof(t->addr.addr4));
332 if (config->debug) myperror("sendto");
336 -void recv_icmp(void){
337 +void recv_icmp(struct target *t){
338 int len,hlen,icmplen,datalen;
340 struct sockaddr_in from;
349 @@ -180,12 +181,13 @@
351 msg.msg_control=ans_data;
352 msg.msg_controllen=sizeof(ans_data);
353 - len=recvmsg(icmp_sock, &msg, MSG_DONTWAIT);
354 + len=recvmsg(t->socket, &msg, MSG_DONTWAIT);
360 - len=recvfrom(icmp_sock,buf,1024,MSG_DONTWAIT,(struct sockaddr *)&from,&sl);
361 + len=recvfrom(t->socket,buf,1024,MSG_DONTWAIT,(struct sockaddr *)&from,&sl);
364 if (errno==EAGAIN) return;
366 debug("checking CMSG...");
367 for (c = CMSG_FIRSTHDR(&msg); c; c = CMSG_NXTHDR(&msg, c)) {
368 debug("CMSG level: %i type: %i",c->cmsg_level,c->cmsg_type);
369 - if (c->cmsg_level != SOL_SOCKET || c->cmsg_type != SO_TIMESTAMP)
370 + if (c->cmsg_level != SOL_SOCKET || c->cmsg_type != SCM_TIMESTAMP)
372 if (c->cmsg_len < CMSG_LEN(sizeof(struct timeval)))
376 if (time_recvp==NULL){
378 - if (!ioctl(icmp_sock, SIOCGSTAMP, &time_recv)){
379 + if (!ioctl(t->socket, SIOCGSTAMP, &time_recv)){
380 debug("Got timestampt from ioctl()");
386 if (icmp->icmp_id != ident){
387 - debug("Alien echo-reply received");
388 + debug("Alien echo-reply received from %s. Expected %i, received %i",inet_ntoa(from.sin_addr), ident, icmp->icmp_id);
392 debug("Ping reply from %s",inet_ntoa(from.sin_addr));
393 @@ -239,19 +242,23 @@
394 analyze_reply(*time_recvp,icmp->icmp_seq,(struct trace_info*)(icmp+1));
397 -int make_icmp_socket(void){
398 +int make_icmp_socket(struct target *t){
401 - icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
403 + t->socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
410 - if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
411 + if (setsockopt(t->socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
412 myperror("setsockopt(SO_TIMESTAMP)");
417 + if (bind(t->socket, (struct sockaddr *)&t->ifaddr.addr4, sizeof(t->ifaddr.addr4)) < 0)
418 + myperror("bind socket");
423 diff -ur apinger-0.6.1.orig//src/icmp6.c apinger-0.6.1/src/icmp6.c
424 --- apinger-0.6.1.orig//src/icmp6.c 2012-07-25 17:46:59.422189729 +0000
425 +++ apinger-0.6.1/src/icmp6.c 2012-07-25 17:44:41.644063862 +0000
426 @@ -113,14 +113,14 @@
427 memcpy(p+1,&ti,sizeof(ti));
428 size=sizeof(*p)+sizeof(ti);
430 - ret=sendto(icmp6_sock,p,size,MSG_DONTWAIT,
431 + ret=sendto(t->socket,p,size,MSG_DONTWAIT,
432 (struct sockaddr *)&t->addr.addr6,sizeof(t->addr.addr6));
434 if (config->debug) myperror("sendto");
438 -void recv_icmp6(void){
439 +void recv_icmp6(struct target *t){
440 int len,icmplen,datalen;
451 @@ -143,12 +144,13 @@
453 msg.msg_control=ans_data;
454 msg.msg_controllen=sizeof(ans_data);
455 - len=recvmsg(icmp6_sock, &msg, MSG_DONTWAIT);
456 + len=recvmsg(t->socket, &msg, MSG_DONTWAIT);
462 - len=recvfrom(icmp6_sock,buf,1024,0,(struct sockaddr *)&from,&sl);
463 + len=recvfrom(t->socket,buf,1024,0,(struct sockaddr *)&from,&sl);
466 if (errno==EAGAIN) return;
469 if (time_recvp==NULL){
471 - if (!ioctl(icmp6_sock, SIOCGSTAMP, &time_recv)){
472 + if (!ioctl(t->socket, SIOCGSTAMP, &time_recv)){
473 debug("Got timestamp from ioctl()");
478 icmp=(struct icmp6_hdr *)buf;
479 if (icmp->icmp6_type != ICMP6_ECHO_REPLY) return;
480 - if (icmp->icmp6_id != ident) return;
482 + if (icmp->icmp6_id != ident){
483 + debug("Alien echo-reply received from xxx. Expected %i, received %i", ident, icmp->icmp6_id);
487 name=inet_ntop(AF_INET6,&from.sin6_addr,abuf,100);
488 debug("Ping reply from %s",name);
489 datalen=icmplen-sizeof(*icmp);
490 @@ -196,33 +201,36 @@
494 -int make_icmp6_socket(void){
495 +int make_icmp6_socket(struct target *t){
498 - icmp6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
500 + t->socket = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
505 #if defined(SOL_RAW) && defined(IPV6_CHECKSUM)
506 - if (setsockopt(icmp6_sock, SOL_RAW, IPV6_CHECKSUM, &opt, sizeof(int)))
507 + if (setsockopt(t->socket, SOL_RAW, IPV6_CHECKSUM, &opt, sizeof(int)))
508 myperror("setsockopt(IPV6_CHECKSUM)");
512 - if (setsockopt(icmp6_sock, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)))
513 + if (setsockopt(t->socket, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)))
514 myperror("setsockopt(SO_TIMESTAMP)");
516 /*install_filter6();*/
519 + if (bind(t->socket, (struct sockaddr *)&t->ifaddr.addr6, sizeof(t->ifaddr.addr6)) < 0)
520 + myperror("bind socket");
528 -int make_icmp6_socket(void){ return -1; }
529 -void recv_icmp6(void){}
530 +int make_icmp6_socket(struct target *t){ return -1; }
531 +void recv_icmp6(struct target *t){}
532 void send_icmp6_probe(struct target *t,int seq){}
535 diff -ur apinger-0.6.1.orig//src/main.c apinger-0.6.1/src/main.c
536 --- apinger-0.6.1.orig//src/main.c 2012-07-25 17:46:59.423189376 +0000
537 +++ apinger-0.6.1/src/main.c 2012-07-25 17:49:53.167255387 +0000
539 { /* target defaults */
540 "default", /* name */
541 "", /* description */
542 + "", /* interface */
544 20, /* avg_delay_samples */
545 5, /* avg_loss_delay_samples */
553 struct timeval next_probe={0,0};
559 - make_icmp_socket();
560 - make_icmp6_socket();
561 - if (icmp6_sock<0 && icmp_sock<0){
565 pw=getpwnam(config->user);
567 debug("getpwnam(\"%s\") failed.",config->user);
568 @@ -264,15 +259,15 @@
573 + ident=getpid() & 0xFFFF;
574 signal(SIGTERM,signal_handler);
575 signal(SIGINT,signal_handler);
576 signal(SIGHUP,signal_handler);
577 signal(SIGUSR1,signal_handler);
578 signal(SIGPIPE,signal_handler);
579 + logit("Starting Alarm Pinger, apinger(%i)", ident);
582 - if (icmp_sock>=0) close(icmp_sock);
583 - if (icmp6_sock>=0) close(icmp6_sock);
585 logit("Exiting on signal %i.",interrupted_by);