bRAWcap 1.1.0
b-plus Technologies - Ethernet Performance Transmitter Receiver
Loading...
Searching...
No Matches
06_filter_firewall_f.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_f.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.1
14 *
15 * @date 2023-03-28
16 *
17 * HISTORY:
18 * - 2023-03-28: Initial version
19 * - 2023-08-10: Set all indentation to 4 spaces
20 *
21 * @copyright
22 * <b> © 2021 - b-plus technologies GmbH. All rights reserved!</b>
23 *
24 * All rights exclusively reserved for b-plus GmbH, unless expressly otherwise agreed.
25 *
26 * Redistribution in source or any other form, with or without modification, is not permitted.
27 *
28 * You may use this code under the according license terms of b-plus.
29 * Please contact b-plus at services@b-plus.com to get the appropriate terms and conditions.
30 */
31// Include bRAWcap
32#include "libbrawcap.h"
33
34// C STD
35#include <stdlib.h> // for strtol
36#include <stdio.h> // for printf
37#include <time.h> // for printing time info
38
39// Check command line parameters if a custom execution time is specified
40// To configure a custom execution time use "-t numberOfSeconds"
41#if 1
42void ParseArgs(int argc, char** argv, int* exec_time)
43{
44 if(argc > 1)
45 {
46 if(!memcmp(argv[1], "-t", 2))
47 {
48 char* pEnd = 0;
49 *exec_time = strtol(argv[2], &pEnd,0);
50 }
51 }
52}
53#endif
54
55int main(int argc, char** argv)
56{
57 // Set console title
58 SetConsoleTitleA("bRAWcap Example - Firewall for SSDP Packets");
59
60 // Some generic helper locals...
61 int retVal = 0;
62 int exec_time = 300; // 5 minutes
63 int runtime_sec = 0;
64
65 // Parse command line argument, to check for user specified execution time
66 ParseArgs(argc, argv, &exec_time);
67
68 // Here we will store the status of any bRAWcap function
70
71 // Here we store the number of available bRAWcap adapters
72 brawcap_adapter_count_t numberAdapters = 0;
73 // This will contain our bRAWcap handle to the adapter we want to receive from
74 brawcap_handle_t* pHandle = 0;
75 // Our local filter to configure which packets should be dropped
76 brawcap_filter_t* pFilter = 0;
77
78 do
79 {
80 // First check if we have any bRAWcap adapters available.
81 // --> This function can only fail if we did something wrong.
82 // But we are sure that we did everything right...
83 // therefore we do not check it´s status.
84 brawcap_adapter_list_count(&numberAdapters);
85
86 // No adapters... nothing do receive from... lets exit ...
87 if (!numberAdapters)
88 {
89 printf("[WARNING] No bRAWcap adapter available... Will stop now.");
90 break;
91 }
92
93 // Get the name of the first adapter.
94 // To not overload the example with complex stuff,
95 // we always go for the first available adapter.
96 brawcap_adapter_name_t name = { '\0' };
98 {
99 printf("[ERROR] Unexpected status while retrieving adapter name: %d", brawcap_last_status());
100 retVal = -1;
101 break;
102 }
103
104 // Create a filter object where to store our filter settings
106 {
107 printf("[ERROR] Unexpected status while creating the filter: %d", brawcap_last_status());
108 retVal = -1;
109 break;
110 }
111
112 // Local filter attributes
113 brawcap_filter_byte_length_t filterOffset = 0;
114 brawcap_filter_byte_length_t filterLength = 0;
115 brawcap_filter_mask_array_t filterMask = { 0 };
116 brawcap_filter_ignore_bits_array_t filterBitMask = { 0 };
117
118 /* Lets specify our (byte) filter.
119 *
120 * In this example we want to filter out all SSDP (Simple Service Discover Protocol) packets.
121 *
122 * -- If you need those packets, change the filter to another packet type. --
123 *
124 * SSDP packets can be identified by their 1900 port and
125 * typically they are transmitted via UDP - so we filter for UDP destination port 1900.
126 *
127 * To make the filter more precise we also check if the transport protocol is UDP.
128 * UDP is identified by the IP protocol type 17 (we always assume IPv4 for this example).
129 */
130
131 // Lets start our filter at the IP protocol type which is byte 23 (for IPv4):
132 filterOffset = 23;
133
134 // Because we also need to check for UDP destination port at byte 36-37 (also for IPv4)
135 // our filter length must be 37 - 23 = 14 bytes
136 filterLength = 14;
137
138 // Now specify the UDP protocol type and the UDP destination port in the filter mask
139 // IPv4 Protocol type = UDP (17 <=> 0x11)
140 filterMask[0] = 0x11;
141 // UDP destination port = SSDP (1900 <=> 0x076C)
142 filterMask[13] = 0x07;
143 filterMask[14] = 0x6C;
144
145 // Ignore all bits of the bytes between IPv4 protocol type and UDP destination port.
146 // Therefore we must set each bit in this range to 1.
147 memset(&filterBitMask[1], 0xFF, 12);
148
149 // Now set our filter attributes to the previous created filter.
150 brawcap_filter_mask_set(pFilter, filterOffset, filterLength, filterMask, filterBitMask);
151
152 // Because we want to discard matched packets - do not forward to network stack -
153 // we set the filter indication to false
154 brawcap_filter_indicate_set(pFilter, 0);
155
156 // Set the filter to active
158
159 // Open a handle to the adapter by using the retrieved name.
160 if (!BRAWCAP_SUCCESS(brawcap_open(name, &pHandle)))
161 {
162 printf("[ERROR] Unexpected status while opening handle: %d", brawcap_last_status());
163 retVal = -1;
164 break;
165 }
166
167 // Now lets apply the filter to our opened handle
168 if(!BRAWCAP_SUCCESS(brawcap_rx_filter_set(pHandle, pFilter)))
169 {
170 printf("[ERROR] Unexpected status while applying the filter: %d", brawcap_last_status());
171 retVal = -1;
172 break;
173 }
174
175 // Because we do not want to process the packets somehow and just filter them.
176 // we can also reduce the drivers receive queue size for this handle to zero.
177 // With this setting the driver doesn´t even try to buffer those packets.
179 {
180 printf("[ERROR] Unexpected status while reducing driver queue size: %d", brawcap_last_status());
181 retVal = -1;
182 break;
183 }
184
185 // Local receive stats for some user feedback
186 brawcap_stats_rx_t rxStats;
190
191 // After applying the filter we would have finished here...
192 // Because we do not want to receive the filtered packets and only drop them.
193 // The bRAWcap driver does everything for us and we just need to keep the handle open.
194 do
195 {
196 // To give the user some feedback request the statistic counters from bRAWcap and
197 // print how many packets have been blocked by our "firewall" since applying it.
198 if (!BRAWCAP_SUCCESS(brawcap_stats_rx(pHandle, &rxStats)))
199 printf("[ERROR] Unexpected status while requesting receive stats: %d", brawcap_last_status());
200 else
201 {
202 time_t curTime = time(0);
203 char strTime[30];
204 struct tm timeinfo;
205 localtime_s(&timeinfo, &curTime);
206 strftime(strTime, 30, "<%F %X>", &timeinfo);
207 // We could also use the rxStats.handleDroppedPacketsQueue here.
208 // Both values should be equal as long as we do not process any of the matched packet
209 // by calling a bRAWcap receive function.
210 printf("%s Number of blocked packets: %llu\n", strTime, rxStats.handleReceivedPacketsMatched);
211 }
212
213 Sleep(1000);
214 } while (++runtime_sec < exec_time);
215 }while(0);
216
217 // We do not want to produce any memory leaks...
218 // ... so always cleanup what we have created
219 // --> The functions here can only fail if we did something wrong.
220 // But we are sure that we did everything right...
221 // therefore we do not check their status.
222 if (pHandle)
223 brawcap_close(pHandle);
224 if(pFilter)
225 brawcap_filter_free(pFilter);
226
227 return retVal;
228}
bRAWcap main header.
struct _brawcap_handle brawcap_handle_t
A bRAWcap handle.
Definition: brawcap_types_um.h:184
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:140
#define BRAWCAP_SUCCESS(status)
Checks if the returned status indicates a success with no additional info.
Definition: brawcap_types_shared.h:112
@ BRAWCAP_STATUS_SUCCESS
Definition: brawcap_types_shared.h:142
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:301
UINT8 brawcap_adapter_count_t
Type used for counting the available/supported adapters on a machine.
Definition: brawcap_types_um.h:286
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:911
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:959
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:923
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:928
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:942
The bRAWcap receive statistics.
Definition: brawcap_types_shared.h:1302
UINT64 handleReceivedPacketsMatched
The total number of packets which have matched the given bRAWcap handle filter.
Definition: brawcap_types_shared.h:1352
BYTE revision
Indicates the revision of the stats.
Definition: brawcap_types_shared.h:1250
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:1255
BYTE type
Indicates which type of stats it is.
Definition: brawcap_types_shared.h:1244
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:1307
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:1389
@ BRAWCAP_STATS_RX_REVISION_1
Revision 1 for receive stats.
Definition: brawcap_types_shared.h:1281
@ BRAWCAP_STATS_TYPE_RX
Type for receive stats.
Definition: brawcap_types_shared.h:1266