1 /* 2 * xfilter.h 3 * 4 * Address filtering for NDIS MACs 5 * 6 * This file is part of the w32api package. 7 * 8 * Contributors: 9 * Created by Casper S. Hornstrup <chorns@users.sourceforge.net> 10 * 11 * THIS SOFTWARE IS NOT COPYRIGHTED 12 * 13 * This source code is offered for use in the public domain. You may 14 * use, modify or distribute it freely. 15 * 16 * This code is distributed in the hope that it will be useful but 17 * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY 18 * DISCLAIMED. This includes but is not limited to warranties of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 */ 22 23 #ifndef _X_FILTER_DEFS_ 24 #define _X_FILTER_DEFS_ 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 #define ETH_LENGTH_OF_ADDRESS 6 31 32 #define ETH_IS_BROADCAST(Address) \ 33 ((((PUCHAR)(Address))[0] == ((UCHAR)0xff)) && (((PUCHAR)(Address))[1] == ((UCHAR)0xff))) 34 35 #define ETH_IS_MULTICAST(Address) \ 36 (BOOLEAN)(((PUCHAR)(Address))[0] & ((UCHAR)0x01)) 37 38 #define ETH_COMPARE_NETWORK_ADDRESSES(_A, _B, _Result) \ 39 { \ 40 if (*(ULONG UNALIGNED *)&(_A)[2] > *(ULONG UNALIGNED *)&(_B)[2]) \ 41 { \ 42 *(_Result) = 1; \ 43 } \ 44 else if (*(ULONG UNALIGNED *)&(_A)[2] < *(ULONG UNALIGNED *)&(_B)[2]) \ 45 { \ 46 *(_Result) = (UINT)-1; \ 47 } \ 48 else if (*(USHORT UNALIGNED *)(_A) > *(USHORT UNALIGNED *)(_B)) \ 49 { \ 50 *(_Result) = 1; \ 51 } \ 52 else if (*(USHORT UNALIGNED *)(_A) < *(USHORT UNALIGNED *)(_B)) \ 53 { \ 54 *(_Result) = (UINT)-1; \ 55 } \ 56 else \ 57 { \ 58 *(_Result) = 0; \ 59 } \ 60 } 61 62 #define ETH_COMPARE_NETWORK_ADDRESSES_EQ(_A,_B, _Result) \ 63 { \ 64 if ((*(ULONG UNALIGNED *)&(_A)[2] == *(ULONG UNALIGNED *)&(_B)[2]) && \ 65 (*(USHORT UNALIGNED *)(_A) == *(USHORT UNALIGNED *)(_B))) \ 66 { \ 67 *(_Result) = 0; \ 68 } \ 69 else \ 70 { \ 71 *(_Result) = 1; \ 72 } \ 73 } 74 75 #define ETH_COPY_NETWORK_ADDRESS(_D, _S) \ 76 { \ 77 *((ULONG UNALIGNED *)(_D)) = *((ULONG UNALIGNED *)(_S)); \ 78 *((USHORT UNALIGNED *)((UCHAR *)(_D) + 4)) = *((USHORT UNALIGNED *)((UCHAR *)(_S) + 4)); \ 79 } 80 81 #define FDDI_LENGTH_OF_LONG_ADDRESS 6 82 #define FDDI_LENGTH_OF_SHORT_ADDRESS 2 83 84 #define FDDI_IS_BROADCAST(Address, AddressLength, Result) \ 85 *Result = ((*(PUCHAR)(Address) == (UCHAR)0xFF) && \ 86 (*((PUCHAR)(Address) + 1) == (UCHAR)0xFF)) 87 88 #define FDDI_IS_MULTICAST(Address, AddressLength, Result) \ 89 *Result = (BOOLEAN)(*(UCHAR *)(Address) & (UCHAR)0x01) 90 91 #define FDDI_IS_SMT(FcByte, Result) \ 92 { \ 93 *Result = ((FcByte & ((UCHAR)0xf0)) == 0x40); \ 94 } 95 96 97 #define FDDI_COMPARE_NETWORK_ADDRESSES(_A, _B, _Length, _Result) \ 98 { \ 99 if (*(USHORT UNALIGNED *)(_A) > *(USHORT UNALIGNED *)(_B)) \ 100 { \ 101 *(_Result) = 1; \ 102 } \ 103 else if (*(USHORT UNALIGNED *)(_A) < *(USHORT UNALIGNED *)(_B)) \ 104 { \ 105 *(_Result) = (UINT)-1; \ 106 } \ 107 else if (_Length == 2) \ 108 { \ 109 *(_Result) = 0; \ 110 } \ 111 else if (*(ULONG UNALIGNED *)((PUCHAR)(_A) + 2) > *(ULONG UNALIGNED *)((PUCHAR)(_B) + 2)) \ 112 { \ 113 *(_Result) = 1; \ 114 } \ 115 else if (*(ULONG UNALIGNED *)((PUCHAR)(_A) + 2) < *(ULONG UNALIGNED *)((PUCHAR)(_B) + 2)) \ 116 { \ 117 *(_Result) = (UINT)-1; \ 118 } \ 119 else \ 120 { \ 121 *(_Result) = 0; \ 122 } \ 123 } 124 125 #define FDDI_COMPARE_NETWORK_ADDRESSES_EQ(_A, _B, _Length, _Result) \ 126 { \ 127 if ((*(USHORT UNALIGNED *)(_A) == *(USHORT UNALIGNED *)(_B)) && \ 128 (((_Length) == 2) || \ 129 (*(ULONG UNALIGNED *)((PUCHAR)(_A) + 2) == *(ULONG UNALIGNED *)((PUCHAR)(_B) + 2)))) \ 130 { \ 131 *(_Result) = 0; \ 132 } \ 133 else \ 134 { \ 135 *(_Result) = 1; \ 136 } \ 137 } 138 139 #define FDDI_COPY_NETWORK_ADDRESS(D, S, AddressLength) \ 140 { \ 141 PCHAR _D = (D); \ 142 PCHAR _S = (S); \ 143 UINT _C = (AddressLength); \ 144 for ( ; _C > 0 ; _D++, _S++, _C--) \ 145 { \ 146 *_D = *_S; \ 147 } \ 148 } 149 150 #define TR_LENGTH_OF_FUNCTIONAL 4 151 #define TR_LENGTH_OF_ADDRESS 6 152 153 typedef ULONG TR_FUNCTIONAL_ADDRESS; 154 typedef ULONG TR_GROUP_ADDRESS; 155 156 #define TR_IS_NOT_DIRECTED(_Address, _Result) \ 157 { \ 158 *(_Result) = (BOOLEAN)((_Address)[0] & 0x80); \ 159 } 160 161 #define TR_IS_FUNCTIONAL(_Address, _Result) \ 162 { \ 163 *(_Result) = (BOOLEAN)(((_Address)[0] & 0x80) && !((_Address)[2] & 0x80)); \ 164 } 165 166 #define TR_IS_GROUP(_Address, _Result) \ 167 { \ 168 *(_Result) = (BOOLEAN)((_Address)[0] & (_Address)[2] & 0x80); \ 169 } 170 171 #define TR_IS_SOURCE_ROUTING(_Address, _Result) \ 172 { \ 173 *(_Result) = (BOOLEAN)((_Address)[0] & 0x80); \ 174 } 175 176 #define TR_IS_MAC_FRAME(_PacketHeader) ((((PUCHAR)_PacketHeader)[1] & 0xFC) == 0) 177 178 #define TR_IS_BROADCAST(_Address, _Result) \ 179 { \ 180 *(_Result) = (BOOLEAN)(((*(UNALIGNED USHORT *)&(_Address)[0] == 0xFFFF) || \ 181 (*(UNALIGNED USHORT *)&(_Address)[0] == 0x00C0)) && \ 182 (*(UNALIGNED ULONG *)&(_Address)[2] == 0xFFFFFFFF)); \ 183 } 184 185 #define TR_COMPARE_NETWORK_ADDRESSES(_A, _B, _Result) \ 186 { \ 187 if (*(ULONG UNALIGNED *)&(_A)[2] > *(ULONG UNALIGNED *)&(_B)[2]) \ 188 { \ 189 *(_Result) = 1; \ 190 } \ 191 else if (*(ULONG UNALIGNED *)&(_A)[2] < *(ULONG UNALIGNED *)&(_B)[2]) \ 192 { \ 193 *(_Result) = (UINT)-1; \ 194 } \ 195 else if (*(USHORT UNALIGNED *)(_A) > *(USHORT UNALIGNED *)(_B)) \ 196 { \ 197 *(_Result) = 1; \ 198 } \ 199 else if (*(USHORT UNALIGNED *)(_A) < *(USHORT UNALIGNED *)(_B)) \ 200 { \ 201 *(_Result) = (UINT)-1; \ 202 } \ 203 else \ 204 { \ 205 *(_Result) = 0; \ 206 } \ 207 } 208 209 #define TR_COPY_NETWORK_ADDRESS(_D, _S) \ 210 { \ 211 *((ULONG UNALIGNED *)(_D)) = *((ULONG UNALIGNED *)(_S)); \ 212 *((USHORT UNALIGNED *)((UCHAR *)(_D)+4)) = *((USHORT UNALIGNED *)((UCHAR *)(_S) + 4)); \ 213 } 214 215 #define TR_COMPARE_NETWORK_ADDRESSES_EQ(_A, _B, _Result) \ 216 { \ 217 if ((*(ULONG UNALIGNED *)&(_A)[2] == *(ULONG UNALIGNED *)&(_B)[2]) && \ 218 (*(USHORT UNALIGNED *)&(_A)[0] == *(USHORT UNALIGNED *)&(_B)[0])) \ 219 { \ 220 *(_Result) = 0; \ 221 } \ 222 else \ 223 { \ 224 *(_Result) = 1; \ 225 } \ 226 } 227 228 #ifdef __cplusplus 229 } 230 #endif 231 232 #endif /* _X_FILTER_DEFS_ */ 233