1 /****************************************************************************
2  *
3  * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
4  * Copyright (C) 2005-2013 Sourcefire, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License Version 2 as
8  * published by the Free Software Foundation.  You may not use, modify or
9  * distribute this program under any other version of the GNU General
10  * Public License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  *
21  ****************************************************************************/
22 
23 /*
24   sfportobject.h
25 
26   Port List Object Management
27 
28   author: marc norton
29 
30   Hierarchy:
31 
32 	PortTable -> PortObject's
33 
34 	PortVar -> PortObject
35 
36 	PortObject -> PortObjectItems (port or port range)
37 
38  */
39 #ifndef SFPORTOBJECT_H
40 #define SFPORTOBJECT_H
41 
42 #include "sflsq.h"
43 #include "sfghash.h"
44 
45 #ifdef HAVE_CONFIG_H
46 #include "config.h"
47 #endif
48 
49 #define SFPO_MAX_LPORTS 500
50 #define SFPO_MAX_PORTS 65536
51 
52 typedef SFGHASH  PortVarTable;
53 
54 /*
55  * PortObjectItem Flags
56  */
57 #define PORT_OBJECT_NOT_FLAG 1
58 
59 #define PORT_OBJECT_PORT  1
60 #define PORT_OBJECT_RANGE 2
61 #define PORT_OBJECT_ANY   3
62 
63 /*
64  * Port Object Item supports
65  * port, lowport:highport, portlist
66  */
67 typedef struct _PortObjectItem_s {
68 
69     int type;       /*  ANY, RANGE, PORT */
70     int flags;       /* NOT */
71 
72     uint16_t hport;   /* hi port */
73     uint16_t lport;   /* lo port */
74 
75     uint16_t cur_port; /* internal - first/next */
76     uint16_t tmp;
77 
78 }PortObjectItem;
79 
80 
81 /*
82 *  PortObject supports a set of PortObjectItems
83 *
84 *  A Port Set may include one or more of the following
85 *      Port
86 *      Port Range
87 *      List of Ports mixed with Port Ranges
88 */
89 #include "bitop_funcs.h"
90 
91 typedef struct { /* not used yet */
92 	char           * name;      /* user name - always use strdup or malloc for this*/
93     SF_LIST        * item_list; /* list of port and port-range items */
94 }PortList_x;
95 
96 typedef struct {
97 	char           * name;      /* user name - always use strdup or malloc for this*/
98 	int              id;        /* internal tracking - compiling sets this value */
99     SF_LIST        * item_list; /* list of port and port-range items */
100     SF_LIST        * rule_list; /* list of rules  */
101     void           * data;      /* user data, PORT_GROUP based on rule_list - only used by any-any ports */
102     void           (*data_free)(void *);
103 }PortObject;
104 
105 typedef struct  {
106 	char           * name;      /* user name - always use strdup or malloc for this*/
107 	int              id;        /* internal tracking - compiling sets this value */
108     SF_LIST        * item_list; /* list of port and port-range items */
109     SFGHASH        * rule_hash; /* hash of rule (rule-indexes) in use */
110     int              port_cnt;  /* count of ports using this object */
111     BITOP          * bitop;     /* for collecting ports that use this object */
112     void           * data;      /* user data, PORT_GROUP based on rule_hash  */
113     void           (*data_free)(void *);
114 }PortObject2;
115 
116 /*
117     Port Table
118 */
119 typedef struct _PortTable_s {
120 
121     /* turns on group optimization, better speed-but more memory
122      * otherwise a single merged rule group is used.
123      */
124     int pt_optimize;
125 
126     /* save the users input port objects in this list
127      * rules may be added after creation of a port object
128      * but the ports are not modified.
129      */
130     SF_LIST * pt_polist;
131     int       pt_poid;
132 
133     /*
134     * Array of lists of PortObject pointers to unique PortObjects,
135     * the associated rule lists are stored in Data elements in rh,
136     * the keys are the address of the PortObjects
137     */
138     SF_LIST * pt_port_lists[SFPO_MAX_PORTS];
139 
140     /* Compiled / merged port object hash table */
141     SFGHASH * pt_mpo_hash;
142     SFGHASH * pt_mpxo_hash;
143 
144     SF_LIST * pt_plx_list;
145 
146     /*  a single rule list with all rules merged together */
147     SF_LIST * pt_merged_rule_list;
148 
149     /*
150     * Final Port/Rule Groupings, one port object per port, or null
151     */
152     PortObject2 * pt_port_object[SFPO_MAX_PORTS];
153 
154     int pt_lrc; /* large rule count, this many rules is a large group */
155 
156     /* Stats */
157     int single_merges; /* single PortObject on a port */
158     int small_merges;  /* small port objects merged into a bigger object */
159     int large_single_merges; /* 1 large + some small objects */
160     int large_multi_merges; /* >1 large object merged + some small objects */
161     int non_opt_merges;
162 
163 }PortTable;
164 
165 typedef struct {
166 
167     PortTable * tcp_src, * tcp_dst;
168     PortTable * udp_src, * udp_dst;
169     PortTable * icmp_src,* icmp_dst;
170     PortTable * ip_src,  * ip_dst;
171 
172 #ifdef TARGET_BASED
173     PortTable * ns_tcp_src, * ns_tcp_dst;
174     PortTable * ns_udp_src, * ns_udp_dst;
175     PortTable * ns_icmp_src,* ns_icmp_dst;
176     PortTable * ns_ip_src,  * ns_ip_dst;
177 #endif
178 
179     PortObject * tcp_anyany;
180     PortObject * udp_anyany;
181     PortObject * icmp_anyany;
182     PortObject * ip_anyany;
183 
184     PortObject * tcp_nocontent;
185     PortObject * udp_nocontent;
186     PortObject * icmp_nocontent;
187     PortObject * ip_nocontent;
188 
189 }rule_port_tables_t;
190 
191 
192 #define POPERR_NO_NAME            1
193 #define POPERR_NO_ENDLIST_BRACKET 2
194 #define POPERR_NOT_A_NUMBER       3
195 #define POPERR_EXTRA_BRACKET      4
196 #define POPERR_NO_DATA            5
197 #define POPERR_ADDITEM_FAILED     6
198 #define POPERR_MALLOC_FAILED      7
199 #define POPERR_INVALID_RANGE      8
200 #define POPERR_DUPLICATE_ENTRY    9
201 #define POPERR_BOUNDS             10
202 #define POPERR_BAD_VARIABLE       11
203 
204 #define POP_MAX_BUFFER_SIZE 256
205 typedef struct {
206     char * s;         /* current string pointer */
207     int    slen;      /* bytes left in string */
208     int    pos;       /* position in string of last GetChar() */
209     char   token[POP_MAX_BUFFER_SIZE+4]; /* single number, or range, or not flag */
210     int    errflag;
211     /* for handling PortObject references when parsing */
212     PortObject   * po_ref;
213     SF_LNODE     * poi_pos;
214     PortVarTable * pvTable;
215 }POParser;
216 
217 /*
218 	Prototypes
219 */
220 
221 /*
222 *   Port List Table
223 *
224 *    The PortTable provides support to analyze the Port List objects defined by
225 *    the user as either PortVar entries or simply as inline rule port
226 *    list declarations.
227 */
228 PortTable  * PortTableNew      (void);
229 void         PortTableFree( PortTable  *p );
230 int          PortTableAddObject( PortTable *p, PortObject * po );
231 int          PortTableAddObjectRaw( PortTable *p, PortObject * po );
232 int          PortTableAddRule  ( PortTable * p, int port, int rule );
233 int          PortTableCompile  ( PortTable * P);
234 void         PortTablePrintInputEx( PortTable * p,
235                     void (*rule_index_map_print)(int index, char *buf, int bufsize) );
236 int          PortTablePrintCompiledEx( PortTable * p,
237                     void (*rule_index_map_print)(int index, char *buf, int bufsize) );
238 PortObject * PortTableFindPortObjectByPort( PortTable * pt , int port );
239 PortObject * PortTableFindInputPortObjectName(PortTable * pt, char * po_name);
240 PortObject * PortTableFindInputPortObjectPorts( PortTable * pt , PortObject * po );
241 /*
242     Port List Object
243 */
244 PortObject     * PortObjectNew        ( void );
245 PortObject2    * PortObject2New       (int nrules/*guess at this */);
246 void             PortObjectFree       ( void *  p );
247 void             PortObject2Free      ( void *  p );
248 int              PortObjectSetName    ( PortObject * po,  char * name );
249 PortObjectItem * PortObjectItemNew    ( void );
250 PortObjectItem * PortObjectItemDup    ( PortObjectItem * poi );
251 void             PortObjectItemFree    ( PortObjectItem * poi );
252 int              PortObjectAddItem    ( PortObject * po, PortObjectItem * poi, int *errflag);
253 int              PortObjectAddPortObject ( PortObject * podst, PortObject * posrc, int *errflag);
254 int              PortObjectAddPort    ( PortObject * po, int port, int not_flag );
255 int              PortObjectAddRange   ( PortObject * po, int lport, int hport, int not_flag );
256 int              PortObjectAddRule    ( PortObject * po, int rule );
257 int              PortObjectAddPortAny ( PortObject * po );
258 PortObject     * PortObjectDup        ( PortObject * po );
259 PortObject2    * PortObject2Dup       ( PortObject * po );
260 PortObject     * PortObjectDupPorts   ( PortObject * po );
261 int            * PortObjectExtractRuleArray( PortObject * po, int * nrules );
262 int            * PortObject2ExtractRuleArray( PortObject2 * po, int * nrules );
263 
264 int              PortObjectNormalize   ( PortObject * po );
265 int              PortObjectNegate      ( PortObject * po );
266 int              PortObjectEqual       ( PortObject * poa, PortObject * bob );
267 
268 void             PortObjectSetAny      ( PortObject * po );
269 int              PortObjectPortCount   ( PortObject * po );
270 int              PortObjectHasPort     ( PortObject * po, int port );
271 int              PortObjectHasNot      ( PortObject * po );
272 int              PortObjectIsPureNot   ( PortObject * po );
273 int              PortObjectHasAny      ( PortObject * po );
274 int              PortObjectIncludesPort(PortObject * po, int port );
275 char           * PortObjectCharPortArray ( char * parray, PortObject * po, int * nports );
276 int              PortObjectRemovePorts( PortObject * a,  PortObject * b );
277 PortObject     * PortObjectAppend(PortObject * poa, PortObject * pob );
278 PortObject     * PortObjectAppendPortObject(PortObject * poa, PortObject * pob );
279 PortObject2    * PortObject2AppendPortObject(PortObject2 * poa, PortObject * pob );
280 PortObject2    * PortObject2AppendPortObject2(PortObject2 * poa, PortObject2 * pob );
281 PortObject     * PortObjectAppendEx(PortObject * poa, PortObject * pob );
282 PortObject2    * PortObjectAppendEx2(PortObject2 * poa, PortObject * pob );
283 int              PortTableNormalizeInputPortObjects( PortTable *p );
284 int              PortTableCompileMergePortObjects( PortTable * p );
285 int              PortTableConsistencyCheck( PortTable *p );
286 void             PortTablePrintInput( PortTable * p );
287 void             PortTablePrintUserRules( PortTable * p );
288 void             PortTablePrintPortGroups( PortTable * p );
289 void             PortTablePrintPortPortObjects( PortTable * p );
290 int              PortVarTableFree(PortVarTable * pvt);
291 
292 void             PortObjectPrint       ( PortObject * po );
293 void             PortObjectPrintPorts  ( PortObject * po );
294 void             PortObjectPrintPortsRaw(PortObject * po );
295 void             PortObject2PrintPorts ( PortObject2 * po );
296 void             PortObject2Print      ( PortObject2 * po );
297 int              PortObjectPrintDetails( PortObject * po );
298 
299 void PortObjectPrintEx(PortObject * po,
300         void (*print_index_map)(int index, char *buf, int bufsize) );
301 void PortObject2PrintEx(PortObject2 * po,
302         void (*print_index_map)(int index, char *buf, int bufsize) );
303 void PortTableSortUniqRules(
304         PortTable * p
305         );
306 void RuleListSortUniq(
307         SF_LIST * rl
308         );
309 
310 /*
311     PortVarTable
312 
313 	port lists may be defined as 'name port-list'
314 */
315 PortVarTable * PortVarTableCreate (void);
316 int            PortVarTableAdd    ( PortVarTable * pvt, PortObject * po );
317 PortObject   * PortVarTableFind   ( PortVarTable * pvt, char * name );
318 
319 
320 /*
321    PortVars are internally stored in PortObjects
322    This function parses PortVar strings into PortObjects
323 */
324 PortObject *  PortObjectParseString ( PortVarTable * pvTable, POParser * pop,char * name, char * s,int nameflag );
325 char * PortObjectParseError( POParser * p );
326 #endif
327