xref: /linux/include/net/llc_pdu.h (revision 29fb4a26416d851333be909fc313db9147b7099c)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef LLC_PDU_H
3 #define LLC_PDU_H
4 /*
5  * Copyright (c) 1997 by Procom Technology,Inc.
6  * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
7  */
8 
9 #include <linux/if_ether.h>
10 
11 /* Lengths of frame formats */
12 #define LLC_PDU_LEN_I		4       /* header and 2 control bytes */
13 #define LLC_PDU_LEN_S		4
14 #define LLC_PDU_LEN_U		3       /* header and 1 control byte */
15 /* header and 1 control byte and XID info */
16 #define LLC_PDU_LEN_U_XID	(LLC_PDU_LEN_U + sizeof(struct llc_xid_info))
17 /* Known SAP addresses */
18 #define LLC_GLOBAL_SAP	0xFF
19 #define LLC_NULL_SAP	0x00	/* not network-layer visible */
20 #define LLC_MGMT_INDIV	0x02	/* station LLC mgmt indiv addr */
21 #define LLC_MGMT_GRP	0x03	/* station LLC mgmt group addr */
22 #define LLC_RDE_SAP	0xA6	/* route ... */
23 
24 /* SAP field bit masks */
25 #define LLC_ISO_RESERVED_SAP	0x02
26 #define LLC_SAP_GROUP_DSAP	0x01
27 #define LLC_SAP_RESP_SSAP	0x01
28 
29 /* Group/individual DSAP indicator is DSAP field */
30 #define LLC_PDU_GROUP_DSAP_MASK    0x01
31 #define LLC_PDU_IS_GROUP_DSAP(pdu)      \
32 	((pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
33 #define LLC_PDU_IS_INDIV_DSAP(pdu)      \
34 	(!(pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
35 
36 /* Command/response PDU indicator in SSAP field */
37 #define LLC_PDU_CMD_RSP_MASK	0x01
38 #define LLC_PDU_CMD		0
39 #define LLC_PDU_RSP		1
40 #define LLC_PDU_IS_CMD(pdu)    ((pdu->ssap & LLC_PDU_RSP) ? 0 : 1)
41 #define LLC_PDU_IS_RSP(pdu)    ((pdu->ssap & LLC_PDU_RSP) ? 1 : 0)
42 
43 /* Get PDU type from 2 lowest-order bits of control field first byte */
44 #define LLC_PDU_TYPE_I_MASK    0x01	/* 16-bit control field */
45 #define LLC_PDU_TYPE_S_MASK    0x03
46 #define LLC_PDU_TYPE_U_MASK    0x03	/* 8-bit control field */
47 #define LLC_PDU_TYPE_MASK      0x03
48 
49 #define LLC_PDU_TYPE_I		0	/* first bit */
50 #define LLC_PDU_TYPE_S		1	/* first two bits */
51 #define LLC_PDU_TYPE_U		3	/* first two bits */
52 #define LLC_PDU_TYPE_U_XID	4	/* private type for detecting XID commands */
53 
54 #define LLC_PDU_TYPE_IS_I(pdu) \
55 	((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 1 : 0)
56 
57 #define LLC_PDU_TYPE_IS_U(pdu) \
58 	(((pdu->ctrl_1 & LLC_PDU_TYPE_U_MASK) == LLC_PDU_TYPE_U) ? 1 : 0)
59 
60 #define LLC_PDU_TYPE_IS_S(pdu) \
61 	(((pdu->ctrl_1 & LLC_PDU_TYPE_S_MASK) == LLC_PDU_TYPE_S) ? 1 : 0)
62 
63 /* U-format PDU control field masks */
64 #define LLC_U_PF_BIT_MASK      0x10	/* P/F bit mask */
65 #define LLC_U_PF_IS_1(pdu)     ((pdu->ctrl_1 & LLC_U_PF_BIT_MASK) ? 1 : 0)
66 #define LLC_U_PF_IS_0(pdu)     ((!(pdu->ctrl_1 & LLC_U_PF_BIT_MASK)) ? 1 : 0)
67 
68 #define LLC_U_PDU_CMD_MASK     0xEC	/* cmd/rsp mask */
69 #define LLC_U_PDU_CMD(pdu)     (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
70 #define LLC_U_PDU_RSP(pdu)     (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
71 
72 #define LLC_1_PDU_CMD_UI       0x00	/* Type 1 cmds/rsps */
73 #define LLC_1_PDU_CMD_XID      0xAC
74 #define LLC_1_PDU_CMD_TEST     0xE0
75 
76 #define LLC_2_PDU_CMD_SABME    0x6C	/* Type 2 cmds/rsps */
77 #define LLC_2_PDU_CMD_DISC     0x40
78 #define LLC_2_PDU_RSP_UA       0x60
79 #define LLC_2_PDU_RSP_DM       0x0C
80 #define LLC_2_PDU_RSP_FRMR     0x84
81 
82 /* Type 1 operations */
83 
84 /* XID information field bit masks */
85 
86 /* LLC format identifier (byte 1) */
87 #define LLC_XID_FMT_ID		0x81	/* first byte must be this */
88 
89 /* LLC types/classes identifier (byte 2) */
90 #define LLC_XID_CLASS_ZEROS_MASK	0xE0	/* these must be zeros */
91 #define LLC_XID_CLASS_MASK		0x1F	/* AND with byte to get below */
92 
93 #define LLC_XID_NULL_CLASS_1	0x01	/* if NULL LSAP...use these */
94 #define LLC_XID_NULL_CLASS_2	0x03
95 #define LLC_XID_NULL_CLASS_3	0x05
96 #define LLC_XID_NULL_CLASS_4	0x07
97 
98 #define LLC_XID_NNULL_TYPE_1	0x01	/* if non-NULL LSAP...use these */
99 #define LLC_XID_NNULL_TYPE_2	0x02
100 #define LLC_XID_NNULL_TYPE_3	0x04
101 #define LLC_XID_NNULL_TYPE_1_2	0x03
102 #define LLC_XID_NNULL_TYPE_1_3	0x05
103 #define LLC_XID_NNULL_TYPE_2_3	0x06
104 #define LLC_XID_NNULL_ALL		0x07
105 
106 /* Sender Receive Window (byte 3) */
107 #define LLC_XID_RW_MASK	0xFE	/* AND with value to get below */
108 
109 #define LLC_XID_MIN_RW	0x02	/* lowest-order bit always zero */
110 
111 /* Type 2 operations */
112 
113 #define LLC_2_SEQ_NBR_MODULO   ((u8) 128)
114 
115 /* I-PDU masks ('ctrl' is I-PDU control word) */
116 #define LLC_I_GET_NS(pdu)     (u8)((pdu->ctrl_1 & 0xFE) >> 1)
117 #define LLC_I_GET_NR(pdu)     (u8)((pdu->ctrl_2 & 0xFE) >> 1)
118 
119 #define LLC_I_PF_BIT_MASK      0x01
120 
121 #define LLC_I_PF_IS_0(pdu)     ((!(pdu->ctrl_2 & LLC_I_PF_BIT_MASK)) ? 1 : 0)
122 #define LLC_I_PF_IS_1(pdu)     ((pdu->ctrl_2 & LLC_I_PF_BIT_MASK) ? 1 : 0)
123 
124 /* S-PDU supervisory commands and responses */
125 
126 #define LLC_S_PDU_CMD_MASK     0x0C
127 #define LLC_S_PDU_CMD(pdu)     (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
128 #define LLC_S_PDU_RSP(pdu)     (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
129 
130 #define LLC_2_PDU_CMD_RR       0x00	/* rx ready cmd */
131 #define LLC_2_PDU_RSP_RR       0x00	/* rx ready rsp */
132 #define LLC_2_PDU_CMD_REJ      0x08	/* reject PDU cmd */
133 #define LLC_2_PDU_RSP_REJ      0x08	/* reject PDU rsp */
134 #define LLC_2_PDU_CMD_RNR      0x04	/* rx not ready cmd */
135 #define LLC_2_PDU_RSP_RNR      0x04	/* rx not ready rsp */
136 
137 #define LLC_S_PF_BIT_MASK      0x01
138 #define LLC_S_PF_IS_0(pdu)     ((!(pdu->ctrl_2 & LLC_S_PF_BIT_MASK)) ? 1 : 0)
139 #define LLC_S_PF_IS_1(pdu)     ((pdu->ctrl_2 & LLC_S_PF_BIT_MASK) ? 1 : 0)
140 
141 #define PDU_SUPV_GET_Nr(pdu)   ((pdu->ctrl_2 & 0xFE) >> 1)
142 #define PDU_GET_NEXT_Vr(sn)    (((sn) + 1) & ~LLC_2_SEQ_NBR_MODULO)
143 
144 /* FRMR information field macros */
145 
146 #define FRMR_INFO_LENGTH       5	/* 5 bytes of information */
147 
148 /*
149  * info is pointer to FRMR info field structure; 'rej_ctrl' is byte pointer
150  * (if U-PDU) or word pointer to rejected PDU control field
151  */
152 #define FRMR_INFO_SET_REJ_CNTRL(info,rej_ctrl) \
153 	info->rej_pdu_ctrl = ((*((u8 *) rej_ctrl) & \
154 				LLC_PDU_TYPE_U) != LLC_PDU_TYPE_U ? \
155 				(u16)*((u16 *) rej_ctrl) : \
156 				(((u16) *((u8 *) rej_ctrl)) & 0x00FF))
157 
158 /*
159  * Info is pointer to FRMR info field structure; 'vs' is a byte containing
160  * send state variable value in low-order 7 bits (insure the lowest-order
161  * bit remains zero (0))
162  */
163 #define FRMR_INFO_SET_Vs(info,vs) (info->curr_ssv = (((u8) vs) << 1))
164 #define FRMR_INFO_SET_Vr(info,vr) (info->curr_rsv = (((u8) vr) << 1))
165 
166 /*
167  * Info is pointer to FRMR info field structure; 'cr' is a byte containing
168  * the C/R bit value in the low-order bit
169  */
170 #define FRMR_INFO_SET_C_R_BIT(info, cr)  (info->curr_rsv |= (((u8) cr) & 0x01))
171 
172 /*
173  * In the remaining five macros, 'info' is pointer to FRMR info field
174  * structure; 'ind' is a byte containing the bit value to set in the
175  * lowest-order bit)
176  */
177 #define FRMR_INFO_SET_INVALID_PDU_CTRL_IND(info, ind) \
178        (info->ind_bits = ((info->ind_bits & 0xFE) | (((u8) ind) & 0x01)))
179 
180 #define FRMR_INFO_SET_INVALID_PDU_INFO_IND(info, ind) \
181        (info->ind_bits = ( (info->ind_bits & 0xFD) | (((u8) ind) & 0x02)))
182 
183 #define FRMR_INFO_SET_PDU_INFO_2LONG_IND(info, ind) \
184        (info->ind_bits = ( (info->ind_bits & 0xFB) | (((u8) ind) & 0x04)))
185 
186 #define FRMR_INFO_SET_PDU_INVALID_Nr_IND(info, ind) \
187        (info->ind_bits = ( (info->ind_bits & 0xF7) | (((u8) ind) & 0x08)))
188 
189 #define FRMR_INFO_SET_PDU_INVALID_Ns_IND(info, ind) \
190        (info->ind_bits = ( (info->ind_bits & 0xEF) | (((u8) ind) & 0x10)))
191 
192 /* Sequence-numbered PDU format (4 bytes in length) */
193 struct llc_pdu_sn {
194 	u8 dsap;
195 	u8 ssap;
196 	u8 ctrl_1;
197 	u8 ctrl_2;
198 } __packed;
199 
200 static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb)
201 {
202 	return (struct llc_pdu_sn *)skb_network_header(skb);
203 }
204 
205 /* Un-numbered PDU format (3 bytes in length) */
206 struct llc_pdu_un {
207 	u8 dsap;
208 	u8 ssap;
209 	u8 ctrl_1;
210 } __packed;
211 
212 static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
213 {
214 	return (struct llc_pdu_un *)skb_network_header(skb);
215 }
216 
217 /**
218  *	llc_pdu_header_init - initializes pdu header
219  *	@skb: input skb that header must be set into it.
220  *	@type: type of PDU (U, I or S).
221  *	@ssap: source sap.
222  *	@dsap: destination sap.
223  *	@cr: command/response bit (0 or 1).
224  *
225  *	This function sets DSAP, SSAP and command/Response bit in LLC header.
226  */
227 static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,
228 				       u8 ssap, u8 dsap, u8 cr)
229 {
230 	int hlen = 4; /* default value for I and S types */
231 	struct llc_pdu_un *pdu;
232 
233 	switch (type) {
234 	case LLC_PDU_TYPE_U:
235 		hlen = 3;
236 		break;
237 	case LLC_PDU_TYPE_U_XID:
238 		hlen = 6;
239 		break;
240 	}
241 
242 	skb_push(skb, hlen);
243 	skb_reset_network_header(skb);
244 	pdu = llc_pdu_un_hdr(skb);
245 	pdu->dsap = dsap;
246 	pdu->ssap = ssap;
247 	pdu->ssap |= cr;
248 }
249 
250 /**
251  *	llc_pdu_decode_sa - extracts, source address (MAC) of input frame
252  *	@skb: input skb that source address must be extracted from it.
253  *	@sa: pointer to source address (6 byte array).
254  *
255  *	This function extracts source address(MAC) of input frame.
256  */
257 static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
258 {
259 	memcpy(sa, eth_hdr(skb)->h_source, ETH_ALEN);
260 }
261 
262 /**
263  *	llc_pdu_decode_da - extracts dest address of input frame
264  *	@skb: input skb that destination address must be extracted from it
265  *	@da: pointer to destination address (6 byte array).
266  *
267  *	This function extracts destination address(MAC) of input frame.
268  */
269 static inline void llc_pdu_decode_da(struct sk_buff *skb, u8 *da)
270 {
271 	memcpy(da, eth_hdr(skb)->h_dest, ETH_ALEN);
272 }
273 
274 /**
275  *	llc_pdu_decode_ssap - extracts source SAP of input frame
276  *	@skb: input skb that source SAP must be extracted from it.
277  *	@ssap: source SAP (output argument).
278  *
279  *	This function extracts source SAP of input frame. Right bit of SSAP is
280  *	command/response bit.
281  */
282 static inline void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
283 {
284 	*ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE;
285 }
286 
287 /**
288  *	llc_pdu_decode_dsap - extracts dest SAP of input frame
289  *	@skb: input skb that destination SAP must be extracted from it.
290  *	@dsap: destination SAP (output argument).
291  *
292  *	This function extracts destination SAP of input frame. right bit of
293  *	DSAP designates individual/group SAP.
294  */
295 static inline void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
296 {
297 	*dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE;
298 }
299 
300 /**
301  *	llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU
302  *	@skb: input skb that header must be set into it.
303  *
304  *	This function sets third byte of LLC header as a UI PDU.
305  */
306 static inline void llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
307 {
308 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
309 
310 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
311 	pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
312 }
313 
314 /**
315  *	llc_pdu_init_as_test_cmd - sets PDU as TEST
316  *	@skb: Address of the skb to build
317  *
318  * 	Sets a PDU as TEST
319  */
320 static inline void llc_pdu_init_as_test_cmd(struct sk_buff *skb)
321 {
322 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
323 
324 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
325 	pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
326 	pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
327 }
328 
329 /**
330  *	llc_pdu_init_as_test_rsp - build TEST response PDU
331  *	@skb: Address of the skb to build
332  *	@ev_skb: The received TEST command PDU frame
333  *
334  *	Builds a pdu frame as a TEST response.
335  */
336 static inline void llc_pdu_init_as_test_rsp(struct sk_buff *skb,
337 					    struct sk_buff *ev_skb)
338 {
339 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
340 
341 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
342 	pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
343 	pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
344 	if (ev_skb->protocol == htons(ETH_P_802_2)) {
345 		struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb);
346 		int dsize;
347 
348 		dsize = ntohs(eth_hdr(ev_skb)->h_proto) - 3;
349 		memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize);
350 		skb_put(skb, dsize);
351 	}
352 }
353 
354 /* LLC Type 1 XID command/response information fields format */
355 struct llc_xid_info {
356 	u8 fmt_id;	/* always 0x81 for LLC */
357 	u8 type;	/* different if NULL/non-NULL LSAP */
358 	u8 rw;		/* sender receive window */
359 } __packed;
360 
361 /**
362  *	llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID
363  *	@skb: input skb that header must be set into it.
364  *	@svcs_supported: The class of the LLC (I or II)
365  *	@rx_window: The size of the receive window of the LLC
366  *
367  *	This function sets third,fourth,fifth and sixth bytes of LLC header as
368  *	a XID PDU.
369  */
370 static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
371 					   u8 svcs_supported, u8 rx_window)
372 {
373 	struct llc_xid_info *xid_info;
374 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
375 
376 	pdu->ctrl_1	 = LLC_PDU_TYPE_U;
377 	pdu->ctrl_1	|= LLC_1_PDU_CMD_XID;
378 	pdu->ctrl_1	|= LLC_U_PF_BIT_MASK;
379 	xid_info	 = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
380 	xid_info->fmt_id = LLC_XID_FMT_ID;	/* 0x81 */
381 	xid_info->type	 = svcs_supported;
382 	xid_info->rw	 = rx_window << 1;	/* size of receive window */
383 
384 	/* no need to push/put since llc_pdu_header_init() has already
385 	 * pushed 3 + 3 bytes
386 	 */
387 }
388 
389 /**
390  *	llc_pdu_init_as_xid_rsp - builds XID response PDU
391  *	@skb: Address of the skb to build
392  *	@svcs_supported: The class of the LLC (I or II)
393  *	@rx_window: The size of the receive window of the LLC
394  *
395  *	Builds a pdu frame as an XID response.
396  */
397 static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb,
398 					   u8 svcs_supported, u8 rx_window)
399 {
400 	struct llc_xid_info *xid_info;
401 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
402 
403 	pdu->ctrl_1	 = LLC_PDU_TYPE_U;
404 	pdu->ctrl_1	|= LLC_1_PDU_CMD_XID;
405 	pdu->ctrl_1	|= LLC_U_PF_BIT_MASK;
406 
407 	xid_info	 = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
408 	xid_info->fmt_id = LLC_XID_FMT_ID;
409 	xid_info->type	 = svcs_supported;
410 	xid_info->rw	 = rx_window << 1;
411 	skb_put(skb, sizeof(struct llc_xid_info));
412 }
413 
414 /* LLC Type 2 FRMR response information field format */
415 struct llc_frmr_info {
416 	u16 rej_pdu_ctrl;	/* bits 1-8 if U-PDU */
417 	u8  curr_ssv;		/* current send state variable val */
418 	u8  curr_rsv;		/* current receive state variable */
419 	u8  ind_bits;		/* indicator bits set with macro */
420 } __packed;
421 
422 void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type);
423 void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value);
424 void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit);
425 void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit);
426 void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr);
427 void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
428 void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
429 void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
430 void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit);
431 void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit);
432 void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
433 			      u8 f_bit, u8 vs, u8 vr, u8 vzyxw);
434 void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
435 void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
436 void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
437 void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit);
438 #endif /* LLC_PDU_H */
439