xref: /original-bsd/sys/netiso/clnp.h (revision 3705696b)
1 /*-
2  * Copyright (c) 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)clnp.h	8.1 (Berkeley) 06/10/93
8  */
9 
10 /***********************************************************
11 		Copyright IBM Corporation 1987
12 
13                       All Rights Reserved
14 
15 Permission to use, copy, modify, and distribute this software and its
16 documentation for any purpose and without fee is hereby granted,
17 provided that the above copyright notice appear in all copies and that
18 both that copyright notice and this permission notice appear in
19 supporting documentation, and that the name of IBM not be
20 used in advertising or publicity pertaining to distribution of the
21 software without specific, written prior permission.
22 
23 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
25 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
26 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
27 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
28 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
29 SOFTWARE.
30 
31 ******************************************************************/
32 
33 /*
34  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
35  */
36 /* $Header: /big/BSD4.4/isis-usr/src/sys/netiso/RCS/clnp.h,v 1.1 1992/02/07 18:14:59 hagens Exp hagens $ */
37 /* $Source: /big/BSD4.4/isis-usr/src/sys/netiso/RCS/clnp.h,v $ */
38 
39 #ifndef BYTE_ORDER
40 /*
41  * Definitions for byte order,
42  * according to byte significance from low address to high.
43  */
44 #define	LITTLE_ENDIAN	1234	/* least-significant byte first (vax) */
45 #define	BIG_ENDIAN	4321	/* most-significant byte first (IBM, net) */
46 #define	PDP_ENDIAN	3412	/* LSB first in word, MSW first in long (pdp) */
47 
48 #ifdef vax
49 #define	BYTE_ORDER	LITTLE_ENDIAN
50 #else
51 #define	BYTE_ORDER	BIG_ENDIAN	/* mc68000, tahoe, most others */
52 #endif
53 #endif /* BYTE_ORDER */
54 
55 /* should be config option but cpp breaks with too many #defines */
56 #define	DECBIT
57 
58 /*
59  *	Return true if the mbuf is a cluster mbuf
60  */
61 #define	IS_CLUSTER(m)	((m)->m_flags & M_EXT)
62 
63 /*
64  *	Move the halfword into the two characters
65  */
66 #define	HTOC(msb, lsb, hword)\
67 	(msb) = (u_char)((hword) >> 8);\
68 	(lsb) = (u_char)((hword) & 0xff)
69 /*
70  *	Move the two charcters into the halfword
71  */
72 #define	CTOH(msb, lsb, hword)\
73 	(hword) = ((msb) << 8) | (lsb)
74 
75 /*
76  *	Return true if the checksum has been set - ie. the checksum is
77  *	not zero
78  */
79 #define	CKSUM_REQUIRED(clnp)\
80 	(((clnp)->cnf_cksum_msb != 0) || ((clnp)->cnf_cksum_lsb != 0))
81 
82 /*
83  *	Fixed part of clnp header
84  */
85 struct clnp_fixed {
86 	u_char	cnf_proto_id;		/* network layer protocol identifier */
87 	u_char	cnf_hdr_len;		/* length indicator (octets) */
88 	u_char	cnf_vers;			/* version/protocol identifier extension */
89 	u_char	cnf_ttl;			/* lifetime (500 milliseconds) */
90 	u_char	cnf_type;			/* type code */
91 								/* Includes err_ok, more_segs, and seg_ok */
92 	u_char	cnf_seglen_msb;		/* pdu segment length (octets) high byte */
93 	u_char	cnf_seglen_lsb;		/* pdu segment length (octets) low byte */
94 	u_char	cnf_cksum_msb;		/* checksum high byte */
95 	u_char	cnf_cksum_lsb;		/* checksum low byte */
96 };
97 #define CNF_TYPE	0x1f
98 #define CNF_ERR_OK	0x20
99 #define CNF_MORE_SEGS	0x40
100 #define CNF_SEG_OK	0x80
101 
102 #define CLNP_CKSUM_OFF	0x07	/* offset of checksum */
103 
104 #define	clnl_fixed	clnp_fixed
105 
106 /*
107  *	Segmentation part of clnp header
108  */
109 struct clnp_segment {
110 	u_short	cng_id;				/* data unit identifier */
111 	u_short	cng_off;			/* segment offset */
112 	u_short	cng_tot_len;		/* total length */
113 };
114 
115 /*
116  *	Clnp fragment reassembly structures:
117  *
118  *	All packets undergoing reassembly are linked together in
119  *	clnp_fragl structures. Each clnp_fragl structure contains a
120  *	pointer to the original clnp packet header, as well as a
121  *	list of packet fragments. Each packet fragment
122  *	is headed by a clnp_frag structure. This structure contains the
123  *	offset of the first and last byte of the fragment, as well as
124  *	a pointer to the data (an mbuf chain) of the fragment.
125  */
126 
127 /*
128  *	NOTE:
129  *		The clnp_frag structure is stored in an mbuf immedately preceeding
130  *	the fragment data. Since there are words in this struct,
131  *	it must be word aligned.
132  *
133  *	NOTE:
134  *		All the fragment code assumes that the entire clnp header is
135  *	contained in the first mbuf.
136  */
137 struct clnp_frag {
138 	u_int				cfr_first;		/* offset of first byte of this frag */
139 	u_int				cfr_last;		/* offset of last byte of this frag */
140 	u_int				cfr_bytes;		/* bytes to shave to get to data */
141 	struct mbuf			*cfr_data;		/* ptr to data for this frag */
142 	struct clnp_frag	*cfr_next;		/* next fragment in list */
143 };
144 
145 struct clnp_fragl {
146 	struct iso_addr		cfl_src;		/* source of the pkt */
147 	struct iso_addr		cfl_dst;		/* destination of the pkt */
148 	u_short				cfl_id;			/* id of the pkt */
149 	u_char				cfl_ttl;		/* current ttl of pkt */
150 	u_short				cfl_last;		/* offset of last byte of packet */
151 	struct mbuf 		*cfl_orighdr;	/* ptr to original header */
152 	struct clnp_frag	*cfl_frags;		/* linked list of fragments for pkt */
153 	struct clnp_fragl	*cfl_next;		/* next pkt being reassembled */
154 };
155 
156 /*
157  *	The following structure is used to index into an options section
158  *	of a clnp datagram. These values can be used without worry that
159  *	offset or length fields are invalid or too big, etc. That is,
160  *	the consistancy of the options will be guaranteed before this
161  *	structure is filled in. Any pointer (field ending in p) is
162  *	actually the offset from the beginning of the mbuf the option
163  *	is contained in.  A value of NULL for any pointer
164  *	means that the option is not present. The length any option
165  *	does not include the option code or option length fields.
166  */
167 struct clnp_optidx {
168 	u_short	cni_securep;		/* ptr to beginning of security option */
169 	char	cni_secure_len;		/* length of entire security option */
170 
171 	u_short	cni_srcrt_s;		/* offset of start of src rt option */
172 	u_short	cni_srcrt_len;		/* length of entire src rt option */
173 
174 	u_short	cni_recrtp;			/* ptr to beginning of recrt option */
175 	char	cni_recrt_len;		/* length of entire recrt option */
176 
177 	char	cni_priorp;			/* ptr to priority option */
178 
179 	u_short	cni_qos_formatp;	/* ptr to format of qos option */
180 	char	cni_qos_len;		/* length of entire qos option */
181 
182 	u_char	cni_er_reason;		/* reason from ER pdu option */
183 
184 								/* ESIS options */
185 
186 	u_short	cni_esct;			/* value from ISH ESCT option */
187 
188 	u_short	cni_netmaskp;		/* ptr to beginning of netmask option */
189 	char	cni_netmask_len;		/* length of entire netmask option */
190 
191 	u_short	cni_snpamaskp;		/* ptr to beginning of snpamask option */
192 	char	cni_snpamask_len;		/* length of entire snpamask option */
193 
194 };
195 
196 #define	ER_INVALREAS	0xff	/* code for invalid ER pdu discard reason */
197 
198 /* given an mbuf and addr of option, return offset from data of mbuf */
199 #define CLNP_OPTTOOFF(m, opt)\
200 	((u_short) (opt - mtod(m, caddr_t)))
201 
202 /* given an mbuf and offset of option, return address of option */
203 #define CLNP_OFFTOOPT(m, off)\
204 	((caddr_t) (mtod(m, caddr_t) + off))
205 
206 /*	return true iff src route is valid */
207 #define	CLNPSRCRT_VALID(oidx)\
208 	((oidx) && (oidx->cni_srcrt_s))
209 
210 /*	return the offset field of the src rt */
211 #define CLNPSRCRT_OFF(oidx, options)\
212 	(*((u_char *)(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s) + 1)))
213 
214 /*	return the type field of the src rt */
215 #define CLNPSRCRT_TYPE(oidx, options)\
216 	((u_char)(*(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s))))
217 
218 /* return the length of the current address */
219 #define CLNPSRCRT_CLEN(oidx, options)\
220 	((u_char)(*(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s) + CLNPSRCRT_OFF(oidx, options) - 1)))
221 
222 /* return the address of the current address */
223 #define CLNPSRCRT_CADDR(oidx, options)\
224 	((caddr_t)(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s) + CLNPSRCRT_OFF(oidx, options)))
225 
226 /*
227  *	return true if the src route has run out of routes
228  *	this is true if the offset of next route is greater than the end of the rt
229  */
230 #define	CLNPSRCRT_TERM(oidx, options)\
231 	(CLNPSRCRT_OFF(oidx, options) > oidx->cni_srcrt_len)
232 
233 /*
234  *	Options a user can set/get
235  */
236 #define	CLNPOPT_FLAGS	0x01	/* flags: seg permitted, no er xmit, etc  */
237 #define	CLNPOPT_OPTS	0x02	/* datagram options */
238 
239 /*
240  *	Values for particular datagram options
241  */
242 #define	CLNPOVAL_PAD		0xcc	/* padding */
243 #define	CLNPOVAL_SECURE		0xc5	/* security */
244 #define	CLNPOVAL_SRCRT		0xc8	/* source routing */
245 #define	CLNPOVAL_RECRT		0xcb	/* record route */
246 #define	CLNPOVAL_QOS		0xc3	/* quality of service */
247 #define	CLNPOVAL_PRIOR		0xcd	/* priority */
248 #define CLNPOVAL_ERREAS		0xc1	/* ER PDU ONLY: reason for discard */
249 
250 #define	CLNPOVAL_SRCSPEC	0x40	/* source address specific */
251 #define	CLNPOVAL_DSTSPEC	0x80	/* destination address specific */
252 #define	CLNPOVAL_GLOBAL		0xc0	/* globally unique */
253 
254 /* Globally Unique QOS */
255 #define	CLNPOVAL_SEQUENCING	0x10	/* sequencing preferred */
256 #define CLNPOVAL_CONGESTED	0x08	/* congestion experienced */
257 #define CLNPOVAL_LOWDELAY	0x04	/* low transit delay */
258 
259 #define	CLNPOVAL_PARTRT		0x00	/* partial source routing */
260 #define CLNPOVAL_COMPRT		0x01	/* complete source routing */
261 
262 /*
263  *	Clnp flags used in a control block flags field.
264  *	NOTE: these must be out of the range of bits defined in ../net/raw_cb.h
265  */
266 #define	CLNP_NO_SEG		0x010	/* segmentation not permitted */
267 #define	CLNP_NO_ER		0x020	/* do not generate ERs */
268 #define CLNP_SEND_RAW	0x080	/* send pkt as RAW DT rather than TP DT */
269 #define	CLNP_NO_CKSUM	0x100	/* don't use clnp checksum */
270 #define CLNP_ECHO		0x200	/* send echo request */
271 #define	CLNP_NOCACHE	0x400	/* don't store cache information */
272 #define CLNP_ECHOR		0x800	/* send echo reply */
273 
274 /* valid clnp flags */
275 #define CLNP_VFLAGS		(CLNP_SEND_RAW|CLNP_NO_SEG|CLNP_NO_ER|CLNP_NO_CKSUM\
276 	|CLNP_ECHO|CLNP_NOCACHE|CLNP_ECHOR)
277 
278 /*
279  *	Constants used by clnp
280  */
281 #define	CLNP_HDR_MIN	(sizeof (struct clnp_fixed))
282 #define	CLNP_HDR_MAX	(254)
283 #define	CLNP_TTL_UNITS	2					/* 500 milliseconds */
284 #define CLNP_TTL		15*CLNP_TTL_UNITS	/* time to live (seconds) */
285 #define	ISO8473_V1		0x01
286 
287 /*
288  *	Clnp packet types
289  *	In order to test raw clnp and tp/clnp simultaneously, a third type of
290  *	packet has been defined: CLNP_RAW. This is done so that the input
291  *	routine can switch to the correct input routine (rclnp_input or
292  *	tpclnp_input) based on the type field. If clnp had a higher level protocol
293  *	field, this would not be necessary.
294  */
295 #define	CLNP_DT			0x1C	/* normal data */
296 #define	CLNP_ER			0x01	/* error report */
297 #define	CLNP_RAW		0x1D	/* debug only */
298 #define CLNP_EC			0x1E	/* echo packet */
299 #define CLNP_ECR		0x1F	/* echo reply */
300 
301 /*
302  *	ER pdu error codes
303  */
304 #define GEN_NOREAS			0x00	/* reason not specified */
305 #define GEN_PROTOERR		0x01	/* protocol procedure error */
306 #define GEN_BADCSUM			0x02	/* incorrect checksum */
307 #define GEN_CONGEST			0x03	/* pdu discarded due to congestion */
308 #define GEN_HDRSYNTAX		0x04	/* header syntax error */
309 #define GEN_SEGNEEDED		0x05	/* segmentation needed, but not permitted */
310 #define GEN_INCOMPLETE		0x06	/* incomplete pdu received */
311 #define GEN_DUPOPT			0x07	/* duplicate option */
312 
313 /* address errors */
314 #define ADDR_DESTUNREACH	0x80	/* destination address unreachable */
315 #define ADDR_DESTUNKNOWN	0x81	/* destination address unknown */
316 
317 /* source routing */
318 #define SRCRT_UNSPECERR		0x90	/* unspecified src rt error */
319 #define SRCRT_SYNTAX		0x91	/* syntax error in src rt field */
320 #define SRCRT_UNKNOWNADDR	0x92	/* unknown addr in src rt field */
321 #define SRCRT_BADPATH		0x93	/* path not acceptable */
322 
323 /* lifetime */
324 #define TTL_EXPTRANSIT		0xa0	/* lifetime expired during transit */
325 #define TTL_EXPREASS		0xa1	/* lifetime expired during reassembly */
326 
327 /* pdu discarded */
328 #define DISC_UNSUPPOPT		0xb0	/* unsupported option not specified? */
329 #define DISC_UNSUPPVERS		0xb1	/* unsupported protocol version */
330 #define DISC_UNSUPPSECURE	0xb2	/* unsupported security option */
331 #define DISC_UNSUPPSRCRT	0xb3	/* unsupported src rt option */
332 #define DISC_UNSUPPRECRT	0xb4	/* unsupported rec rt option */
333 
334 /* reassembly */
335 #define REASS_INTERFERE		0xc0	/* reassembly interference */
336 #define CLNP_ERRORS		22
337 
338 
339 #ifdef KERNEL
340 int clnp_er_index();
341 #endif
342 
343 #ifdef CLNP_ER_CODES
344 u_char clnp_er_codes[CLNP_ERRORS] =  {
345 GEN_NOREAS, GEN_PROTOERR, GEN_BADCSUM, GEN_CONGEST,
346 GEN_HDRSYNTAX, GEN_SEGNEEDED, GEN_INCOMPLETE, GEN_DUPOPT,
347 ADDR_DESTUNREACH, ADDR_DESTUNKNOWN,
348 SRCRT_UNSPECERR, SRCRT_SYNTAX, SRCRT_UNKNOWNADDR, SRCRT_BADPATH,
349 TTL_EXPTRANSIT, TTL_EXPREASS,
350 DISC_UNSUPPOPT, DISC_UNSUPPVERS, DISC_UNSUPPSECURE,
351 DISC_UNSUPPSRCRT, DISC_UNSUPPRECRT, REASS_INTERFERE };
352 #endif
353 
354 #ifdef	TROLL
355 
356 #define	TR_DUPEND		0x01	/* duplicate end of fragment */
357 #define TR_DUPPKT		0x02	/* duplicate entire packet */
358 #define	TR_DROPPKT		0x04	/* drop packet on output */
359 #define TR_TRIM			0x08	/* trim bytes from packet */
360 #define TR_CHANGE		0x10	/* change bytes in packet */
361 #define TR_MTU			0x20	/* delta to change device mtu */
362 #define	TR_CHUCK		0x40	/* drop packet in rclnp_input */
363 #define	TR_BLAST		0x80	/* force rclnp_output to blast many packet */
364 #define	TR_RAWLOOP		0x100	/* make if_loop call clnpintr directly */
365 struct troll {
366 	int		tr_ops;				/* operations to perform */
367 	float	tr_dup_size;		/* % to duplicate */
368 	float	tr_dup_freq;		/* frequency to duplicate packets */
369 	float	tr_drop_freq;		/* frequence to drop packets */
370 	int		tr_mtu_adj;			/* delta to adjust if mtu */
371 	int		tr_blast_cnt;		/* # of pkts to blast out */
372 };
373 
374 #define	SN_OUTPUT(clcp, m)\
375 	troll_output(clcp->clc_ifp, m, clcp->clc_firsthop, clcp->clc_rt)
376 
377 #define	SN_MTU(ifp, rt) (((rt && rt->rt_rmx.rmx_mtu) ?\
378 	rt->rt_rmx.rmx_mtu : clnp_badmtu(ifp, rt, __LINE__, __FILE__))\
379 		- trollctl.tr_mtu_adj)
380 
381 #ifdef KERNEL
382 extern float troll_random;
383 #endif
384 
385 #else	/* NO TROLL */
386 
387 #define	SN_OUTPUT(clcp, m)\
388 	(*clcp->clc_ifp->if_output)(clcp->clc_ifp, m, clcp->clc_firsthop, clcp->clc_rt)
389 
390 #define	SN_MTU(ifp, rt) (((rt && rt->rt_rmx.rmx_mtu) ?\
391 	rt->rt_rmx.rmx_mtu : clnp_badmtu(ifp, rt, __LINE__, __FILE__)))
392 
393 #endif	/* TROLL */
394 
395 /*
396  *	Macro to remove an address from a clnp header
397  */
398 #define CLNP_EXTRACT_ADDR(isoa, hoff, hend)\
399 	{\
400 		isoa.isoa_len = (u_char)*hoff;\
401 		if ((((++hoff) + isoa.isoa_len) > hend) ||\
402 			(isoa.isoa_len > 20) || (isoa.isoa_len == 0)) {\
403 			hoff = (caddr_t)0;\
404 		} else {\
405 			(void) bcopy(hoff, (caddr_t)isoa.isoa_genaddr, isoa.isoa_len);\
406 			hoff += isoa.isoa_len;\
407 		}\
408 	}
409 
410 /*
411  *	Macro to insert an address into a clnp header
412  */
413 #define CLNP_INSERT_ADDR(hoff, isoa)\
414 	*hoff++ = (isoa).isoa_len;\
415 	(void) bcopy((caddr_t)((isoa).isoa_genaddr), hoff, (isoa).isoa_len);\
416 	hoff += (isoa).isoa_len;
417 
418 /*
419  *	Clnp hdr cache.	Whenever a clnp packet is sent, a copy of the
420  *	header is made and kept in this cache. In addition to a copy of
421  *	the cached clnp hdr, the cache contains
422  *	information necessary to determine whether the new packet
423  *	to send requires a new header to be built.
424  */
425 struct clnp_cache {
426 	/* these fields are used to check the validity of the cache */
427 	struct iso_addr		clc_dst;		/* destination of packet */
428 	struct mbuf 		*clc_options;	/* ptr to options mbuf */
429 	int					clc_flags;		/* flags passed to clnp_output */
430 
431 	/* these fields are state that clnp_output requires to finish the pkt */
432 	int					clc_segoff;		/* offset of seg part of header */
433 	struct rtentry		*clc_rt;		/* ptr to rtentry (points into
434 											the route structure) */
435 	struct sockaddr		*clc_firsthop;	/* first hop of packet */
436 	struct ifnet		*clc_ifp;		/* ptr to interface structure */
437 	struct iso_ifaddr	*clc_ifa;		/* ptr to interface address */
438 	struct mbuf 		*clc_hdr;		/* cached pkt hdr (finally)! */
439 };
440 
441 #ifndef	satosiso
442 #define	satosiso(sa)\
443 	((struct sockaddr_iso *)(sa))
444 #endif
445 
446 #ifdef	KERNEL
447 caddr_t			clnp_insert_addr();
448 struct iso_addr	*clnp_srcaddr();
449 struct mbuf		*clnp_reass();
450 #ifdef	TROLL
451 struct troll	trollctl;
452 #endif	/* TROLL */
453 #endif	/* KERNEL */
454