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