12632SN/A/*
22632SN/A * icmp.h
32632SN/A *
42632SN/A * Internet Control Message Protocol.
52632SN/A * RFC 792, 950, 1256, 1393, 1475, 2002, 2521
62632SN/A *
72632SN/A * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
82632SN/A *
92632SN/A * $Id: icmp.h,v 1.14 2003/03/16 17:39:17 dugsong Exp $
102632SN/A */
112632SN/A
122632SN/A#ifndef DNET_ICMP_H
132632SN/A#define DNET_ICMP_H
142632SN/A
152632SN/A#define ICMP_HDR_LEN	4	/* base ICMP header length */
162632SN/A#define ICMP_LEN_MIN	8	/* minimum ICMP message size, with header */
172632SN/A
182632SN/A#ifndef __GNUC__
192632SN/A# define __attribute__(x)
202632SN/A# pragma pack(1)
212632SN/A#endif
222632SN/A
232632SN/A/*
242632SN/A * ICMP header
252632SN/A */
262632SN/Astruct icmp_hdr {
272632SN/A        uint8_t		icmp_type;	/* type of message, see below */
282632SN/A        uint8_t		icmp_code;	/* type sub code */
292632SN/A        uint16_t	icmp_cksum;	/* ones complement cksum of struct */
302632SN/A};
312632SN/A
322632SN/A/*
332632SN/A * Types (icmp_type) and codes (icmp_code) -
342632SN/A * http://www.iana.org/assignments/icmp-parameters
352632SN/A */
362632SN/A#define		ICMP_CODE_NONE		0	/* for types without codes */
372632SN/A#define	ICMP_ECHOREPLY		0		/* echo reply */
382632SN/A#define	ICMP_UNREACH		3		/* dest unreachable, codes: */
392632SN/A#define		ICMP_UNREACH_NET		0	/* bad net */
402632SN/A#define		ICMP_UNREACH_HOST		1	/* bad host */
412632SN/A#define		ICMP_UNREACH_PROTO		2	/* bad protocol */
422632SN/A#define		ICMP_UNREACH_PORT		3	/* bad port */
432632SN/A#define		ICMP_UNREACH_NEEDFRAG		4	/* IP_DF caused drop */
442632SN/A#define		ICMP_UNREACH_SRCFAIL		5	/* src route failed */
452632SN/A#define		ICMP_UNREACH_NET_UNKNOWN	6	/* unknown net */
462632SN/A#define		ICMP_UNREACH_HOST_UNKNOWN	7	/* unknown host */
472632SN/A#define		ICMP_UNREACH_ISOLATED		8	/* src host isolated */
482632SN/A#define		ICMP_UNREACH_NET_PROHIB		9	/* for crypto devs */
492632SN/A#define		ICMP_UNREACH_HOST_PROHIB	10	/* ditto */
502632SN/A#define		ICMP_UNREACH_TOSNET		11	/* bad tos for net */
512632SN/A#define		ICMP_UNREACH_TOSHOST		12	/* bad tos for host */
522632SN/A#define		ICMP_UNREACH_FILTER_PROHIB	13	/* prohibited access */
532632SN/A#define		ICMP_UNREACH_HOST_PRECEDENCE	14	/* precedence error */
542632SN/A#define		ICMP_UNREACH_PRECEDENCE_CUTOFF	15	/* precedence cutoff */
552632SN/A#define	ICMP_SRCQUENCH		4		/* packet lost, slow down */
562632SN/A#define	ICMP_REDIRECT		5		/* shorter route, codes: */
572632SN/A#define		ICMP_REDIRECT_NET		0	/* for network */
582632SN/A#define		ICMP_REDIRECT_HOST		1	/* for host */
592632SN/A#define		ICMP_REDIRECT_TOSNET		2	/* for tos and net */
602632SN/A#define		ICMP_REDIRECT_TOSHOST		3	/* for tos and host */
612632SN/A#define	ICMP_ALTHOSTADDR	6		/* alternate host address */
622632SN/A#define	ICMP_ECHO		8		/* echo service */
632632SN/A#define	ICMP_RTRADVERT		9		/* router advertise, codes: */
642632SN/A#define		ICMP_RTRADVERT_NORMAL		0	/* normal */
652632SN/A#define		ICMP_RTRADVERT_NOROUTE_COMMON 16	/* selective routing */
662632SN/A#define	ICMP_RTRSOLICIT		10		/* router solicitation */
672632SN/A#define	ICMP_TIMEXCEED		11		/* time exceeded, code: */
682632SN/A#define		ICMP_TIMEXCEED_INTRANS		0	/* ttl==0 in transit */
692632SN/A#define		ICMP_TIMEXCEED_REASS		1	/* ttl==0 in reass */
702632SN/A#define	ICMP_PARAMPROB		12		/* ip header bad */
712632SN/A#define		ICMP_PARAMPROB_ERRATPTR		0	/* req. opt. absent */
722632SN/A#define		ICMP_PARAMPROB_OPTABSENT	1	/* req. opt. absent */
732632SN/A#define		ICMP_PARAMPROB_LENGTH		2	/* bad length */
742632SN/A#define	ICMP_TSTAMP		13		/* timestamp request */
752632SN/A#define	ICMP_TSTAMPREPLY	14		/* timestamp reply */
762632SN/A#define	ICMP_INFO		15		/* information request */
772632SN/A#define	ICMP_INFOREPLY		16		/* information reply */
782632SN/A#define	ICMP_MASK		17		/* address mask request */
792632SN/A#define	ICMP_MASKREPLY		18		/* address mask reply */
802632SN/A#define ICMP_TRACEROUTE		30		/* traceroute */
812632SN/A#define ICMP_DATACONVERR	31		/* data conversion error */
822632SN/A#define ICMP_MOBILE_REDIRECT	32		/* mobile host redirect */
832632SN/A#define ICMP_IPV6_WHEREAREYOU	33		/* IPv6 where-are-you */
842632SN/A#define ICMP_IPV6_IAMHERE	34		/* IPv6 i-am-here */
852632SN/A#define ICMP_MOBILE_REG		35		/* mobile registration req */
862632SN/A#define ICMP_MOBILE_REGREPLY	36		/* mobile registration reply */
872632SN/A#define ICMP_DNS		37		/* domain name request */
882632SN/A#define ICMP_DNSREPLY		38		/* domain name reply */
892632SN/A#define ICMP_SKIP		39		/* SKIP */
902632SN/A#define ICMP_PHOTURIS		40		/* Photuris */
912632SN/A#define		ICMP_PHOTURIS_UNKNOWN_INDEX	0	/* unknown sec index */
922632SN/A#define		ICMP_PHOTURIS_AUTH_FAILED	1	/* auth failed */
932632SN/A#define		ICMP_PHOTURIS_DECOMPRESS_FAILED	2	/* decompress failed */
942632SN/A#define		ICMP_PHOTURIS_DECRYPT_FAILED	3	/* decrypt failed */
952632SN/A#define		ICMP_PHOTURIS_NEED_AUTHN	4	/* no authentication */
962632SN/A#define		ICMP_PHOTURIS_NEED_AUTHZ	5	/* no authorization */
972632SN/A#define	ICMP_TYPE_MAX		40
982632SN/A
992632SN/A#define	ICMP_INFOTYPE(type)						\
1002632SN/A        ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO ||		\
1012632SN/A        (type) == ICMP_RTRADVERT || (type) == ICMP_RTRSOLICIT ||	\
1022632SN/A        (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY ||		\
1032632SN/A        (type) == ICMP_INFO || (type) == ICMP_INFOREPLY ||		\
1042632SN/A        (type) == ICMP_MASK || (type) == ICMP_MASKREPLY)
1052632SN/A
1062632SN/A/*
1072632SN/A * Echo message data
1082632SN/A */
1092632SN/Astruct icmp_msg_echo {
1102632SN/A        uint16_t	icmp_id;
1112632SN/A        uint16_t	icmp_seq;
1122632SN/A        uint8_t		icmp_data __flexarr;	/* optional data */
1132632SN/A};
1142632SN/A
1152632SN/A/*
1162632SN/A * Fragmentation-needed (unreachable) message data
1172632SN/A */
1182632SN/Astruct icmp_msg_needfrag {
1192632SN/A        uint16_t	icmp_void;		/* must be zero */
1202632SN/A        uint16_t	icmp_mtu;		/* MTU of next-hop network */
1212632SN/A        uint8_t		icmp_ip __flexarr;	/* IP hdr + 8 bytes of pkt */
1222632SN/A};
1232632SN/A
1242632SN/A/*
1252632SN/A *  Unreachable, source quench, redirect, time exceeded,
1262632SN/A *  parameter problem message data
1272632SN/A */
1282632SN/Astruct icmp_msg_quote {
1292632SN/A        uint32_t	icmp_void;		/* must be zero */
1302632SN/A#define icmp_gwaddr	icmp_void		/* router IP address to use */
1312632SN/A#define icmp_pptr	icmp_void		/* ptr to bad octet field */
1322632SN/A        uint8_t		icmp_ip __flexarr;	/* IP hdr + 8 bytes of pkt */
1332632SN/A};
1342632SN/A
1352632SN/A/*
1362632SN/A * Router advertisement message data, RFC 1256
1372632SN/A */
1382632SN/Astruct icmp_msg_rtradvert {
1392632SN/A        uint8_t		icmp_num_addrs;		/* # of address / pref pairs */
1402632SN/A        uint8_t		icmp_wpa;		/* words / address == 2 */
1412632SN/A        uint16_t	icmp_lifetime;		/* route lifetime in seconds */
1422632SN/A        struct icmp_msg_rtr_data {
1432632SN/A                uint32_t	icmp_void;
1442632SN/A#define icmp_gwaddr		icmp_void	/* router IP address */
1452632SN/A                uint32_t	icmp_pref;	/* router preference (usu 0) */
1462632SN/A        } icmp_rtr __flexarr;			/* variable # of routers */
1472632SN/A};
1482632SN/A#define ICMP_RTR_PREF_NODEFAULT	0x80000000	/* do not use as default gw */
1492632SN/A
1502632SN/A/*
1512632SN/A * Timestamp message data
1522632SN/A */
1532632SN/Astruct icmp_msg_tstamp {
1542632SN/A        uint32_t	icmp_id;		/* identifier */
1552632SN/A        uint32_t	icmp_seq;		/* sequence number */
1562632SN/A        uint32_t	icmp_ts_orig;		/* originate timestamp */
1572632SN/A        uint32_t	icmp_ts_rx;		/* receive timestamp */
1582632SN/A        uint32_t	icmp_ts_tx;		/* transmit timestamp */
1592632SN/A};
1602632SN/A
1612632SN/A/*
1622632SN/A * Address mask message data, RFC 950
1632632SN/A */
1642632SN/Astruct icmp_msg_mask {
1652632SN/A        uint32_t	icmp_id;		/* identifier */
1662632SN/A        uint32_t	icmp_seq;		/* sequence number */
1672632SN/A        uint32_t	icmp_mask;		/* address mask */
1682632SN/A};
1692632SN/A
1702632SN/A/*
1712632SN/A * Traceroute message data, RFC 1393, RFC 1812
1722632SN/A */
1732632SN/Astruct icmp_msg_traceroute {
1742632SN/A        uint16_t	icmp_id;		/* identifier */
1752632SN/A        uint16_t	icmp_void;		/* unused */
1762632SN/A        uint16_t	icmp_ohc;		/* outbound hop count */
1772632SN/A        uint16_t	icmp_rhc;		/* return hop count */
1782632SN/A        uint32_t	icmp_speed;		/* link speed, bytes/sec */
1792632SN/A        uint32_t	icmp_mtu;		/* MTU in bytes */
1802632SN/A};
1812632SN/A
1822632SN/A/*
1832632SN/A * Domain name reply message data, RFC 1788
1842632SN/A */
1852632SN/Astruct icmp_msg_dnsreply {
1862632SN/A        uint16_t	icmp_id;		/* identifier */
1872632SN/A        uint16_t	icmp_seq;		/* sequence number */
1882632SN/A        uint32_t	icmp_ttl;		/* time-to-live */
1892632SN/A        uint8_t		icmp_names __flexarr;	/* variable number of names */
1902632SN/A};
1912632SN/A
1922632SN/A/*
1932632SN/A * Generic identifier, sequence number data
1942632SN/A */
1952632SN/Astruct icmp_msg_idseq {
1962632SN/A        uint16_t	icmp_id;
1972632SN/A        uint16_t	icmp_seq;
1982632SN/A};
1992632SN/A
2002632SN/A/*
2012632SN/A * ICMP message union
2022632SN/A */
2032632SN/Aunion icmp_msg {
2042632SN/A        struct icmp_msg_echo	   echo;	/* ICMP_ECHO{REPLY} */
2052632SN/A        struct icmp_msg_quote	   unreach;	/* ICMP_UNREACH */
2062632SN/A        struct icmp_msg_needfrag   needfrag;	/* ICMP_UNREACH_NEEDFRAG */
2072632SN/A        struct icmp_msg_quote	   srcquench;	/* ICMP_SRCQUENCH */
2082632SN/A        struct icmp_msg_quote	   redirect;	/* ICMP_REDIRECT (set to 0) */
2092632SN/A        uint32_t		   rtrsolicit;	/* ICMP_RTRSOLICIT */
2102632SN/A        struct icmp_msg_rtradvert  rtradvert;	/* ICMP_RTRADVERT */
2112632SN/A        struct icmp_msg_quote	   timexceed;	/* ICMP_TIMEXCEED */
2122632SN/A        struct icmp_msg_quote	   paramprob;	/* ICMP_PARAMPROB */
2132632SN/A        struct icmp_msg_tstamp	   tstamp;	/* ICMP_TSTAMP{REPLY} */
2142632SN/A        struct icmp_msg_idseq	   info;	/* ICMP_INFO{REPLY} */
2152632SN/A        struct icmp_msg_mask	   mask;	/* ICMP_MASK{REPLY} */
2162632SN/A        struct icmp_msg_traceroute traceroute;	/* ICMP_TRACEROUTE */
2172632SN/A        struct icmp_msg_idseq	   dns;		/* ICMP_DNS */
2182632SN/A        struct icmp_msg_dnsreply   dnsreply;	/* ICMP_DNSREPLY */
2192632SN/A};
2202632SN/A
2212632SN/A#ifndef __GNUC__
2222632SN/A# pragma pack()
2232632SN/A#endif
2242632SN/A
2252632SN/A#define icmp_pack_hdr(hdr, type, code) do {				\
2262632SN/A        struct icmp_hdr *icmp_pack_p = (struct icmp_hdr *)(hdr);	\
2272632SN/A        icmp_pack_p->icmp_type = type; icmp_pack_p->icmp_code = code;	\
2282632SN/A} while (0)
2292632SN/A
2302632SN/A#define icmp_pack_hdr_echo(hdr, type, code, id, seq, data, len) do {	\
2312632SN/A        struct icmp_msg_echo *echo_pack_p = (struct icmp_msg_echo *)	\
2322632SN/A                ((uint8_t *)(hdr) + ICMP_HDR_LEN);			\
2332632SN/A        icmp_pack_hdr(hdr, type, code);					\
2342632SN/A        echo_pack_p->icmp_id = htons(id);				\
2352632SN/A        echo_pack_p->icmp_seq = htons(seq);				\
2362632SN/A        memmove(echo_pack_p->icmp_data, data, len);			\
2372632SN/A} while (0)
2382632SN/A
2392632SN/A#define icmp_pack_hdr_quote(hdr, type, code, word, pkt, len) do {	\
2402632SN/A        struct icmp_msg_quote *quote_pack_p = (struct icmp_msg_quote *)	\
2412632SN/A                ((uint8_t *)(hdr) + ICMP_HDR_LEN);			\
2422632SN/A        icmp_pack_hdr(hdr, type, code);					\
2432632SN/A        quote_pack_p->icmp_void = htonl(word);				\
2442632SN/A        memmove(quote_pack_p->icmp_ip, pkt, len);			\
2452632SN/A} while (0)
2462632SN/A
2472632SN/A#define icmp_pack_hdr_mask(hdr, type, code, id, seq, mask) do {		\
2482632SN/A        struct icmp_msg_mask *mask_pack_p = (struct icmp_msg_mask *)	\
2492632SN/A                ((uint8_t *)(hdr) + ICMP_HDR_LEN);			\
2502632SN/A        icmp_pack_hdr(hdr, type, code);					\
2512632SN/A        mask_pack_p->icmp_id = htons(id);				\
2522632SN/A        mask_pack_p->icmp_seq = htons(seq);				\
2532632SN/A        mask_pack_p->icmp_mask = htonl(mask);				\
2542632SN/A} while (0)
2552632SN/A
2562632SN/A#define icmp_pack_hdr_needfrag(hdr, type, code, mtu, pkt, len) do {	\
2572632SN/A        struct icmp_msg_needfrag *frag_pack_p =				\
2582632SN/A        (struct icmp_msg_needfrag *)((uint8_t *)(hdr) + ICMP_HDR_LEN);	\
2592632SN/A        icmp_pack_hdr(hdr, type, code);					\
2602632SN/A        frag_pack_p->icmp_void = 0;					\
2612632SN/A        frag_pack_p->icmp_mtu = htons(mtu);				\
2622632SN/A        memmove(frag_pack_p->icmp_ip, pkt, len);			\
2632632SN/A} while (0)
2642632SN/A
2652632SN/A#endif /* DNET_ICMP_H */
266