Revert "datapath-windows: Support attribute OVS_KEY_ATTR_TCP_FLAGS"
[cascardo/ovs.git] / datapath-windows / ovsext / PacketParser.h
1 /*
2  * Copyright (c) 2014 VMware, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __PACKET_PARSER_H_
18 #define __PACKET_PARSER_H_ 1
19
20 #include "precomp.h"
21 #include "NetProto.h"
22
23 const VOID* OvsGetPacketBytes(const NET_BUFFER_LIST *_pNB, UINT32 len,
24                               UINT32 SrcOffset, VOID *storage);
25 NDIS_STATUS OvsParseIPv6(const NET_BUFFER_LIST *packet, OvsFlowKey *key,
26                         POVS_PACKET_HDR_INFO layers);
27 VOID OvsParseTcp(const NET_BUFFER_LIST *packet, L4Key *flow,
28                  POVS_PACKET_HDR_INFO layers);
29 VOID OvsParseUdp(const NET_BUFFER_LIST *packet, L4Key *flow,
30                  POVS_PACKET_HDR_INFO layers);
31 NDIS_STATUS OvsParseIcmpV6(const NET_BUFFER_LIST *packet, OvsFlowKey *key,
32                             POVS_PACKET_HDR_INFO layers);
33
34 static __inline ULONG
35 OvsPacketLenNBL(const NET_BUFFER_LIST *_pNB)
36 {
37     INT length = 0;
38     NET_BUFFER *nb;
39
40     nb = NET_BUFFER_LIST_FIRST_NB(_pNB);
41     ASSERT(nb);
42     while(nb) {
43         length += NET_BUFFER_DATA_LENGTH(nb);
44         nb = NET_BUFFER_NEXT_NB(nb);
45     }
46
47     return length;
48 }
49
50 /*
51  * Returns the ctl field from the TCP header in 'packet', or 0 if the field
52  * can't be read.  The caller must have ensured that 'packet' contains a TCP
53  * header.
54  *
55  * We can't just use TCPHdr, from netProto.h, for this because that
56  * breaks the flags down into individual bit-fields.  We can't even use
57  * offsetof because that will try to take the address of a bit-field,
58  * which C does not allow.
59  */
60 static UINT16
61 OvsGetTcpCtl(const NET_BUFFER_LIST *packet, // IN
62              const POVS_PACKET_HDR_INFO layers) // IN
63 {
64 #define TCP_CTL_OFS 12                // Offset of "ctl" field in TCP header.
65 #define TCP_FLAGS(CTL) ((CTL) & 0x3f) // Obtain TCP flags from CTL.
66
67     const UINT16 *ctl;
68     UINT16 storage;
69
70     ctl = OvsGetPacketBytes(packet, sizeof *ctl, layers->l4Offset + TCP_CTL_OFS,
71                          &storage);
72     return ctl ? *ctl : 0;
73 }
74
75
76 static UINT8
77 OvsGetTcpFlags(const NET_BUFFER_LIST *packet,    // IN
78                const OvsFlowKey *key,   // IN
79                const POVS_PACKET_HDR_INFO layers) // IN
80 {
81     UNREFERENCED_PARAMETER(key); // should be removed later
82
83     if (layers->isTcp) {
84         return TCP_FLAGS(OvsGetTcpCtl(packet, layers));
85     } else {
86         return 0;
87     }
88 }
89
90 static const EtherArp *
91 OvsGetArp(const NET_BUFFER_LIST *packet,
92           UINT32 ofs,
93           EtherArp *storage)
94 {
95     return OvsGetPacketBytes(packet, sizeof *storage, ofs, storage);
96 }
97
98 static const IPHdr *
99 OvsGetIp(const NET_BUFFER_LIST *packet,
100          UINT32 ofs,
101          IPHdr *storage)
102 {
103     const IPHdr *ip = OvsGetPacketBytes(packet, sizeof *ip, ofs, storage);
104     if (ip) {
105         int ipLen = ip->ihl * 4;
106         if (ipLen >= sizeof *ip && OvsPacketLenNBL(packet) >= ofs + ipLen) {
107             return ip;
108         }
109     }
110     return NULL;
111 }
112
113 static const TCPHdr *
114 OvsGetTcp(const NET_BUFFER_LIST *packet,
115           UINT32 ofs,
116           TCPHdr *storage)
117 {
118     const TCPHdr *tcp = OvsGetPacketBytes(packet, sizeof *tcp, ofs, storage);
119     if (tcp) {
120         int tcpLen = tcp->doff * 4;
121         if (tcpLen >= sizeof *tcp && OvsPacketLenNBL(packet) >= ofs + tcpLen) {
122             return tcp;
123         }
124     }
125     return NULL;
126 }
127
128 static const UDPHdr *
129 OvsGetUdp(const NET_BUFFER_LIST *packet,
130           UINT32 ofs,
131           UDPHdr *storage)
132 {
133     return OvsGetPacketBytes(packet, sizeof *storage, ofs, storage);
134 }
135
136 static const ICMPHdr *
137 OvsGetIcmp(const NET_BUFFER_LIST *packet,
138            UINT32 ofs,
139            ICMPHdr *storage)
140 {
141     return OvsGetPacketBytes(packet, sizeof *storage, ofs, storage);
142 }
143
144 #endif /* __PACKET_PARSER_H_ */