1#ifndef _CONNTRACK_PROTO_GRE_H
2#define _CONNTRACK_PROTO_GRE_H
3#include <asm/byteorder.h>
4
5/* GRE PROTOCOL HEADER */
6
7/* GRE Version field */
8#define GRE_VERSION_1701	0x0
9#define GRE_VERSION_PPTP	0x1
10
11/* GRE Protocol field */
12#define GRE_PROTOCOL_PPTP	0x880B
13
14/* GRE Flags */
15#define GRE_FLAG_C		0x80
16#define GRE_FLAG_R		0x40
17#define GRE_FLAG_K		0x20
18#define GRE_FLAG_S		0x10
19#define GRE_FLAG_A		0x80
20
21#define GRE_IS_C(f)	((f)&GRE_FLAG_C)
22#define GRE_IS_R(f)	((f)&GRE_FLAG_R)
23#define GRE_IS_K(f)	((f)&GRE_FLAG_K)
24#define GRE_IS_S(f)	((f)&GRE_FLAG_S)
25#define GRE_IS_A(f)	((f)&GRE_FLAG_A)
26
27/* GRE is a mess: Four different standards */
28struct gre_hdr {
29#if defined(__LITTLE_ENDIAN_BITFIELD)
30	__u16	rec:3,
31		srr:1,
32		seq:1,
33		key:1,
34		routing:1,
35		csum:1,
36		version:3,
37		reserved:4,
38		ack:1;
39#elif defined(__BIG_ENDIAN_BITFIELD)
40	__u16	csum:1,
41		routing:1,
42		key:1,
43		seq:1,
44		srr:1,
45		rec:3,
46		ack:1,
47		reserved:4,
48		version:3;
49#else
50#error "Adjust your <asm/byteorder.h> defines"
51#endif
52	__u16	protocol;
53};
54
55/* modified GRE header for PPTP */
56struct gre_hdr_pptp {
57	__u8  flags;		/* bitfield */
58	__u8  version;		/* should be GRE_VERSION_PPTP */
59	__u16 protocol;		/* should be GRE_PROTOCOL_PPTP */
60	__u16 payload_len;	/* size of ppp payload, not inc. gre header */
61	__u16 call_id;		/* peer's call_id for this session */
62	__u32 seq;		/* sequence number.  Present if S==1 */
63	__u32 ack;		/* seq number of highest packet recieved by */
64				/*  sender in this session */
65};
66
67
68/* this is part of ip_conntrack */
69struct ip_ct_gre {
70	unsigned int stream_timeout;
71	unsigned int timeout;
72};
73
74/* this is part of ip_conntrack_expect */
75struct ip_ct_gre_expect {
76	struct ip_ct_gre_keymap *keymap_orig, *keymap_reply;
77};
78
79#ifdef __KERNEL__
80
81/* structure for original <-> reply keymap */
82struct ip_ct_gre_keymap {
83	struct list_head list;
84
85	struct ip_conntrack_tuple tuple;
86	struct ip_conntrack_expect *master;
87};
88
89
90/* add new tuple->key_reply pair to keymap */
91int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp,
92			 struct ip_conntrack_tuple *t,
93			 int reply);
94
95/* change an existing keymap entry */
96void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km,
97			     struct ip_conntrack_tuple *t);
98
99
100
101/* get pointer to gre key, if present */
102static inline u_int32_t *gre_key(struct gre_hdr *greh)
103{
104	if (!greh->key)
105		return NULL;
106	if (greh->csum || greh->routing)
107		return (u_int32_t *) (greh+sizeof(*greh)+4);
108	return (u_int32_t *) (greh+sizeof(*greh));
109}
110
111/* get pointer ot gre csum, if present */
112static inline u_int16_t *gre_csum(struct gre_hdr *greh)
113{
114	if (!greh->csum)
115		return NULL;
116	return (u_int16_t *) (greh+sizeof(*greh));
117}
118
119#endif /* __KERNEL__ */
120
121#endif /* _CONNTRACK_PROTO_GRE_H */
122