1 //--------------------------------------------------------------------------
2 // Copyright (C) 2016-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation. You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 //--------------------------------------------------------------------------
18
19 //dce_tcp.h author Maya Dagon <mdagon@cisco.com>
20 // based on work by Todd Wease
21
22 #ifndef DCE_UDP_H
23 #define DCE_UDP_H
24
25 #include "profiler/profiler_defs.h"
26
27 #include "dce_common.h"
28
29 #define DCE2_UDP_NAME "dce_udp"
30 #define DCE2_UDP_HELP "dce over udp inspection"
31
32 #define DCE2_MOCK_HDR_LEN__CL (sizeof(DceRpcClHdr))
33
34 struct dce2UdpStats
35 {
36 /* The common stats block has to be at the beginning followed
37 by the protocol specific stats */
38
39 /*common stats -defined in common.h*/
40 PegCount events;
41
42 /*DCE UDP specific*/
43 PegCount udp_sessions;
44 PegCount udp_pkts;
45 PegCount cl_request;
46 PegCount cl_ack;
47 PegCount cl_cancel;
48 PegCount cl_cli_fack;
49 PegCount cl_ping;
50 PegCount cl_response;
51 PegCount cl_reject;
52 PegCount cl_cancel_ack;
53 PegCount cl_srv_fack;
54 PegCount cl_fault;
55 PegCount cl_nocall;
56 PegCount cl_working;
57 PegCount cl_other_req;
58 PegCount cl_other_resp;
59 PegCount cl_fragments;
60 PegCount cl_max_frag_size;
61 PegCount cl_frag_reassembled;
62 PegCount cl_max_seqnum;
63 PegCount concurrent_sessions;
64 PegCount max_concurrent_sessions;
65 };
66
67 extern THREAD_LOCAL dce2UdpStats dce2_udp_stats;
68 extern THREAD_LOCAL snort::ProfileStats dce2_udp_pstat_main;
69
70 struct DceRpcClHdr /* Connectionless header */
71 {
72 uint8_t rpc_vers;
73 uint8_t ptype;
74 uint8_t flags1;
75 uint8_t flags2;
76 uint8_t drep[3];
77 uint8_t serial_hi;
78 Uuid object;
79 Uuid if_id;
80 Uuid act_id;
81 uint32_t server_boot;
82 uint32_t if_vers;
83 uint32_t seqnum;
84 uint16_t opnum;
85 uint16_t ihint;
86 uint16_t ahint;
87 uint16_t len;
88 uint16_t fragnum;
89 uint8_t auth_proto;
90 uint8_t serial_lo;
91 };
92
93 enum DceRpcClFlags1
94 {
95 DCERPC_CL_FLAGS1__RESERVED_01 = 0x01,
96 DCERPC_CL_FLAGS1__LASTFRAG = 0x02,
97 DCERPC_CL_FLAGS1__FRAG = 0x04,
98 DCERPC_CL_FLAGS1__NOFACK = 0x08,
99 DCERPC_CL_FLAGS1__MAYBE = 0x10,
100 DCERPC_CL_FLAGS1__IDEMPOTENT = 0x20,
101 DCERPC_CL_FLAGS1__BROADCAST = 0x40,
102 DCERPC_CL_FLAGS1__RESERVED_80 = 0x80
103 };
104
DceRpcClRpcVers(const DceRpcClHdr * cl)105 inline uint8_t DceRpcClRpcVers(const DceRpcClHdr* cl)
106 {
107 return cl->rpc_vers;
108 }
109
DceRpcClPduType(const DceRpcClHdr * cl)110 inline uint8_t DceRpcClPduType(const DceRpcClHdr* cl)
111 {
112 return cl->ptype;
113 }
114
DceRpcClByteOrder(const DceRpcClHdr * cl)115 inline DceRpcBoFlag DceRpcClByteOrder(const DceRpcClHdr* cl)
116 {
117 return DceRpcByteOrder(cl->drep[0]);
118 }
119
DceRpcClLen(const DceRpcClHdr * cl)120 inline uint16_t DceRpcClLen(const DceRpcClHdr* cl)
121 {
122 return DceRpcNtohs(&cl->len, DceRpcClByteOrder(cl));
123 }
124
DceRpcClOpnum(const DceRpcClHdr * cl)125 inline uint16_t DceRpcClOpnum(const DceRpcClHdr* cl)
126 {
127 return DceRpcNtohs(&cl->opnum, DceRpcClByteOrder(cl));
128 }
129
DceRpcClSeqNum(const DceRpcClHdr * cl)130 inline uint32_t DceRpcClSeqNum(const DceRpcClHdr* cl)
131 {
132 return DceRpcNtohl(&cl->seqnum, DceRpcClByteOrder(cl));
133 }
134
DceRpcClIface(const DceRpcClHdr * cl)135 inline const Uuid* DceRpcClIface(const DceRpcClHdr* cl)
136 {
137 return &cl->if_id;
138 }
139
DceRpcClIfaceVers(const DceRpcClHdr * cl)140 inline uint32_t DceRpcClIfaceVers(const DceRpcClHdr* cl)
141 {
142 return DceRpcNtohl(&cl->if_vers, DceRpcClByteOrder(cl));
143 }
144
DceRpcClFragNum(const DceRpcClHdr * cl)145 inline uint16_t DceRpcClFragNum(const DceRpcClHdr* cl)
146 {
147 return DceRpcNtohs(&cl->fragnum, DceRpcClByteOrder(cl));
148 }
149
DceRpcClFragFlag(const DceRpcClHdr * cl)150 inline int DceRpcClFragFlag(const DceRpcClHdr* cl)
151 {
152 return cl->flags1 & DCERPC_CL_FLAGS1__FRAG;
153 }
154
DceRpcClFirstFrag(const DceRpcClHdr * cl)155 inline bool DceRpcClFirstFrag(const DceRpcClHdr* cl)
156 {
157 return (DceRpcClFragFlag(cl) && (DceRpcClFragNum(cl) == 0));
158 }
159
DceRpcClLastFrag(const DceRpcClHdr * cl)160 inline int DceRpcClLastFrag(const DceRpcClHdr* cl)
161 {
162 return cl->flags1 & DCERPC_CL_FLAGS1__LASTFRAG;
163 }
164
DceRpcClFrag(const DceRpcClHdr * cl)165 inline bool DceRpcClFrag(const DceRpcClHdr* cl)
166 {
167 if (DceRpcClFragFlag(cl))
168 {
169 if (DceRpcClLastFrag(cl) && (DceRpcClFragNum(cl) == 0))
170 return false;
171
172 return true;
173 }
174
175 return false;
176 }
177
178 struct DCE2_ClTracker
179 {
180 DCE2_List* act_trackers; /* List of activity trackers */
181 };
182
183 struct DCE2_UdpSsnData
184 {
185 DCE2_SsnData sd; // This member must be first
186 DCE2_ClTracker cl_tracker;
187 };
188
189 class Dce2UdpFlowData : public snort::FlowData
190 {
191 public:
192 Dce2UdpFlowData();
193 ~Dce2UdpFlowData() override;
194
init()195 static void init()
196 { inspector_id = snort::FlowData::create_flow_data_id(); }
197
198 static unsigned inspector_id;
199 DCE2_UdpSsnData dce2_udp_session;
200 };
201
202 DCE2_UdpSsnData* get_dce2_udp_session_data(snort::Flow*);
203
204 void DCE2_ClProcess(DCE2_SsnData* sd, DCE2_ClTracker* clt);
205 void DCE2_ClInitRdata(uint8_t*);
206
207 #endif
208
209