1/* 2 * icmp.h 3 * 4 * Internet Control Message Protocol. 5 * RFC 792, 950, 1256, 1393, 1475, 2002, 2521 6 * 7 * Copyright (c) 2000 Dug Song <dugsong@monkey.org> 8 * 9 * $Id: icmp.h,v 1.14 2003/03/16 17:39:17 dugsong Exp $ 10 */ 11 12#ifndef DNET_ICMP_H 13#define DNET_ICMP_H 14 15#define ICMP_HDR_LEN 4 /* base ICMP header length */ 16#define ICMP_LEN_MIN 8 /* minimum ICMP message size, with header */ 17 18#ifndef __GNUC__ 19# define __attribute__(x) 20# pragma pack(1) 21#endif 22 23/* 24 * ICMP header 25 */ 26struct icmp_hdr { 27 uint8_t icmp_type; /* type of message, see below */ 28 uint8_t icmp_code; /* type sub code */ 29 uint16_t icmp_cksum; /* ones complement cksum of struct */ 30}; 31 32/* 33 * Types (icmp_type) and codes (icmp_code) - 34 * http://www.iana.org/assignments/icmp-parameters 35 */ 36#define ICMP_CODE_NONE 0 /* for types without codes */ 37#define ICMP_ECHOREPLY 0 /* echo reply */ 38#define ICMP_UNREACH 3 /* dest unreachable, codes: */ 39#define ICMP_UNREACH_NET 0 /* bad net */ 40#define ICMP_UNREACH_HOST 1 /* bad host */ 41#define ICMP_UNREACH_PROTO 2 /* bad protocol */ 42#define ICMP_UNREACH_PORT 3 /* bad port */ 43#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ 44#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ 45#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ 46#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ 47#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ 48#define ICMP_UNREACH_NET_PROHIB 9 /* for crypto devs */ 49#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ 50#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ 51#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ 52#define ICMP_UNREACH_FILTER_PROHIB 13 /* prohibited access */ 53#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* precedence error */ 54#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */ 55#define ICMP_SRCQUENCH 4 /* packet lost, slow down */ 56#define ICMP_REDIRECT 5 /* shorter route, codes: */ 57#define ICMP_REDIRECT_NET 0 /* for network */ 58#define ICMP_REDIRECT_HOST 1 /* for host */ 59#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ 60#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ 61#define ICMP_ALTHOSTADDR 6 /* alternate host address */ 62#define ICMP_ECHO 8 /* echo service */ 63#define ICMP_RTRADVERT 9 /* router advertise, codes: */ 64#define ICMP_RTRADVERT_NORMAL 0 /* normal */ 65#define ICMP_RTRADVERT_NOROUTE_COMMON 16 /* selective routing */ 66#define ICMP_RTRSOLICIT 10 /* router solicitation */ 67#define ICMP_TIMEXCEED 11 /* time exceeded, code: */ 68#define ICMP_TIMEXCEED_INTRANS 0 /* ttl==0 in transit */ 69#define ICMP_TIMEXCEED_REASS 1 /* ttl==0 in reass */ 70#define ICMP_PARAMPROB 12 /* ip header bad */ 71#define ICMP_PARAMPROB_ERRATPTR 0 /* req. opt. absent */ 72#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ 73#define ICMP_PARAMPROB_LENGTH 2 /* bad length */ 74#define ICMP_TSTAMP 13 /* timestamp request */ 75#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ 76#define ICMP_INFO 15 /* information request */ 77#define ICMP_INFOREPLY 16 /* information reply */ 78#define ICMP_MASK 17 /* address mask request */ 79#define ICMP_MASKREPLY 18 /* address mask reply */ 80#define ICMP_TRACEROUTE 30 /* traceroute */ 81#define ICMP_DATACONVERR 31 /* data conversion error */ 82#define ICMP_MOBILE_REDIRECT 32 /* mobile host redirect */ 83#define ICMP_IPV6_WHEREAREYOU 33 /* IPv6 where-are-you */ 84#define ICMP_IPV6_IAMHERE 34 /* IPv6 i-am-here */ 85#define ICMP_MOBILE_REG 35 /* mobile registration req */ 86#define ICMP_MOBILE_REGREPLY 36 /* mobile registration reply */ 87#define ICMP_DNS 37 /* domain name request */ 88#define ICMP_DNSREPLY 38 /* domain name reply */ 89#define ICMP_SKIP 39 /* SKIP */ 90#define ICMP_PHOTURIS 40 /* Photuris */ 91#define ICMP_PHOTURIS_UNKNOWN_INDEX 0 /* unknown sec index */ 92#define ICMP_PHOTURIS_AUTH_FAILED 1 /* auth failed */ 93#define ICMP_PHOTURIS_DECOMPRESS_FAILED 2 /* decompress failed */ 94#define ICMP_PHOTURIS_DECRYPT_FAILED 3 /* decrypt failed */ 95#define ICMP_PHOTURIS_NEED_AUTHN 4 /* no authentication */ 96#define ICMP_PHOTURIS_NEED_AUTHZ 5 /* no authorization */ 97#define ICMP_TYPE_MAX 40 98 99#define ICMP_INFOTYPE(type) \ 100 ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ 101 (type) == ICMP_RTRADVERT || (type) == ICMP_RTRSOLICIT || \ 102 (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ 103 (type) == ICMP_INFO || (type) == ICMP_INFOREPLY || \ 104 (type) == ICMP_MASK || (type) == ICMP_MASKREPLY) 105 106/* 107 * Echo message data 108 */ 109struct icmp_msg_echo { 110 uint16_t icmp_id; 111 uint16_t icmp_seq; 112 uint8_t icmp_data __flexarr; /* optional data */ 113}; 114 115/* 116 * Fragmentation-needed (unreachable) message data 117 */ 118struct icmp_msg_needfrag { 119 uint16_t icmp_void; /* must be zero */ 120 uint16_t icmp_mtu; /* MTU of next-hop network */ 121 uint8_t icmp_ip __flexarr; /* IP hdr + 8 bytes of pkt */ 122}; 123 124/* 125 * Unreachable, source quench, redirect, time exceeded, 126 * parameter problem message data 127 */ 128struct icmp_msg_quote { 129 uint32_t icmp_void; /* must be zero */ 130#define icmp_gwaddr icmp_void /* router IP address to use */ 131#define icmp_pptr icmp_void /* ptr to bad octet field */ 132 uint8_t icmp_ip __flexarr; /* IP hdr + 8 bytes of pkt */ 133}; 134 135/* 136 * Router advertisement message data, RFC 1256 137 */ 138struct icmp_msg_rtradvert { 139 uint8_t icmp_num_addrs; /* # of address / pref pairs */ 140 uint8_t icmp_wpa; /* words / address == 2 */ 141 uint16_t icmp_lifetime; /* route lifetime in seconds */ 142 struct icmp_msg_rtr_data { 143 uint32_t icmp_void; 144#define icmp_gwaddr icmp_void /* router IP address */ 145 uint32_t icmp_pref; /* router preference (usu 0) */ 146 } icmp_rtr __flexarr; /* variable # of routers */ 147}; 148#define ICMP_RTR_PREF_NODEFAULT 0x80000000 /* do not use as default gw */ 149 150/* 151 * Timestamp message data 152 */ 153struct icmp_msg_tstamp { 154 uint32_t icmp_id; /* identifier */ 155 uint32_t icmp_seq; /* sequence number */ 156 uint32_t icmp_ts_orig; /* originate timestamp */ 157 uint32_t icmp_ts_rx; /* receive timestamp */ 158 uint32_t icmp_ts_tx; /* transmit timestamp */ 159}; 160 161/* 162 * Address mask message data, RFC 950 163 */ 164struct icmp_msg_mask { 165 uint32_t icmp_id; /* identifier */ 166 uint32_t icmp_seq; /* sequence number */ 167 uint32_t icmp_mask; /* address mask */ 168}; 169 170/* 171 * Traceroute message data, RFC 1393, RFC 1812 172 */ 173struct icmp_msg_traceroute { 174 uint16_t icmp_id; /* identifier */ 175 uint16_t icmp_void; /* unused */ 176 uint16_t icmp_ohc; /* outbound hop count */ 177 uint16_t icmp_rhc; /* return hop count */ 178 uint32_t icmp_speed; /* link speed, bytes/sec */ 179 uint32_t icmp_mtu; /* MTU in bytes */ 180}; 181 182/* 183 * Domain name reply message data, RFC 1788 184 */ 185struct icmp_msg_dnsreply { 186 uint16_t icmp_id; /* identifier */ 187 uint16_t icmp_seq; /* sequence number */ 188 uint32_t icmp_ttl; /* time-to-live */ 189 uint8_t icmp_names __flexarr; /* variable number of names */ 190}; 191 192/* 193 * Generic identifier, sequence number data 194 */ 195struct icmp_msg_idseq { 196 uint16_t icmp_id; 197 uint16_t icmp_seq; 198}; 199 200/* 201 * ICMP message union 202 */ 203union icmp_msg { 204 struct icmp_msg_echo echo; /* ICMP_ECHO{REPLY} */ 205 struct icmp_msg_quote unreach; /* ICMP_UNREACH */ 206 struct icmp_msg_needfrag needfrag; /* ICMP_UNREACH_NEEDFRAG */ 207 struct icmp_msg_quote srcquench; /* ICMP_SRCQUENCH */ 208 struct icmp_msg_quote redirect; /* ICMP_REDIRECT (set to 0) */ 209 uint32_t rtrsolicit; /* ICMP_RTRSOLICIT */ 210 struct icmp_msg_rtradvert rtradvert; /* ICMP_RTRADVERT */ 211 struct icmp_msg_quote timexceed; /* ICMP_TIMEXCEED */ 212 struct icmp_msg_quote paramprob; /* ICMP_PARAMPROB */ 213 struct icmp_msg_tstamp tstamp; /* ICMP_TSTAMP{REPLY} */ 214 struct icmp_msg_idseq info; /* ICMP_INFO{REPLY} */ 215 struct icmp_msg_mask mask; /* ICMP_MASK{REPLY} */ 216 struct icmp_msg_traceroute traceroute; /* ICMP_TRACEROUTE */ 217 struct icmp_msg_idseq dns; /* ICMP_DNS */ 218 struct icmp_msg_dnsreply dnsreply; /* ICMP_DNSREPLY */ 219}; 220 221#ifndef __GNUC__ 222# pragma pack() 223#endif 224 225#define icmp_pack_hdr(hdr, type, code) do { \ 226 struct icmp_hdr *icmp_pack_p = (struct icmp_hdr *)(hdr); \ 227 icmp_pack_p->icmp_type = type; icmp_pack_p->icmp_code = code; \ 228} while (0) 229 230#define icmp_pack_hdr_echo(hdr, type, code, id, seq, data, len) do { \ 231 struct icmp_msg_echo *echo_pack_p = (struct icmp_msg_echo *) \ 232 ((uint8_t *)(hdr) + ICMP_HDR_LEN); \ 233 icmp_pack_hdr(hdr, type, code); \ 234 echo_pack_p->icmp_id = htons(id); \ 235 echo_pack_p->icmp_seq = htons(seq); \ 236 memmove(echo_pack_p->icmp_data, data, len); \ 237} while (0) 238 239#define icmp_pack_hdr_quote(hdr, type, code, word, pkt, len) do { \ 240 struct icmp_msg_quote *quote_pack_p = (struct icmp_msg_quote *) \ 241 ((uint8_t *)(hdr) + ICMP_HDR_LEN); \ 242 icmp_pack_hdr(hdr, type, code); \ 243 quote_pack_p->icmp_void = htonl(word); \ 244 memmove(quote_pack_p->icmp_ip, pkt, len); \ 245} while (0) 246 247#define icmp_pack_hdr_mask(hdr, type, code, id, seq, mask) do { \ 248 struct icmp_msg_mask *mask_pack_p = (struct icmp_msg_mask *) \ 249 ((uint8_t *)(hdr) + ICMP_HDR_LEN); \ 250 icmp_pack_hdr(hdr, type, code); \ 251 mask_pack_p->icmp_id = htons(id); \ 252 mask_pack_p->icmp_seq = htons(seq); \ 253 mask_pack_p->icmp_mask = htonl(mask); \ 254} while (0) 255 256#define icmp_pack_hdr_needfrag(hdr, type, code, mtu, pkt, len) do { \ 257 struct icmp_msg_needfrag *frag_pack_p = \ 258 (struct icmp_msg_needfrag *)((uint8_t *)(hdr) + ICMP_HDR_LEN); \ 259 icmp_pack_hdr(hdr, type, code); \ 260 frag_pack_p->icmp_void = 0; \ 261 frag_pack_p->icmp_mtu = htons(mtu); \ 262 memmove(frag_pack_p->icmp_ip, pkt, len); \ 263} while (0) 264 265#endif /* DNET_ICMP_H */ 266