1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
/* if_ether.h needed for definition of ETH_DATA_LEN and ETH_ALEN
*/
#include "linux/if_ether.h"
/* frame layout based on par3.2 "LLC PDU format"
*/
typedef union { /* pdu layout from pages 40 & 44 */
struct { /* general header, all pdu types */
unsigned dsap : 8; /* dest service access point */
unsigned ssap : 8; /* source service access point */
unsigned f1 : 1; /* I- U- or S- format id bits */
unsigned f2 : 1;
unsigned : 6;
unsigned : 8;
} pdu_hdr;
struct {
char dummy1[2]; /* dsap + ssap */
char byte1;
char byte2;
} pdu_cntl; /* unformatted control bytes */
struct { /* header of an Information pdu */
unsigned char dummy2[2];
unsigned : 1;
unsigned ns : 7;
unsigned i_pflag : 1; /* poll/final bit */
unsigned nr : 7; /* N(R) */
unsigned char is_info[ ETH_DATA_LEN ];
} i_hdr;
struct { /* header of a Supervisory pdu */
unsigned char dummy3[2];
unsigned : 2;
unsigned ss : 2; /* supervisory function bits */
unsigned : 4;
unsigned s_pflag : 1; /* poll/final bit */
unsigned nr : 7; /* N(R) */
} s_hdr;
/* when accessing the P/F bit or the N(R) field there's no need to distinguish
I pdus from S pdus i_pflag and s_pflag / i_nr and s_nr map to the same
physical location.
*/
struct { /* header of an Unnumbered pdu */
unsigned char dummy4[2];
unsigned : 2;
unsigned mm1 : 2; /* modifier function part1 */
unsigned u_pflag : 1; /* P/F for U- pdus */
unsigned mm2 : 3; /* modifier function part2 */
unsigned char u_info[ ETH_DATA_LEN-1];
} u_hdr;
struct { /* mm field in an Unnumbered pdu */
unsigned char dummy5[2];
unsigned : 2;
unsigned mm : 6; /* must be masked to get ridd of P/F ! */
} u_mm;
} frame_type, *frameptr;
/* frame format test macros: */
#define IS_UFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & ( (fr)->pdu_hdr.f2) )
#define IS_IFRAME( fr ) ( !( (fr)->pdu_hdr.f1) )
#define IS_SFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & !( (fr)->pdu_hdr.f2) )
#define IS_RSP( fr ) ( fr->pdu_hdr.ssap & 0x01 )
/* The transition table, the _encode tables and some tests in the
source code depend on the numeric order of these values.
Think twice before changing.
*/
/* frame names for TYPE 2 operation: */
#define I_CMD 0
#define RR_CMD 1
#define RNR_CMD 2
#define REJ_CMD 3
#define DISC_CMD 4
#define SABME_CMD 5
#define I_RSP 6
#define RR_RSP 7
#define RNR_RSP 8
#define REJ_RSP 9
#define UA_RSP 10
#define DM_RSP 11
#define FRMR_RSP 12
/* junk frame name: */
#define BAD_FRAME 13
#define NO_FRAME 13
/* frame names for TYPE 1 operation: */
#define UI_CMD 14
#define XID_CMD 15
#define TEST_CMD 16
#define XID_RSP 17
#define TEST_RSP 18
|