bRAWcap 1.0.1
b-plus Technologies - Ethernet Performance Transmitter Receiver
Loading...
Searching...
No Matches
06_filter_firewall.c

This example shows how bRAWcap can be used to filter (discard) specific packets by using a byte filter.

1/**
2 * @file 06_filter_firewall.c
3 *
4 * @brief bRAWcap Example - Demonstrates how to throw away specific received packets.
5 *
6 * It shows how to:
7 * - Open a handle to the first available adapter
8 * - Create and apply a receive filter
9 * - Read the receive statistics
10 *
11 * This example makes use of C only.
12 *
13 * @version 1.0
14 *
15 * @date 2023-03-28
16 *
17 * @copyright
18 * <b> © 2021 - b-plus technologies GmbH. All rights reserved!</b>
19 *
20 * All rights exclusively reserved for b-plus GmbH, unless expressly otherwise agreed.
21 *
22 * Redistribution in source or any other form, with or without modification, is not permitted.
23 *
24 * You may use this code under the according license terms of b-plus.
25 * Please contact b-plus at services@b-plus.com to get the appropriate terms and conditions.
26 */
27// Include bRAWcap
28#include "libbrawcap.h"
29
30// C STD
31#include <stdlib.h> // for strtol
32#include <stdio.h> // for printf
33#include <time.h> // for printing time info
34
35// Check command line parameters if a custom execution time is specified
36// To configure a custom execution time use "-t numberOfSeconds"
37#if 1
38void ParseArgs(int argc, char** argv, int* exec_time)
39{
40 if(argc > 1)
41 {
42 if(!memcmp(argv[1], "-t", 2))
43 {
44 char* pEnd = 0;
45 *exec_time = strtol(argv[2], &pEnd,0);
46 }
47 }
48}
49#endif
50
51int main(int argc, char** argv)
52{
53 // Set console title
54 SetConsoleTitleA("bRAWcap Example - Firewall for SSDP Packets");
55
56 // Some generic helper locals...
57 int retVal = 0;
58 int exec_time = 300; // 5 minutes
59 int runtime_sec = 0;
60
61 // Parse command line argument, to check for user specified execution time
62 ParseArgs(argc, argv, &exec_time);
63
64 // Here we will store the status of any bRAWcap function
66
67 // Here we store the number of available bRAWcap adapters
68 brawcap_adapter_count_t numberAdapters = 0;
69 // This will contain our bRAWcap handle to the adapter we want to receive from
70 brawcap_handle_t* pHandle = 0;
71 // Our local filter to configure which packets should be dropped
72 brawcap_filter_t* pFilter = 0;
73
74 do
75 {
76 // First check if we have any bRAWcap adapters available.
77 // --> This function can only fail if we did something wrong.
78 // But we are sure that we did everything right...
79 // therefore we do not check it´s status.
80 brawcap_adapter_list_count(&numberAdapters);
81
82 // No adapters... nothing do receive from... lets exit ...
83 if (!numberAdapters)
84 {
85 printf("[WARNING] No bRAWcap adapter available... Will stop now.");
86 break;
87 }
88
89 // Get the name of the first adapter.
90 // To not overload the example with complex stuff,
91 // we always go for the first available adapter.
92 brawcap_adapter_name_t name = { '\0' };
94 {
95 printf("[ERROR] Unexpected status while retrieving adapter name: %d", brawcap_last_status());
96 retVal = -1;
97 break;
98 }
99
100 // Create a filter object where to store our filter settings
102 {
103 printf("[ERROR] Unexpected status while creating the filter: %d", brawcap_last_status());
104 retVal = -1;
105 break;
106 }
107
108 // Local filter attributes
109 brawcap_filter_byte_length_t filterOffset = 0;
110 brawcap_filter_byte_length_t filterLength = 0;
111 brawcap_filter_mask_array_t filterMask = { 0 };
112 brawcap_filter_ignore_bits_array_t filterBitMask = { 0 };
113
114 /* Lets specify our (byte) filter.
115 *
116 * In this example we want to filter out all SSDP (Simple Service Discover Protocol) packets.
117 *
118 * -- If you need those packets, change the filter to another packet type. --
119 *
120 * SSDP packets can be identified by their 1900 port and
121 * typically they are transmitted via UDP - so we filter for UDP destination port 1900.
122 *
123 * To make the filter more precise we also check if the transport protocol is UDP.
124 * UDP is identified by the IP protocol type 17 (we always assume IPv4 for this example).
125 */
126
127 // Lets start our filter at the IP protocol type which is byte 23 (for IPv4):
128 filterOffset = 23;
129
130 // Because we also need to check for UDP destination port at byte 36-37 (also for IPv4)
131 // our filter length must be 37 - 23 = 14 bytes
132 filterLength = 14;
133
134 // Now specify the UDP protocol type and the UDP destination port in the filter mask
135 // IPv4 Protocol type = UDP (17 <=> 0x11)
136 filterMask[0] = 0x11;
137 // UDP destination port = SSDP (1900 <=> 0x076C)
138 filterMask[13] = 0x07;
139 filterMask[14] = 0x6C;
140
141 // Ignore all bits of the bytes between IPv4 protocol type and UDP destination port.
142 // Therefore we must set each bit in this range to 1.
143 memset(&filterBitMask[1], 0xFF, 12);
144
145 // Now set our filter attributes to the previous created filter.
146 brawcap_filter_mask_set(pFilter, filterOffset, filterLength, filterMask, filterBitMask);
147
148 // Because we want to discard matched packets - do not forward to network stack -
149 // we set the filter indication to false
150 brawcap_filter_indicate_set(pFilter, 0);
151
152 // Set the filter to active
154
155 // Open a handle to the adapter by using the retrieved name.
156 if (!BRAWCAP_SUCCESS(brawcap_open(name, &pHandle)))
157 {
158 printf("[ERROR] Unexpected status while opening handle: %d", brawcap_last_status());
159 retVal = -1;
160 break;
161 }
162
163 // Now lets apply the filter to our opened handle
164 if(!BRAWCAP_SUCCESS(brawcap_rx_filter_set(pHandle, pFilter)))
165 {
166 printf("[ERROR] Unexpected status while applying the filter: %d", brawcap_last_status());
167 retVal = -1;
168 break;
169 }
170
171 // Because we do not want to process the packets somehow and just filter them.
172 // we can also reduce the drivers receive queue size for this handle to zero.
173 // With this setting the driver doesn´t even try to buffer those packets.
175 {
176 printf("[ERROR] Unexpected status while reducing driver queue size: %d", brawcap_last_status());
177 retVal = -1;
178 break;
179 }
180
181 // Local receive stats for some user feedback
182 brawcap_stats_rx_t rxStats;
186
187 // After applying the filter we would have finished here...
188 // Because we do not want to receive the filtered packets and only drop them.
189 // The bRAWcap driver does everything for us and we just need to keep the handle open.
190 do
191 {
192 // To give the user some feedback request the statistic counters from bRAWcap and
193 // print how many packets have been blocked by our "firewall" since applying it.
194 if (!BRAWCAP_SUCCESS(brawcap_stats_rx(pHandle, &rxStats)))
195 printf("[ERROR] Unexpected status while requesting receive stats: %d", brawcap_last_status());
196 else
197 {
198 time_t curTime = time(0);
199 char strTime[30];
200 strftime(strTime, 30, "<%F %X>", localtime(&curTime));
201 // We could also use the rxStats.handleDroppedPacketsQueue here.
202 // Both values should be equal as long as we do not process any of the matched packet
203 // by calling a bRAWcap receive function.
204 printf("%s Number of blocked packets: %llu\n", strTime, rxStats.handleReceivedPacketsMatched);
205 }
206
207 Sleep(1000);
208 } while (++runtime_sec < exec_time);
209 }while(0);
210
211 // We do not want to produce any memory leaks...
212 // ... so always cleanup what we have created
213 // --> The functions here can only fail if we did something wrong.
214 // But we are sure that we did everything right...
215 // therefore we do not check their status.
216 if (pHandle)
217 brawcap_close(pHandle);
218 if(pFilter)
219 brawcap_filter_free(pFilter);
220
221 return retVal;
222}
bRAWcap main header.
struct _brawcap_handle brawcap_handle_t
A bRAWcap handle.
Definition: brawcap_types_um.h:173
brawcap_status_t brawcap_close(brawcap_handle_t *pHandle)
Closes the specified bRAWcap handle.
brawcap_status_t brawcap_open(const brawcap_adapter_name_t name, brawcap_handle_t **const pHandle)
Opens a new bRAWcap handle on the adapter, specified by it´s name.
brawcap_status_t brawcap_last_status()
Reads the last status appeared in bRAWcap, for the calling thread.
brawcap_status_t
bRAWcap status/return codes.
Definition: brawcap_types_shared.h:150
#define BRAWCAP_SUCCESS(status)
Checks if the returned status indicates a success with no additional info.
Definition: brawcap_types_shared.h:122
@ BRAWCAP_STATUS_SUCCESS
Definition: brawcap_types_shared.h:152
brawcap_status_t brawcap_adapter_list_at(const brawcap_adapter_count_t index, brawcap_adapter_name_t name)
Reads out the adapter name of the adapter at the adapter list index.
brawcap_status_t brawcap_adapter_list_count(brawcap_adapter_count_t *const pCount)
Reads out the current number of supported adapters in the adapter list.
char brawcap_adapter_name_t[BRAWCAP_ADAPTER_NAME_LENGTH]
Fixed size array containing a adapter name.
Definition: brawcap_types_um.h:257
UINT8 brawcap_adapter_count_t
Type used for counting the available/supported adapters on a machine.
Definition: brawcap_types_um.h:242
brawcap_status_t brawcap_rx_driver_queue_size_set(brawcap_handle_t *const pHandle, const brawcap_queue_size_t size)
Sets the driver queue size (in number of packets) for the specified handle.
brawcap_status_t brawcap_rx_filter_set(brawcap_handle_t *const pHandle, const brawcap_filter_t *const pFilter)
Sets the specified filter to the specified handle.
UINT8 brawcap_filter_mask_array_t[BRAWCAP_FILTER_BYTE_MAX_LENGTH]
Fixed size array for storing a filter byte mask.
Definition: brawcap_types_shared.h:900
brawcap_status_t brawcap_filter_create(brawcap_filter_t **const pFilter, const brawcap_filter_type_t type)
Creates a new filter.
struct _brawcap_filter brawcap_filter_t
bRAWcap filter object.
Definition: brawcap_types_shared.h:973
UINT8 brawcap_filter_ignore_bits_array_t[BRAWCAP_FILTER_BYTE_MAX_LENGTH]
Fixed size array for storing a byte wise bitfield.
Definition: brawcap_types_shared.h:912
brawcap_status_t brawcap_filter_mask_set(brawcap_filter_t *const pFilter, const brawcap_filter_byte_length_t offset, const brawcap_filter_byte_length_t length, const brawcap_filter_mask_array_t mask, const brawcap_filter_ignore_bits_array_t ignoreBits)
Sets the filter parameters for the specified filter.
brawcap_status_t brawcap_filter_free(brawcap_filter_t *pFilter)
Frees the specified filter. When this function is called the given filter becomes invalid and it´s me...
brawcap_packet_size_t brawcap_filter_byte_length_t
Type for specifying the byte filter length.
Definition: brawcap_types_shared.h:917
brawcap_status_t brawcap_filter_indicate_set(brawcap_filter_t *const pFilter, const BOOLEAN indicate)
Specifies if packets which matched the specified filter should be indicated to the network stack.
brawcap_status_t brawcap_filter_activate(brawcap_filter_t *const pFilter)
Sets the specified filter to active.
@ BRAWCAP_FILTER_TYPE_BYTE_MASK
A bRAWcap byte filter.
Definition: brawcap_types_shared.h:931
The bRAWcap receive statistics.
Definition: brawcap_types_shared.h:1303
UINT64 handleReceivedPacketsMatched
The total number of packets which have matched the given bRAWcap handle filter.
Definition: brawcap_types_shared.h:1353
BYTE revision
Indicates the revision of the stats.
Definition: brawcap_types_shared.h:1251
UINT16 size
Should be set to the size of the structure depending on it´s type and revision. You should use the BR...
Definition: brawcap_types_shared.h:1256
BYTE type
Indicates which type of stats it is.
Definition: brawcap_types_shared.h:1245
brawcap_stats_header_t header
Header for receive statistics. This has to be always initialized by the user after creation before us...
Definition: brawcap_types_shared.h:1308
brawcap_status_t brawcap_stats_rx(brawcap_handle_t *const pHandle, brawcap_stats_rx_t *const pStats)
Reads out the available receive statistic counters for the specified handle.
#define BRAWCAP_STATS_RX_SIZEOF_REVISION_1
Returns the size of receive statistics revision 1.
Definition: brawcap_types_shared.h:1390
@ BRAWCAP_STATS_RX_REVISION_1
Revision 1 for receive stats.
Definition: brawcap_types_shared.h:1282
@ BRAWCAP_STATS_TYPE_RX
Type for receive stats.
Definition: brawcap_types_shared.h:1267