| 230 | | iphlen = ip->ip_hl << 2; |
|---|
| 231 | | if((inlen-iphlen) != (sizeof(struct icmp)+PING_PAYLOAD_LEN)) { |
|---|
| 232 | | noitLT(nldeb, now, |
|---|
| 233 | | "ping_icmp bad size: %d+%d\n", iphlen, inlen-iphlen); |
|---|
| 234 | | continue; |
|---|
| 235 | | } |
|---|
| 236 | | icp = (struct icmp *)(packet + iphlen); |
|---|
| 237 | | payload = (struct ping_payload *)(icp + 1); |
|---|
| 238 | | if(icp->icmp_type != ICMP_ECHOREPLY) { |
|---|
| 239 | | noitLT(nldeb, now, "ping_icmp bad type: %d\n", icp->icmp_type); |
|---|
| 240 | | continue; |
|---|
| 241 | | } |
|---|
| 242 | | if(icp->icmp_id != (((vpsized_uint)self) & 0xffff)) { |
|---|
| 243 | | noitLT(nldeb, now, |
|---|
| 244 | | "ping_icmp not sent from this instance (%d:%d) vs. %lu\n", |
|---|
| 245 | | icp->icmp_id, ntohs(icp->icmp_seq), |
|---|
| 246 | | (unsigned long)(((vpsized_uint)self) & 0xffff)); |
|---|
| | 236 | |
|---|
| | 237 | if(family == AF_INET) { |
|---|
| | 238 | struct ip *ip = (struct ip *)packet; |
|---|
| | 239 | struct icmp *icp4; |
|---|
| | 240 | iphlen = ((struct ip *)packet)->ip_hl << 2; |
|---|
| | 241 | if((inlen-iphlen) != sizeof(struct icmp)+PING_PAYLOAD_LEN) { |
|---|
| | 242 | noitLT(nldeb, now, |
|---|
| | 243 | "ping_icmp bad size: %d+%d\n", iphlen, inlen-iphlen); |
|---|
| | 244 | continue; |
|---|
| | 245 | } |
|---|
| | 246 | icp4 = (struct icmp *)(packet + iphlen); |
|---|
| | 247 | payload = (struct ping_payload *)(icp4 + 1); |
|---|
| | 248 | if(icp4->icmp_type != ICMP_ECHOREPLY) { |
|---|
| | 249 | noitLT(nldeb, now, "ping_icmp bad type: %d\n", icp4->icmp_type); |
|---|
| | 250 | continue; |
|---|
| | 251 | } |
|---|
| | 252 | if(icp4->icmp_id != (((vpsized_uint)self) & 0xffff)) { |
|---|
| | 253 | noitLT(nldeb, now, |
|---|
| | 254 | "ping_icmp not sent from this instance (%d:%d) vs. %lu\n", |
|---|
| | 255 | icp4->icmp_id, ntohs(icp4->icmp_seq), |
|---|
| | 256 | (unsigned long)(((vpsized_uint)self) & 0xffff)); |
|---|
| | 257 | continue; |
|---|
| | 258 | } |
|---|
| | 259 | } |
|---|
| | 260 | else if(family == AF_INET6) { |
|---|
| | 261 | struct icmp6_hdr *icp6 = (struct icmp6_hdr *)packet; |
|---|
| | 262 | if((inlen) != sizeof(struct icmp6_hdr)+PING_PAYLOAD_LEN) { |
|---|
| | 263 | noitLT(nldeb, now, |
|---|
| | 264 | "ping_icmp bad size: %d+%d\n", iphlen, inlen-iphlen); |
|---|
| | 265 | continue; |
|---|
| | 266 | } |
|---|
| | 267 | payload = (struct ping_payload *)(icp6+1); |
|---|
| | 268 | if(icp6->icmp6_type != ICMP6_ECHO_REPLY) { |
|---|
| | 269 | noitLT(nldeb, now, "ping_icmp bad type: %d\n", icp6->icmp6_type); |
|---|
| | 270 | continue; |
|---|
| | 271 | } |
|---|
| | 272 | if(icp6->icmp6_id != (((vpsized_uint)self) & 0xffff)) { |
|---|
| | 273 | noitLT(nldeb, now, |
|---|
| | 274 | "ping_icmp not sent from this instance (%d:%d) vs. %lu\n", |
|---|
| | 275 | icp6->icmp6_id, ntohs(icp6->icmp6_seq), |
|---|
| | 276 | (unsigned long)(((vpsized_uint)self) & 0xffff)); |
|---|
| | 277 | continue; |
|---|
| | 278 | } |
|---|
| | 279 | } |
|---|
| | 280 | else { |
|---|
| | 281 | /* This should be unreachable */ |
|---|
| | 337 | static int ping_icmp4_handler(eventer_t e, int mask, |
|---|
| | 338 | void *closure, struct timeval *now) { |
|---|
| | 339 | return ping_icmp_handler(e, mask, closure, now, AF_INET); |
|---|
| | 340 | } |
|---|
| | 341 | static int ping_icmp6_handler(eventer_t e, int mask, |
|---|
| | 342 | void *closure, struct timeval *now) { |
|---|
| | 343 | return ping_icmp_handler(e, mask, closure, now, AF_INET6); |
|---|
| | 344 | } |
|---|
| 357 | | data->ipv6_fd = socket(AF_INET6, SOCK_RAW, proto->p_proto); |
|---|
| 358 | | if(data->ipv6_fd < 0) { |
|---|
| 359 | | noitL(noit_error, "ping_icmp: socket failed: %s\n", |
|---|
| 360 | | strerror(errno)); |
|---|
| 361 | | } |
|---|
| 362 | | else { |
|---|
| 363 | | if(eventer_set_fd_nonblocking(data->ipv6_fd)) { |
|---|
| 364 | | close(data->ipv6_fd); |
|---|
| 365 | | data->ipv6_fd = -1; |
|---|
| 366 | | noitL(noit_error, |
|---|
| 367 | | "ping_icmp: could not set socket non-blocking: %s\n", |
|---|
| 368 | | strerror(errno)); |
|---|
| 369 | | } |
|---|
| 370 | | } |
|---|
| 371 | | if(data->ipv6_fd >= 0) { |
|---|
| 372 | | eventer_t newe; |
|---|
| 373 | | newe = eventer_alloc(); |
|---|
| 374 | | newe->fd = data->ipv6_fd; |
|---|
| 375 | | newe->mask = EVENTER_READ; |
|---|
| 376 | | newe->callback = ping_icmp_handler; |
|---|
| 377 | | newe->closure = self; |
|---|
| 378 | | eventer_add(newe); |
|---|
| 379 | | } |
|---|
| | 400 | if ((proto = getprotobyname("ipv6-icmp")) != NULL) { |
|---|
| | 401 | data->ipv6_fd = socket(AF_INET6, SOCK_RAW, proto->p_proto); |
|---|
| | 402 | if(data->ipv6_fd < 0) { |
|---|
| | 403 | noitL(noit_error, "ping_icmp: socket failed: %s\n", |
|---|
| | 404 | strerror(errno)); |
|---|
| | 405 | } |
|---|
| | 406 | else { |
|---|
| | 407 | if(eventer_set_fd_nonblocking(data->ipv6_fd)) { |
|---|
| | 408 | close(data->ipv6_fd); |
|---|
| | 409 | data->ipv6_fd = -1; |
|---|
| | 410 | noitL(noit_error, |
|---|
| | 411 | "ping_icmp: could not set socket non-blocking: %s\n", |
|---|
| | 412 | strerror(errno)); |
|---|
| | 413 | } |
|---|
| | 414 | } |
|---|
| | 415 | if(data->ipv6_fd >= 0) { |
|---|
| | 416 | eventer_t newe; |
|---|
| | 417 | newe = eventer_alloc(); |
|---|
| | 418 | newe->fd = data->ipv6_fd; |
|---|
| | 419 | newe->mask = EVENTER_READ; |
|---|
| | 420 | newe->callback = ping_icmp6_handler; |
|---|
| | 421 | newe->closure = self; |
|---|
| | 422 | eventer_add(newe); |
|---|
| | 423 | } |
|---|
| | 424 | } |
|---|
| | 425 | else |
|---|
| | 426 | noitL(noit_error, "Couldn't find 'ipv6-icmp' protocol\n"); |
|---|
| 525 | | payload = (struct ping_payload *)(icp + 1); |
|---|
| 526 | | |
|---|
| 527 | | icp->icmp_type = ICMP_ECHO; |
|---|
| 528 | | icp->icmp_code = 0; |
|---|
| 529 | | icp->icmp_cksum = 0; |
|---|
| 530 | | icp->icmp_seq = htons(ci->seq++); |
|---|
| 531 | | icp->icmp_id = (((vpsized_uint)self) & 0xffff); |
|---|
| | 575 | payload = (struct ping_payload *)((char *)icp + icp_len); |
|---|
| | 576 | |
|---|
| | 577 | if(check->target_family == AF_INET) { |
|---|
| | 578 | struct icmp *icp4 = icp; |
|---|
| | 579 | icp4->icmp_type = ICMP_ECHO; |
|---|
| | 580 | icp4->icmp_code = 0; |
|---|
| | 581 | icp4->icmp_cksum = 0; |
|---|
| | 582 | icp4->icmp_seq = htons(ci->seq++); |
|---|
| | 583 | icp4->icmp_id = (((vpsized_uint)self) & 0xffff); |
|---|
| | 584 | } |
|---|
| | 585 | else if(check->target_family == AF_INET6) { |
|---|
| | 586 | struct icmp6_hdr *icp6 = icp; |
|---|
| | 587 | icp6->icmp6_type = ICMP6_ECHO_REQUEST; |
|---|
| | 588 | icp6->icmp6_code = 0; |
|---|
| | 589 | icp6->icmp6_cksum = 0; |
|---|
| | 590 | icp6->icmp6_seq = htons(ci->seq++); |
|---|
| | 591 | icp6->icmp6_id = (((vpsized_uint)self) & 0xffff); |
|---|
| | 592 | } |
|---|