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