/* ex: set tabstop=4 shiftwidth=4 autoindent: +-------------------------------------------------------------------------+ | Copyright (C) 2004-2026 The Cacti Group | | | | This program is free software; you can redistribute it and/or | | modify it under the terms of the GNU Lesser General Public | | License as published by the Free Software Foundation; either | | version 2.1 of the License, or (at your option) any later version. | | | | This program is distributed in the hope that it will be useful, | | but WITHOUT ANY WARRANTY; without even the implied warranty of | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | GNU Lesser General Public License for more details. | | | | You should have received a copy of the GNU Lesser General Public | | License along with this library; if not, write to the Free Software | | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | | 02110-1301, USA | | | +-------------------------------------------------------------------------+ | spine: a backend data gatherer for cacti | +-------------------------------------------------------------------------+ | This poller would not have been possible without: | | - Larry Adams (current development and enhancements) | | - Rivo Nurges (rrd support, mysql poller cache, misc functions) | | - RTG (core poller code, pthreads, snmp, autoconf examples) | | - Brady Alleman/Doug Warner (threading ideas, implementation details) | +-------------------------------------------------------------------------+ | - Cacti - http://www.cacti.net/ | +-------------------------------------------------------------------------+ */ #ifndef SPINE_PING_H #define SPINE_PING_H #ifndef ICMP_ECHOREPLY #define ICMP_ECHOREPLY 0 /* Echo Reply */ #endif /* IPv6 pinging needs a raw ICMPv6 socket and the RFC 3542 socket options. * Platforms without them keep the previous behavior of reporting IPv6 * devices as pingable by SNMP only. */ #if !defined(__CYGWIN__) && defined(AF_INET6) && defined(IPPROTO_ICMPV6) && \ defined(ICMP6_FILTER) && defined(ICMP6_ECHO_REQUEST) && defined(ICMP6_ECHO_REPLY) #define SPINE_HAVE_ICMPV6 1 #endif #ifndef MSG_WAITALL #define MSG_WAITALL 0x100 #endif #ifdef __CYGWIN__ struct icmp_ra_addr { u_int32_t ira_addr; u_int32_t ira_preference; }; struct iphdr { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int ihl:4; unsigned int version:4; #elif __BYTE_ORDER == __BIG_ENDIAN unsigned int version:4; unsigned int ihl:4; #else # error "Please fix " #endif u_int8_t tos; u_int16_t tot_len; u_int16_t id; u_int16_t frag_off; u_int8_t ttl; u_int8_t protocol; u_int16_t check; u_int32_t saddr; u_int32_t daddr; /*The options start here. */ }; struct icmp { u_int8_t icmp_type; /* type of message, see below */ u_int8_t icmp_code; /* type sub code */ u_int16_t icmp_cksum; /* ones complement checksum of struct */ union { u_char ih_pptr; /* ICMP_PARAMPROB */ struct in_addr ih_gwaddr; /* gateway address */ struct ih_idseq /* echo datagram */ { u_int16_t icd_id; u_int16_t icd_seq; } ih_idseq; u_int32_t ih_void; /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ struct ih_pmtu { u_int16_t ipm_void; u_int16_t ipm_nextmtu; } ih_pmtu; struct ih_rtradv { u_int8_t irt_num_addrs; u_int8_t irt_wpa; u_int16_t irt_lifetime; } ih_rtradv; } icmp_hun; #define icmp_pptr icmp_hun.ih_pptr #define icmp_gwaddr icmp_hun.ih_gwaddr #define icmp_id icmp_hun.ih_idseq.icd_id #define icmp_seq icmp_hun.ih_idseq.icd_seq #define icmp_void icmp_hun.ih_void #define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void #define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu #define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs #define icmp_wpa icmp_hun.ih_rtradv.irt_wpa #define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime union { struct { u_int32_t its_otime; u_int32_t its_rtime; u_int32_t its_ttime; } id_ts; struct { struct ip idi_ip; /* options and then 64 bits of data */ } id_ip; struct icmp_ra_addr id_radv; u_int32_t id_mask; u_int8_t id_data[1]; } icmp_dun; #define icmp_otime icmp_dun.id_ts.its_otime #define icmp_rtime icmp_dun.id_ts.its_rtime #define icmp_ttime icmp_dun.id_ts.its_ttime #define icmp_ip icmp_dun.id_ip.idi_ip #define icmp_radv icmp_dun.id_radv #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data }; #endif /* Host availability functions */ /* Classification of a raw ICMP reply. Declared here so the fuzz target can * link against the shipped implementation. */ typedef enum { SPINE_ICMP_REPLY_TOO_SHORT = 0, /* shorter than an IP header */ SPINE_ICMP_REPLY_BAD_HEADER, /* IHL implausible, or no room for the ICMP header */ SPINE_ICMP_REPLY_NOT_ECHO, /* not an echo reply */ SPINE_ICMP_REPLY_NOT_OURS, /* echo reply, but not our id/sequence */ SPINE_ICMP_REPLY_OK } spine_icmp_reply_t; extern spine_icmp_reply_t spine_icmp_classify_reply(const unsigned char *reply, ssize_t len, uint16_t want_id, uint16_t want_seq, const struct icmp **out_pkt); extern spine_icmp_reply_t spine_icmp_classify_dgram_reply(const unsigned char *reply, ssize_t len, uint16_t want_seq, const struct icmp **out_pkt); extern int ping_host(host_t *host, ping_t *ping); extern int ping_snmp(host_t *host, ping_t *ping); extern int ping_icmp(const host_t *host, ping_t *ping); extern int ping_icmp_open_shared(void); extern int ping_icmp_shared_available(void); extern int ping_udp(const host_t *host, ping_t *ping); extern int ping_tcp(const host_t *host, ping_t *ping); extern name_t *get_namebyhost(const char *hostname, name_t *name); extern void update_host_status(int status, host_t *host, const ping_t *ping, int availability_method); extern int init_sockaddr(struct sockaddr_in *name, const char *hostname, int port); extern int get_address_type(host_t *host); extern unsigned short int get_checksum(void* buf, int len); #endif /* SPINE_PING_H */