├── .gitignore ├── BUGS ├── CMakeLists.txt ├── Makefile ├── README.md ├── doc └── libpacket.md.1 ├── extras ├── defragment.c ├── defragment.h ├── hashtable.c ├── hashtable.h ├── packet_flow_key.c ├── timequeue.c └── timequeue.h ├── include ├── packet.h └── packet │ ├── ipaddr.h │ ├── libpacket.h │ ├── options.h │ ├── packet.h │ ├── protocol.h │ └── stats.h ├── src ├── .gitignore ├── CMakeLists.txt ├── checksum.c ├── checksum.h ├── crc32.h ├── eth.c ├── eth.h ├── icmp4.c ├── icmp4.h ├── icmp6.c ├── icmp6.h ├── ip4.c ├── ip4.h ├── ip6.c ├── ip6.h ├── ipx.c ├── ipx.h ├── mpls.c ├── mpls.h ├── packet.c ├── packet_private.c ├── packet_private.h ├── ppp.c ├── ppp.h ├── pppoe.c ├── pppoe.h ├── raw.c ├── raw.h ├── sctp.c ├── sctp.h ├── spx.c ├── spx.h ├── tcp.c ├── tcp.h ├── udp.c ├── udp.h ├── vlan.c └── vlan.h └── tests ├── CMakeLists.txt ├── Makefile ├── check_packet_accessors.cpp ├── check_packet_alt_payload.cpp ├── check_packet_create.cpp ├── check_packet_decode.cpp └── testme.c /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | tests/build 3 | tests/Testing 4 | -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | This is a list of known bugs/pitfalls in libpacket 2 | 3 | * SCTP Checksuming always reports error 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(libpacket C) 3 | add_subdirectory(src) 4 | 5 | # Install library headers 6 | install( 7 | DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include" 8 | DESTINATION "${CMAKE_INSTALL_PREFIX}" 9 | ) 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build clean install test uninstall 2 | 3 | build: 4 | cmake -B build -G Ninja . \ 5 | -D CMAKE_BUILD_TYPE:STRING=Debug \ 6 | -D CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE 7 | cmake --build build 8 | 9 | clean: 10 | rm -rf build/ 11 | 12 | install: build 13 | cmake --install build 14 | 15 | test: install 16 | make -C tests/ 17 | 18 | uninstall: 19 | rm -f /usr/local/include/packet.h 20 | rm -rf /usr/local/include/packet/ 21 | rm -f /usr/local/lib/libpacket.so.* 22 | rm -f /usr/local/lib/libpacket.so 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | _ _ _ _ _ 2 | | (_) |__ _ __ __ _ ___| | _____| |_ 3 | | | | '_ \| '_ \ / _` |/ __| |/ / _ \ __| 4 | | | | |_) | |_) | (_| | (__| < __/ |_ 5 | |_|_|_.__/| .__/ \__,_|\___|_|\_\___|\__| 6 | |_| 7 | 8 | Release: 0.2.0 9 | Bug Report: github.com/wtfbbqhax/LibPacket/issues 10 | 11 | TCP/IP packet decoder/parser that provides a clean API to aide in the 12 | creation of packet sniffers. 13 | 14 | 15 | Platforms 16 | --------- 17 | 18 | 19 | Expected to work on the following OSs: 20 | - Linux 21 | - Mac OSX 22 | - FreeBSD 23 | - OpenBSD 24 | 25 | * If it doesn't work on the listed platforms, or you would like it to 26 | work on a different platform; please submit an issue. 27 | 28 | 29 | Protocol Support 30 | ---------------- 31 | 32 | LibPacket supports decoding the following protocol headers: 33 | - Ethernet 34 | - VLAN / 802.1Q 35 | - IPv4 36 | - IPv6 37 | - MPLS 38 | - PPP 39 | - PPPOE 40 | - TCP 41 | - UDP 42 | - SCTP 43 | - ICMP 44 | - ICMPv6 45 | 46 | Experimental support is provided for the following protocol headers: 47 | - IPX 48 | - SPX 49 | 50 | 51 | Build and Install 52 | ----------------- 53 | 54 | ```sh 55 | cmake -B build -G Ninja . 56 | cmake --build build 57 | sudo cmake --install build 58 | ``` 59 | 60 | Getting Started 61 | --------------- 62 | 63 | 64 | Refer to the header files: 65 | - include/packet/packet.h 66 | - include/packet/ipaddr.h 67 | - include/packet/protocol.h 68 | - include/packet/options.h 69 | - include/packet/stats.h 70 | 71 | The primary interface is documented below: 72 | 73 | ## Packet type 74 | 75 | | Packet* packet_create( ); 76 | | void packet_destroy(Packet *); 77 | 78 | Allocates and destroy a packet instance respectively. 79 | 80 | 81 | | int packet_decode(Packet *packet, const unsigned char *raw_data, unsigned raw_data_size); 82 | 83 | Decode's "raw_data" and writes results into "packet". 84 | 85 | ## Protocol Layers 86 | 87 | | Protocol* packet_proto_first(Packet *packet, unsigned *); 88 | | Protocol* packet_proto_next(Packet *packet, unsigned *); 89 | | unsigned packet_proto_count(Packet *packet); 90 | | 91 | | PROTOCOL packet_proto_proto(Protocol *proto); 92 | | int packet_proto_size(Protocol *proto); 93 | | const uint8_t* packet_proto_data(Protocol *proto); 94 | | const char* packet_proto_name(Protocol *proto); 95 | 96 | 97 | ## IPv4 and IPv6 Protocols 98 | 99 | | int packet_version(Packet *packet) 100 | | 101 | | struct ipaddr packet_srcaddr(Packet *packet) 102 | | struct ipaddr packet_dstaddr(Packet *packet) 103 | | 104 | | uint8_t packet_protocol(Packet *packet) 105 | | uint32_t packet_id(Packet *packet) 106 | | uint8_t packet_ttl(Packet *packet) 107 | | uint8_t packet_tos(Packet *packet) 108 | | 109 | | bool packet_is_fragment(Packet *packet) 110 | | bool packet_frag_mf(Packet *packet) 111 | | bool packet_frag_df(Packet *packet) 112 | | uint16_t packet_frag_offset(Packet *packet) 113 | 114 | 115 | ## TCP, UDP and SCTP Protocols 116 | 117 | | uint16_t packet_srcport(Packet *packet) 118 | | uint16_t packet_dstport(Packet *packet) 119 | 120 | 121 | ## TCP Protocol 122 | 123 | | uint32_t packet_seq(Packet *packet) // Sequence # 124 | | uint32_t packet_ack(Packet *packet) // Acknowledgement # 125 | | 126 | | uint16_t packet_mss(Packet *packet) 127 | | uint16_t packet_win(Packet *packet) 128 | | uint16_t packet_winscale(Packet *packet) 129 | | 130 | | int packet_tcpflags(Packet *packet) 131 | | bool packet_tcp_fin(Packet *packet) 132 | | bool packet_tcp_syn(Packet *packet) 133 | | bool packet_tcp_rst(Packet *packet) 134 | | bool packet_tcp_push(Packet *packet) 135 | | bool packet_tcp_ack(Packet *packet) 136 | | bool packet_tcp_urg(Packet *packet) 137 | 138 | 139 | # Payload Pseudo-Protocol 140 | 141 | Paylaod is a pointer to the start of the first un-supported protocol encountered 142 | durring decoding phase; normally the "Application Protocol" (e.g. HTTP). 143 | 144 | | void packet_set_payload(Packet *packet, void *payload, uint32_t paysize); 145 | | bool packet_has_alt_payload(Packet *packet); 146 | 147 | Set the "alternate payload" pointer to "payload". 148 | Used to associate defragmented data to a packet (see "extras/defragment.c"). 149 | 150 | 151 | | uint32_t packet_raw_paysize(Packet *packet); 152 | | const uint8_t* packet_raw_payload(Packet *packet); 153 | 154 | The "raw" payload is returned always. 155 | 156 | 157 | | uint32_t packet_paysize(Packet *packet); 158 | | const uint8_t* packet_payload(Packet *packet); 159 | 160 | Returns the "alt" payload if set; the "raw" payload otherwise. 161 | 162 | -------------------------------------------------------------------------------- /doc/libpacket.md.1: -------------------------------------------------------------------------------- 1 | % libpacket(3) LibPacket User Manual | Version 0.0.1 2 | % Victor Roemer 3 | % January 14, 2013 4 | 5 | NAME 6 | ==== 7 | 8 | libpacket - Shallow packet inspection library 9 | 10 | SYNOPSIS 11 | ======== 12 | **#include ** 13 | 14 | DESCRIPTION 15 | =========== 16 | 17 | ~~~~~~~~~~~ 18 | packet_ack(Packet *packet) 19 | packet_create( ) 20 | packet_decode(Packet *, const unsigned char *, unsigned) 21 | packet_decode_pcap(Packet *, const uint8_t *, const struct pcap_pkthdr *) 22 | packet_destroy(Packet *) 23 | packet_dstaddr(Packet *packet) 24 | packet_dstport(Packet *packet) 25 | packet_frag_df(Packet *packet) 26 | packet_frag_mf(Packet *packet) 27 | packet_frag_offset(Packet *packet) 28 | packet_has_alt_payload(Packet *packet) 29 | packet_id(Packet *packet) 30 | packet_is_fragment(Packet *packet) 31 | packet_lib_version(void) 32 | packet_mss(Packet *packet) 33 | packet_payload(Packet *packet) 34 | packet_paysize(Packet *packet) 35 | packet_proto_count(Packet *packet) 36 | packet_proto_data(Protocol *proto) 37 | packet_proto_first(Packet *packet, unsigned *) 38 | packet_proto_name(Protocol *proto) 39 | packet_proto_next(Packet *packet, unsigned *) 40 | packet_proto_proto(Protocol *proto) 41 | packet_proto_size(Protocol *proto) 42 | packet_protocol(Packet *packet) 43 | packet_raw_payload(Packet *packet) 44 | packet_raw_paysize(Packet *packet) 45 | packet_seq(Packet *packet) 46 | packet_set_datalink(unsigned datalink) 47 | packet_set_payload(Packet *packet, void *payload, uint32_t paysize) 48 | packet_srcaddr(Packet *packet) 49 | packet_srcport(Packet *packet) 50 | packet_stats(const struct packet_stats **ps) 51 | packet_tcp_ack(Packet *packet) 52 | packet_tcp_fin(Packet *packet) 53 | packet_tcp_push(Packet *packet) 54 | packet_tcp_rst(Packet *packet) 55 | packet_tcp_syn(Packet *packet) 56 | packet_tcp_urg(Packet *packet) 57 | packet_tcpflags(Packet *packet) 58 | packet_tos(Packet *packet) 59 | packet_ttl(Packet *packet) 60 | packet_version(Packet *packet) 61 | packet_win(Packet *packet) 62 | packet_winscale(Packet *packet) 63 | 64 | ~~~~~~~~~~~ 65 | -------------------------------------------------------------------------------- /extras/defragment.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef VJR2015_FRAG_H 32 | #define VJR2015_FRAG_H 33 | 34 | //#include 35 | //#include 36 | //#include 37 | 38 | //#include "../ghthash/ght_hash_table.h" 39 | 40 | /* Public Interface */ 41 | //int ip4_defrag (uint8_t * pkt, int len, Packet * p); 42 | int defragment(Packet *p); 43 | 44 | /* Setup functions */ 45 | int set_defrag_method(const char *value, const char *filename, unsigned linenum, int *error); 46 | 47 | 48 | /* Frag Table Public Interface */ 49 | int frag_table_init(); 50 | int frag_table_finalize(); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /extras/hashtable.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012, Victor J Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | // 32 | // hashtable.c 33 | // Open address hash table using quadratic probing to avoid 34 | // collisions. Modeled loosely after Googles sparse hash table. 35 | // 36 | // Created by Victor J. Roemer on 3/4/12. 37 | // Copyright (c) 2012 Victor J. Roemer. All rights reserved. 38 | // 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include 50 | 51 | #include 52 | 53 | 54 | #include "hashtable.h" 55 | 56 | /* __flexarr crap stolen from dnet. */ 57 | #undef __flexarr 58 | #if defined(__GNUC__) && ((__GNUC__ > 2) || \ 59 | (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)) 60 | # define __flexarr [] 61 | #else 62 | # ifdef __GNUC__ 63 | # define __flexarr [0] 64 | # else 65 | # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 66 | # define __flexarr [] 67 | # elif defined(_WIN32) 68 | /* MS VC++ */ 69 | # define __flexarr [] 70 | # else 71 | /* Some other non-C99 compiler. Approximate with [1]. */ 72 | # define __flexarr [1] 73 | # endif 74 | # endif 75 | #endif 76 | 77 | typedef struct 78 | { 79 | bool filled; 80 | void *value; 81 | size_t keysize; 82 | #if __STDC_VERSION__ >= 199901L 83 | char key __flexarr; 84 | #else 85 | void *key; 86 | #endif 87 | } Bucket; 88 | 89 | struct _Hash 90 | { 91 | size_t buckets; 92 | size_t size; 93 | Bucket **table; 94 | }; 95 | 96 | /* 97 | ============== 98 | Data 'hashing' routines. 99 | ============== 100 | */ 101 | static int seed; 102 | 103 | void digest_init(unsigned buckets) 104 | { 105 | srand(time(0)); 106 | seed = (rand() * rand() % buckets); 107 | } 108 | 109 | unsigned long fnv1a_digest(const void *buf, size_t len, unsigned long hval) 110 | { 111 | unsigned char *start = (unsigned char *)buf; 112 | unsigned char *end = start + len; 113 | 114 | while (start < end) { 115 | hval ^= (unsigned char)*start++; 116 | hval *= 0x01000193; 117 | hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 118 | } 119 | 120 | return hval + seed; 121 | } 122 | 123 | /* 124 | ============== 125 | Hash table managment code below. 126 | ============== 127 | */ 128 | 129 | /* 130 | * hash_create 131 | * 132 | * Allocate space for a new table and initialize all the table elements. 133 | */ 134 | Hash *hash_create(size_t buckets) 135 | { 136 | size_t i; 137 | 138 | Hash *this = calloc(1, sizeof(*this)); 139 | if (this == NULL) { 140 | return NULL; 141 | } 142 | 143 | this->table = (Bucket **)calloc(buckets, sizeof(*(this->table))); 144 | if (this->table == NULL) { 145 | free(this); 146 | return NULL; 147 | } 148 | 149 | this->buckets = buckets; 150 | this->size = 0; 151 | 152 | for (i = 0; i < this->buckets; ++i) { 153 | this->table[i] = NULL; 154 | } 155 | 156 | digest_init(buckets); 157 | 158 | return this; 159 | } 160 | 161 | /* 162 | * hash_destroy 163 | * 164 | * Will not remove entries in the table so make sure you take care of that. 165 | */ 166 | void hash_destroy(Hash *this) 167 | { 168 | size_t i; 169 | 170 | assert(this != NULL); 171 | assert(this->table != NULL); 172 | assert(this->size == 0); 173 | 174 | for (i = 0; i < this->buckets; ++i) 175 | free(this->table[i]); 176 | 177 | free(this->table); 178 | free(this); 179 | } 180 | 181 | /* 182 | * bucket_create 183 | * 184 | * Create a new bucket. 185 | */ 186 | static inline Bucket *bucket_create(void *value, void *key, size_t keysize) 187 | { 188 | Bucket *bucket = NULL; 189 | if ((bucket = malloc(keysize + sizeof(*bucket))) == NULL) { 190 | return NULL; 191 | } 192 | 193 | bucket->keysize = keysize; 194 | bucket->value = value; 195 | bucket->filled = true; 196 | 197 | /* store key with bucket, bucket->key will point into itself */ 198 | #if __STDC_VERSION__ < 199901L 199 | bucket->key = &bucket->key+1; 200 | #endif 201 | memcpy(bucket->key, key, keysize); 202 | 203 | return bucket; 204 | } 205 | 206 | /* 207 | * hash_insert 208 | * 209 | * Insert a new key/value pair. 210 | */ 211 | int hash_insert(Hash *this, void *value, void *key, size_t keysize) 212 | { 213 | size_t i; 214 | // if ((float)(this->size/this->buckets) > 0.8f) { 215 | // printf("Loadfactor == %f\n", (float)(this->size/this->buckets)); 216 | // return -1; 217 | // } 218 | 219 | unsigned long idx = fnv1a_digest(key, keysize, 0x811c9dc5) % this->buckets; 220 | 221 | for (i = 1; i < this->buckets; ++i) { 222 | if (this->table[idx] == NULL) { 223 | this->table[idx] = bucket_create(value, key, keysize); 224 | this->size++; 225 | return 0; 226 | } 227 | /** FIXME: if key sizes differ, than the bucket really needs to be 228 | * updated. */ 229 | else if (this->table[idx]->filled == false) { 230 | this->table[idx]->filled = true; 231 | memcpy(this->table[idx]->key, key, keysize); 232 | this->table[idx]->keysize = keysize; 233 | this->table[idx]->value = value; 234 | this->size++; 235 | return 0; 236 | } 237 | 238 | /* bucket was already filled, find a new bucket */ 239 | idx = (idx + i*i) % this->buckets; 240 | } 241 | 242 | return -1; 243 | } 244 | 245 | /* 246 | * hash_remove 247 | * 248 | * Remove key/value pair from table and return the value. 249 | */ 250 | void *hash_remove(Hash *this, const void *key, size_t keysize) 251 | { 252 | size_t i; 253 | unsigned long idx = fnv1a_digest(key, keysize, 0x811c9dc5) % this->buckets; 254 | 255 | for (i = 0; i < this->buckets; i++) { 256 | if (this->table[idx] == NULL) 257 | return NULL; 258 | 259 | if (this->table[idx]->filled == false) { 260 | idx = (idx + i*i) % this->buckets; 261 | continue; 262 | } 263 | 264 | if (memcmp(key, this->table[idx]->key, 265 | this->table[idx]->keysize) == 0) { 266 | this->table[idx]->filled = false; 267 | this->size--; 268 | return this->table[idx]->value; 269 | } 270 | 271 | idx = (idx + i*i) % this->buckets; 272 | } 273 | 274 | return NULL; 275 | } 276 | 277 | /* 278 | * hash_get 279 | * 280 | * Return value for the key in the table. 281 | */ 282 | void *hash_get(Hash *this, void *key, size_t keysize) 283 | { 284 | size_t i; 285 | unsigned long idx = fnv1a_digest(key, keysize, 0x811c9dc5) 286 | % this->buckets; 287 | 288 | for (i = 0; i < this->buckets; i++) { 289 | if (this->table[idx] == NULL) 290 | return NULL; 291 | 292 | if (this->table[idx]->filled == false) 293 | continue; 294 | 295 | else 296 | if (memcmp(key, this->table[idx]->key, 297 | this->table[idx]->keysize) == 0) 298 | return this->table[idx]->value; 299 | 300 | idx = (idx + i*i) % this->buckets; 301 | } 302 | 303 | return NULL; 304 | } 305 | 306 | /* 307 | * hash_first 308 | * 309 | * return the first element in the hash table. 310 | */ 311 | void *hash_first(Hash *this, unsigned *it, const void **key) 312 | { 313 | for (*it = 0; (*it) < this->buckets; (*it)++) { 314 | if (this->table[*it] == NULL) 315 | continue; 316 | if (this->table[*it]->filled) { 317 | *key = this->table[*it]->key; 318 | return this->table[*it]->value; 319 | } 320 | } 321 | 322 | return NULL; 323 | } 324 | 325 | /* 326 | * hash_next 327 | * 328 | * return the next element in the hash table. 329 | */ 330 | void *hash_next(Hash *this, unsigned *it, const void **key) 331 | { 332 | for ((*it)++; (*it) < this->buckets; (*it)++) { 333 | if (this->table[*it] == NULL) 334 | continue; 335 | if (this->table[*it]->filled) { 336 | *key = this->table[*it]->key; 337 | return this->table[*it]->value; 338 | } 339 | } 340 | 341 | return NULL; 342 | } 343 | 344 | /* 345 | * hash_dump 346 | * 347 | * display the contents of the hash table. 348 | */ 349 | void hash_dump(Hash *this) 350 | { 351 | size_t i; 352 | unsigned long memuse = sizeof(*this) + ((sizeof(Bucket)+16)*this->buckets); 353 | printf("Fixed memory usage = %lu\n", memuse); 354 | for (i = 1; i < this->buckets; ++i) { 355 | if (this->table[i] != NULL && this->table[i]->filled) 356 | printf("[%u][ full ]\n", (unsigned)i); 357 | } 358 | } 359 | -------------------------------------------------------------------------------- /extras/hashtable.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012, Victor J Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | // 32 | // hashtable.h 33 | // pcapstats 34 | // 35 | // Lightweight hashtable implementation in C. 36 | // 37 | // Created by Victor J. Roemer on 3/4/12. 38 | // Copyright (c) 2012 Victor J. Roemer. All rights reserved. 39 | 40 | // Modified by Victor J. Roemer Jan 2, 2015: 41 | // - Merge hashdigest.[ch] into hashtable.[ch] 42 | // - fixup header to be more aligned to my current style nitpicks. 43 | 44 | #ifndef VJR2015_HASHTABLE_H 45 | #define VJR2015_HASHTABLE_H 46 | 47 | // XXX Include the following headers in your code before including this file. 48 | //#include 49 | //#include 50 | //#include 51 | 52 | typedef struct _Hash Hash; 53 | 54 | void digest_init (unsigned buckets); 55 | unsigned long fnv1a_digest (const void *buf, size_t len, unsigned long hval); 56 | 57 | Hash* hash_create (size_t buckets); 58 | void hash_destroy (Hash*); 59 | void hash_dump (Hash*); 60 | #define hash_size(X) \ 61 | ((X)->size) 62 | 63 | // Basic hash table operations (insert, remove and retrieve[get]). 64 | int hash_insert (Hash*, void *data, void *key, size_t keysize); 65 | void* hash_remove (Hash*, const void *key, size_t keysize); 66 | void* hash_get (Hash*, void *key, size_t keysize); 67 | 68 | // Functions to Iterate the entries in the hash table. 69 | void* hash_first (Hash*, unsigned *it, const void **key); 70 | void* hash_next (Hash*, unsigned *it, const void **key); 71 | 72 | #endif /* VJR2015_HASHTABLE_H */ 73 | -------------------------------------------------------------------------------- /extras/packet_flow_key.c: -------------------------------------------------------------------------------- 1 | // Packet flow keying 2 | // Victor Roemer (wtfbbqhax), . 3 | #include 4 | 5 | #include 6 | 7 | #define FNV_PRIME_32 16777619 8 | #define FNV_OFFSET_32 2166136261 9 | 10 | static inline 11 | uint32_t fnv1a(uint32_t data_byte, uint32_t hash) 12 | { 13 | return (data_byte ^ hash) * FNV_PRIME_32; 14 | } 15 | 16 | unsigned 17 | packet_flow_key(const uint8_t *data, const size_t len) 18 | { 19 | Packet packet = {}; 20 | packet_clear(&packet); 21 | packet_decode(&packet, data, len); 22 | 23 | struct ipaddr src = packet_srcaddr(&packet); 24 | struct ipaddr dst = packet_dstaddr(&packet); 25 | struct ipaddr *a = &src; 26 | struct ipaddr *b = &dst; 27 | uint16_t sport = packet_srcport(&packet); 28 | uint16_t dport = packet_dstport(&packet); 29 | uint8_t proto = packet_protocol(&packet); 30 | 31 | // Note: srcport/dstport are shared with icmp type/code respectively. 32 | if (proto == IPPROTO_ICMP) 33 | { 34 | // ICMP ECHO and ICMP ECHO RESPONSE should be keyed to the same Snort 35 | // instance. 36 | if (sport == 0) 37 | { 38 | sport = 8; 39 | } 40 | } 41 | 42 | // bi-directional keying, treating ip address as most significant bit(s). 43 | if (ip_compare(&src, &dst) == IP_LESSER) 44 | { 45 | a = &dst; 46 | b = &src; 47 | 48 | // never flip the type and code 49 | if (proto != IPPROTO_ICMP) 50 | { 51 | dport = packet_srcport(&packet); 52 | sport = packet_dstport(&packet); 53 | } 54 | } 55 | 56 | uint32_t hash = FNV_OFFSET_32; 57 | hash = fnv1a(a->addr8[0], hash); hash = fnv1a(a->addr8[1], hash); 58 | hash = fnv1a(a->addr8[2], hash); hash = fnv1a(a->addr8[3], hash); 59 | hash = fnv1a(a->addr8[4], hash); hash = fnv1a(a->addr8[5], hash); 60 | hash = fnv1a(a->addr8[6], hash); hash = fnv1a(a->addr8[7], hash); 61 | hash = fnv1a(a->addr8[8], hash); hash = fnv1a(a->addr8[9], hash); 62 | hash = fnv1a(a->addr8[10], hash); hash = fnv1a(a->addr8[11], hash); 63 | hash = fnv1a(a->addr8[12], hash); hash = fnv1a(a->addr8[13], hash); 64 | hash = fnv1a(a->addr8[14], hash); hash = fnv1a(a->addr8[15], hash); 65 | 66 | hash = fnv1a(b->addr8[0], hash); hash = fnv1a(b->addr8[1], hash); 67 | hash = fnv1a(b->addr8[2], hash); hash = fnv1a(b->addr8[3], hash); 68 | hash = fnv1a(b->addr8[4], hash); hash = fnv1a(b->addr8[5], hash); 69 | hash = fnv1a(b->addr8[6], hash); hash = fnv1a(b->addr8[7], hash); 70 | hash = fnv1a(b->addr8[8], hash); hash = fnv1a(b->addr8[9], hash); 71 | hash = fnv1a(b->addr8[10], hash); hash = fnv1a(b->addr8[11], hash); 72 | hash = fnv1a(b->addr8[12], hash); hash = fnv1a(b->addr8[13], hash); 73 | hash = fnv1a(b->addr8[14], hash); hash = fnv1a(b->addr8[15], hash); 74 | 75 | hash = fnv1a(proto, hash); 76 | 77 | hash = fnv1a((uint8_t)(sport >> 8), hash); 78 | hash = fnv1a((uint8_t)(sport & 0xFF), hash); 79 | hash = fnv1a((uint8_t)(dport >> 8), hash); 80 | hash = fnv1a((uint8_t)(dport & 0xFF), hash); 81 | 82 | return hash; 83 | } 84 | -------------------------------------------------------------------------------- /extras/timequeue.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | 39 | #include "timequeue.h" 40 | 41 | #define UNUSED __attribute__((unused)) 42 | 43 | /** Timeout Queue Create 44 | * @return pointer to new tmq 45 | */ 46 | struct tmq * 47 | tmq_create (unsigned timeout) 48 | { 49 | struct tmq *tmq; 50 | 51 | if ((tmq = malloc (sizeof (*tmq))) == NULL) 52 | return NULL; 53 | 54 | tmq->size = 0; 55 | tmq->head = NULL; 56 | tmq->tail = NULL; 57 | tmq->timeout = timeout ? timeout : TIMEOUT; 58 | 59 | #ifdef ENABLE_PTHREADS 60 | pthread_mutex_init (&tmq->lock, NULL); 61 | #endif 62 | 63 | tmq->state = QUEUE_STOPPED; 64 | 65 | return tmq; 66 | } 67 | 68 | /** Start the clock 69 | * @return 0 on success, -1 on failure 70 | */ 71 | #ifdef ENABLE_PTHREADS 72 | int 73 | tmq_start (struct tmq *tmq) 74 | { 75 | if (tmq == NULL) 76 | return -1; 77 | 78 | if (tmq->state != QUEUE_STOPPED) 79 | return -1; 80 | 81 | if (pthread_create (&tmq->thread, NULL, tmq_thread, (void *)tmq)) 82 | return -1; 83 | 84 | tmq->state = QUEUE_STARTED; 85 | 86 | return 0; 87 | } 88 | #else 89 | int 90 | tmq_start (struct tmq *tmq UNUSED) 91 | { 92 | return -1; 93 | } 94 | #endif 95 | 96 | /** Timeout Queue Stop 97 | * @return 0 on success, -1 on failure 98 | */ 99 | #ifdef ENABLE_PTHREADS 100 | int 101 | tmq_stop (struct tmq *tmq) 102 | { 103 | if (tmq == NULL) 104 | return -1; 105 | 106 | if (tmq->state != QUEUE_STARTED) 107 | return -1; 108 | 109 | tmq->state = QUEUE_STOPPED; 110 | 111 | if (pthread_cancel (tmq->thread)) 112 | return -1; 113 | 114 | return 0; 115 | } 116 | #else 117 | int 118 | tmq_stop (struct tmq *tmq UNUSED) 119 | { 120 | return -1; 121 | } 122 | #endif 123 | 124 | /** Timeout Queue Element Create 125 | * @return pointer to a new tmq element 126 | */ 127 | struct tmq_element * 128 | tmq_element_create (const void *p_key, unsigned int i_key_size) 129 | { 130 | struct tmq_element *elem; 131 | 132 | if (p_key == NULL || i_key_size == 0) 133 | return NULL; 134 | 135 | 136 | if ((elem = malloc (sizeof (*elem))) == NULL) 137 | return NULL; 138 | 139 | if ((elem->key = malloc (i_key_size)) == NULL) 140 | { 141 | free (elem); 142 | return NULL; 143 | } 144 | memcpy (elem->key, p_key, i_key_size); 145 | 146 | elem->prev = NULL; 147 | elem->next = NULL; 148 | gettimeofday (&elem->time, NULL); 149 | 150 | return elem; 151 | } 152 | 153 | /** Timeout Queue Destroy 154 | * @return -1 on failure, 0 on success 155 | */ 156 | int 157 | tmq_destroy (struct tmq *tmq) 158 | { 159 | if (tmq == NULL) 160 | return -1; 161 | 162 | if (tmq->state == QUEUE_STARTED) 163 | return -1; 164 | 165 | while (tmq->size > 0) 166 | tmq_delete (tmq, tmq->head); 167 | 168 | free (tmq); 169 | 170 | tmq = NULL; 171 | 172 | return 0; 173 | } 174 | 175 | /** Timeout Queue Pop 176 | * Remove the element from the list 177 | * @return -1 on failure, 0 on success 178 | */ 179 | int 180 | tmq_pop (struct tmq *tmq, struct tmq_element *elem) 181 | { 182 | if (tmq == NULL || tmq->size == 0 || elem == NULL) 183 | return -1; 184 | 185 | #ifdef ENABLE_PTHREADS 186 | pthread_mutex_lock (&tmq->lock); 187 | #endif 188 | 189 | if (elem == tmq->head) 190 | { 191 | tmq->head = elem->next; 192 | 193 | if (tmq->head == NULL) 194 | tmq->tail = NULL; 195 | else 196 | tmq->head->prev = NULL; 197 | } 198 | else 199 | { 200 | elem->prev->next = elem->next; 201 | 202 | if (elem->next == NULL) 203 | tmq->tail = elem->prev; 204 | else 205 | elem->next->prev = elem->prev; 206 | } 207 | 208 | elem->prev = NULL; 209 | elem->next = NULL; 210 | 211 | tmq->size--; 212 | 213 | #ifdef ENABLE_PTHREADS 214 | pthread_mutex_unlock (&tmq->lock); 215 | #endif 216 | 217 | return 0; 218 | } 219 | 220 | /** Timeout Queue Delete 221 | * Delete an element from the list 222 | * @return -1 on failure, 0 on success 223 | */ 224 | int 225 | tmq_delete (struct tmq *tmq, struct tmq_element *elem) 226 | { 227 | if (tmq == NULL || elem == NULL || elem->key == NULL) 228 | return -1; 229 | 230 | if (tmq_pop (tmq, elem)) 231 | return -1; 232 | 233 | free (elem->key); 234 | free (elem); 235 | 236 | return 0; 237 | } 238 | 239 | /** Timeout Queue Element Insert 240 | * @return -1 on failure, 0 on success 241 | */ 242 | int 243 | tmq_insert (struct tmq *tmq, struct tmq_element *elem) 244 | { 245 | if (tmq == NULL || elem == NULL) 246 | return -1; 247 | 248 | #ifdef ENABLE_PTHREADS 249 | pthread_mutex_lock (&tmq->lock); 250 | #endif 251 | 252 | if (tmq->size == 0) 253 | { 254 | tmq->head = elem; 255 | tmq->tail = elem; 256 | tmq->head->prev = NULL; 257 | tmq->head->next = NULL; 258 | } 259 | else 260 | { 261 | elem->next = tmq->head; 262 | elem->prev = NULL; 263 | tmq->head->prev = elem; 264 | tmq->head = elem; 265 | } 266 | 267 | tmq->size++; 268 | gettimeofday (&elem->time, NULL); 269 | 270 | #ifdef ENABLE_PTHREADS 271 | pthread_mutex_unlock (&tmq->lock); 272 | #endif 273 | 274 | return 0; 275 | } 276 | 277 | /** Update the atime on the element and bump it up the tmq 278 | * @return -1 on failure, 0 on success 279 | */ 280 | int 281 | tmq_bump (struct tmq *tmq, struct tmq_element *elem) 282 | { 283 | if (tmq == NULL || elem == NULL) 284 | return -1; 285 | 286 | if (tmq_pop (tmq, elem)) 287 | return -1; 288 | 289 | tmq_insert (tmq, elem); 290 | 291 | return 0; 292 | } 293 | 294 | /** Timeout Queue Find 295 | * @return pointer to matching element 296 | */ 297 | struct tmq_element * 298 | tmq_find (struct tmq *tmq, const void *p_key) 299 | { 300 | struct tmq_element *it; 301 | 302 | if (tmq == NULL || p_key == NULL) 303 | return NULL; 304 | 305 | for (it = tmq->head; it; it = it->next) 306 | if (tmq->compare (p_key, it->key) == 0) 307 | return it; 308 | 309 | return NULL; 310 | } 311 | 312 | /** Timeout old elements in the tmq 313 | * @return number of elements timed out 314 | */ 315 | int 316 | tmq_timeout (struct tmq *tmq) 317 | { 318 | struct tmq_element *it; 319 | struct timeval timeout; 320 | int removed = 0; 321 | 322 | if (tmq == NULL) 323 | return -1; 324 | 325 | gettimeofday (&timeout, NULL); 326 | timeout.tv_sec -= TIMEOUT; 327 | 328 | for (it = tmq->tail; it; it = tmq->tail) 329 | { 330 | if (it->time.tv_sec > timeout.tv_sec) 331 | break; 332 | 333 | if (tmq->task != NULL) 334 | tmq->task (it->key); 335 | 336 | tmq_delete (tmq, it); 337 | removed++; 338 | } 339 | 340 | return removed; 341 | } 342 | 343 | /** Timeout Thread 344 | * @return void * 345 | */ 346 | #ifdef ENABLE_PTHREADS 347 | void * 348 | tmq_thread (void *args) 349 | { 350 | struct tmq *tmq = (struct tmq *)args; 351 | struct timespec timeout; 352 | timeout.tv_sec = TIMEOUT_INTERVAL; 353 | timeout.tv_nsec = 0; 354 | 355 | pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); 356 | pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL); 357 | 358 | while (1) 359 | { 360 | nanosleep(&timeout, NULL); 361 | tmq_timeout (tmq); 362 | } 363 | 364 | return (void *)0; 365 | } 366 | #else 367 | void * 368 | tmq_thread (void *args UNUSED) 369 | { 370 | return (void *)-1; 371 | } 372 | #endif 373 | -------------------------------------------------------------------------------- /extras/timequeue.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef __TIMEOUT_QUEUE_H__ 31 | #define __TIMEOUT_QUEUE_H__ 32 | 33 | #include 34 | #include 35 | 36 | /** Default Queue Time value (in seconds) 37 | */ 38 | #define DEFAULT_TIMEOUT 60 39 | 40 | #ifndef TIMEOUT 41 | # define TIMEOUT DEFAULT_TIMEOUT 42 | #endif 43 | 44 | /** Schedule check interval 45 | * how often to check for expired elements 46 | */ 47 | #define DEFAULT_TIMEOUT_INTERVAL 1 48 | 49 | #ifndef TIMEOUT_INTERVAL 50 | # define TIMEOUT_INTERVAL DEFAULT_TIMEOUT_INTERVAL 51 | #endif 52 | 53 | /** State of the tmq 54 | */ 55 | typedef enum 56 | { 57 | QUEUE_STOPPED, 58 | QUEUE_STARTED 59 | } QUEUE_STATE; 60 | 61 | /** Schedule Queue Element 62 | */ 63 | struct tmq_element 64 | { 65 | struct tmq_element *prev; 66 | struct tmq_element *next; 67 | struct timeval time; /* access time */ 68 | void *key; 69 | }; 70 | 71 | /** Schedule Queue Structure 72 | */ 73 | struct tmq 74 | { 75 | struct tmq_element *head; 76 | struct tmq_element *tail; 77 | int tmq; 78 | int size; 79 | int timeout; 80 | 81 | pthread_t thread; 82 | pthread_mutex_t lock; 83 | QUEUE_STATE state; 84 | 85 | int (*compare) (const void *p1, const void *p2); 86 | int (*task) (const void *p); 87 | }; 88 | 89 | /** Timer routine 90 | */ 91 | extern void *tmq_thread (void *args); 92 | 93 | /** Create a new tmq 94 | */ 95 | extern struct tmq *tmq_create (); 96 | 97 | /** Start the expiration thread for the tmq 98 | */ 99 | int tmq_start (struct tmq *tmq); 100 | 101 | /** Stop the expiration thread fro the tmq 102 | */ 103 | int tmq_stop (struct tmq *tmq); 104 | 105 | /** Create a new tmq element 106 | */ 107 | extern struct tmq_element *tmq_element_create (const void *p_key, 108 | unsigned int i_key_size); 109 | 110 | /** Destroy a tmq 111 | */ 112 | extern int tmq_destroy (struct tmq *tmq); 113 | 114 | /** Pop an element out of the tmq 115 | */ 116 | extern int tmq_pop (struct tmq *tmq, struct tmq_element *elem); 117 | 118 | /** Delete an element from the tmq 119 | */ 120 | extern int tmq_delete (struct tmq *tmq, struct tmq_element *elem); 121 | 122 | /** Insert an element into the tmq 123 | */ 124 | extern int tmq_insert (struct tmq *tmq, struct tmq_element *elem); 125 | 126 | /** Push element to top of tmq and update access time 127 | */ 128 | extern int tmq_bump (struct tmq *tmq, struct tmq_element *elem); 129 | 130 | /** Find an element that matches the data 131 | */ 132 | extern struct tmq_element *tmq_find (struct tmq *tmq, 133 | const void *p_key); 134 | 135 | /** Timeout old elements in the tmq 136 | */ 137 | extern int tmq_timeout (struct tmq *tmq); 138 | 139 | #endif /* __TIMEOUT_QUEUE_H__ */ 140 | -------------------------------------------------------------------------------- /include/packet.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | -------------------------------------------------------------------------------- /include/packet/ipaddr.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | /* 32 | * IPv4/IPv6 Address Encapsulation 33 | */ 34 | #ifndef PACKET_IPADDR_H 35 | #define PACKET_IPADDR_H 36 | 37 | #include 38 | #include 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | struct ipaddr { 45 | union { 46 | uint64_t addr64[2]; 47 | uint32_t addr32[4]; 48 | uint16_t addr16[8]; 49 | uint8_t addr8[16]; 50 | } __ipa_u_; 51 | #define addr64 __ipa_u_.addr64 52 | #define addr32 __ipa_u_.addr32 53 | #define addr16 __ipa_u_.addr16 54 | #define addr8 __ipa_u_.addr8 55 | }; 56 | 57 | typedef enum { 58 | IP_LESSER = -1, 59 | IP_EQUAL, 60 | IP_GREATER, 61 | } IP_CODE; 62 | 63 | /* 64 | * Compare 2 ip address structures, return whether ip_1 65 | * is greater than, less than or equal too ip_2. 66 | */ 67 | static inline int 68 | ip_compare(struct ipaddr *ip_1, struct ipaddr *ip_2) 69 | { 70 | /* Profiling tests show that 32 bit comparisons are 71 | * wayyy faster on 32 bit platforms than the 64 bit 72 | * variants. */ 73 | #ifndef __x86_64__ 74 | if (ip_1->addr32[0] < ip_2->addr32[0]) 75 | return IP_LESSER; 76 | if (ip_1->addr32[0] > ip_2->addr32[0]) 77 | return IP_GREATER; 78 | if (ip_1->addr32[1] < ip_2->addr32[1]) 79 | return IP_LESSER; 80 | if (ip_1->addr32[1] > ip_2->addr32[1]) 81 | return IP_GREATER; 82 | if (ip_1->addr32[2] < ip_2->addr32[2]) 83 | return IP_LESSER; 84 | if (ip_1->addr32[2] > ip_2->addr32[2]) 85 | return IP_GREATER; 86 | if (ip_1->addr32[3] < ip_2->addr32[3]) 87 | return IP_LESSER; 88 | if (ip_1->addr32[3] > ip_2->addr32[3]) 89 | return IP_GREATER; 90 | #else 91 | if (ip_1->addr64[0] < ip_2->addr64[0]) 92 | return IP_LESSER; 93 | if (ip_1->addr64[0] > ip_2->addr64[0]) 94 | return IP_GREATER; 95 | if (ip_1->addr64[1] < ip_2->addr64[1]) 96 | return IP_LESSER; 97 | if (ip_1->addr64[1] > ip_2->addr64[1]) 98 | return IP_GREATER; 99 | #endif 100 | 101 | return IP_EQUAL; 102 | } 103 | 104 | #ifdef __cplusplus 105 | }; 106 | #endif 107 | 108 | #endif /* PACKET_IPADDR_H */ 109 | -------------------------------------------------------------------------------- /include/packet/libpacket.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIBPACKET_H_ 2 | #define _LIBPACKET_H_ 3 | 4 | #define PACKAGE "libpacket" 5 | #define PACKAGE_VERSION "0.2.2" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /include/packet/options.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012, Victor Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions are met: 5 | * 6 | * 1. Redistributions of source code must retain the above copyright notice, 7 | * this list of conditions and the following disclaimer. 8 | * 9 | * 2. Redistributions in binary form must reproduce the above copyright notice, 10 | * this list of conditions and the following disclaimer in the documentation 11 | * and/or other materials provided with the distribution. 12 | * 13 | * 3. The name of the author may not be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | #ifndef PACKET_OPTIONS_H 28 | #define PACKET_OPTIONS_H 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | typedef struct Option 35 | { 36 | uint8_t type; 37 | uint8_t len; 38 | const uint8_t *value; 39 | } Option; 40 | 41 | #ifdef __cplusplus 42 | }; 43 | #endif 44 | 45 | #endif /* PACKET_OPTIONS_H */ 46 | -------------------------------------------------------------------------------- /include/packet/packet.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef PACKET_H 31 | #define PACKET_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | struct _PacketLayer 48 | { 49 | PROTOCOL protocol; 50 | unsigned size; 51 | const uint8_t *start; 52 | }; 53 | 54 | #ifndef MAX_LAYERS 55 | # define MAX_LAYERS 32 56 | #endif 57 | 58 | #ifndef MAX_TCPOPTLEN 59 | //# warning "MAX_TCPOPTLEN value 40 is only a guessed value to fix compilation" 60 | # define MAX_TCPOPTLEN 40 61 | #endif 62 | 63 | struct _Packet 64 | { 65 | unsigned version; 66 | struct ipaddr srcaddr; 67 | struct ipaddr dstaddr; 68 | uint16_t srcport; 69 | uint16_t dstport; 70 | uint8_t protocol; 71 | bool mf, df; 72 | uint16_t offset; 73 | uint32_t id; 74 | uint8_t ttl; 75 | uint8_t tos; 76 | uint16_t mss; 77 | uint8_t wscale; 78 | unsigned paysize; 79 | const uint8_t *payload; 80 | 81 | /* Alt payload is set outside of libpacket */ 82 | unsigned alt_paysize; 83 | uint8_t *alt_payload; 84 | 85 | Protocol *transport; 86 | unsigned layer_count; 87 | unsigned tcpopt_count; 88 | 89 | /* Start of some static lists */ 90 | Protocol layer[MAX_LAYERS]; 91 | Option tcp_option[MAX_TCPOPTLEN]; 92 | }; 93 | typedef struct _Packet Packet; 94 | 95 | struct pcap_pkthdr; 96 | 97 | /* Packet Functions 98 | */ 99 | Packet *packet_create( ); 100 | 101 | void packet_destroy(Packet *); 102 | 103 | void packet_clear(Packet* packet); 104 | 105 | int packet_set_datalink(unsigned datalink); 106 | 107 | int packet_decode(Packet *, const unsigned char *, unsigned); 108 | 109 | int packet_decode_pcap(Packet *, const uint8_t *, 110 | const struct pcap_pkthdr *); 111 | 112 | const char * packet_lib_version(void); 113 | 114 | void packet_stats(const struct packet_stats **ps); 115 | 116 | 117 | /* Packet layer functions 118 | * XXX Defining these here because there is a dependency on type Packet. 119 | */ 120 | Protocol *packet_proto_first(Packet *packet, unsigned *); 121 | 122 | Protocol *packet_proto_next(Packet *packet, unsigned *); 123 | 124 | unsigned packet_proto_count(Packet *packet); 125 | 126 | int packet_proto_size(Protocol *proto); 127 | 128 | const uint8_t *packet_proto_data(Protocol *proto); 129 | 130 | PROTOCOL packet_proto_proto(Protocol *proto); 131 | 132 | const char *packet_proto_name(Protocol *proto); 133 | 134 | 135 | /* Packet Type Accessors 136 | */ 137 | int packet_version(Packet *packet); 138 | 139 | struct ipaddr packet_srcaddr(Packet *packet); 140 | 141 | struct ipaddr packet_dstaddr(Packet *packet); 142 | 143 | bool packet_is_fragment(Packet *packet); 144 | 145 | bool packet_frag_mf(Packet *packet); 146 | 147 | bool packet_frag_df(Packet *packet); 148 | 149 | uint16_t packet_frag_offset(Packet *packet); 150 | 151 | uint8_t packet_protocol(Packet *packet); 152 | 153 | uint32_t packet_id(Packet *packet); 154 | 155 | uint8_t packet_ttl(Packet *packet); 156 | 157 | uint8_t packet_tos(Packet *packet); 158 | 159 | uint16_t packet_srcport(Packet *packet); 160 | 161 | uint16_t packet_dstport(Packet *packet); 162 | 163 | uint8_t packet_icmp_code(Packet *packet); 164 | 165 | uint8_t packet_icmp_type(Packet *packet); 166 | 167 | uint16_t packet_mss(Packet *packet); 168 | 169 | uint16_t packet_win(Packet *packet); 170 | 171 | uint16_t packet_winscale(Packet *packet); 172 | 173 | uint32_t packet_seq(Packet *packet); 174 | 175 | uint32_t packet_ack(Packet *packet); 176 | 177 | int packet_tcpflags(Packet *packet); 178 | 179 | bool packet_tcp_fin(Packet *packet); 180 | 181 | bool packet_tcp_syn(Packet *packet); 182 | 183 | bool packet_tcp_rst(Packet *packet); 184 | 185 | bool packet_tcp_push(Packet *packet); 186 | 187 | bool packet_tcp_ack(Packet *packet); 188 | 189 | bool packet_tcp_urg(Packet *packet); 190 | 191 | void packet_set_payload(Packet *packet, void *payload, 192 | uint32_t paysize); 193 | 194 | bool packet_has_alt_payload(Packet *packet); 195 | 196 | uint32_t packet_raw_paysize(Packet *packet); 197 | 198 | const uint8_t *packet_raw_payload(Packet *packet); 199 | 200 | uint32_t packet_paysize(Packet *packet); 201 | 202 | const uint8_t *packet_payload(Packet *packet); 203 | 204 | #ifdef __cplusplus 205 | }; 206 | #endif 207 | 208 | #endif /* PACKET_H */ 209 | -------------------------------------------------------------------------------- /include/packet/protocol.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | /* NOTE: packet/packet.h defines type Packet, thus this file relies 32 | * on it. */ 33 | 34 | #ifndef PACKET_PROTOCOL_H 35 | #define PACKET_PROTOCOL_H 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | typedef struct _PacketLayer Protocol; 42 | 43 | typedef enum 44 | { 45 | PROTO_ETH, 46 | PROTO_PPP, 47 | PROTO_VLAN, 48 | PROTO_MPLS, 49 | PROTO_PPPOE, 50 | PROTO_IPX, 51 | PROTO_SPX, 52 | PROTO_IP4, 53 | PROTO_IP6, 54 | PROTO_IP6_RTE, 55 | PROTO_IP6_FRAG, 56 | PROTO_IP6_EXT, /* DST OPTS and HBH */ 57 | PROTO_GRE, 58 | PROTO_TCP, 59 | PROTO_UDP, 60 | PROTO_SCTP, 61 | PROTO_ICMP, 62 | PROTO_ICMP6, 63 | PROTO_MAX 64 | } PROTOCOL; 65 | 66 | #ifdef __cplusplus 67 | }; 68 | #endif 69 | 70 | #endif /* PACKET_PROTOCOL_H */ 71 | -------------------------------------------------------------------------------- /include/packet/stats.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef PACKET_STATS_H 32 | #define PACKET_STATS_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /* Protocol decoding stats 39 | */ 40 | struct packet_stats { 41 | uint32_t total_packets; /* total packets received */ 42 | uint32_t total_bytes; /* total bytes received */ 43 | uint32_t total_errors; /* bad packet received */ 44 | 45 | uint32_t mplss_packets; /* mpls packets */ 46 | uint32_t mplss_bytes; /* mpls bytes */ 47 | uint32_t mplss_tooshort; /* packet too short */ 48 | 49 | uint32_t pppoes_packets; /* pppoe packets */ 50 | uint32_t pppoes_bytes; /* pppoe bytes */ 51 | uint32_t pppoes_tooshort; /* packet too short */ 52 | 53 | uint32_t ppps_packets; /* ppp packets */ 54 | uint32_t ppps_bytes; /* ppp bytes */ 55 | uint32_t ppps_tooshort; /* packet too short */ 56 | 57 | uint32_t ipxs_packets; /* total number of ipx packets */ 58 | uint32_t ipxs_bytes; /* total number of ipx bytes */ 59 | uint32_t ipxs_badsum; /* checksum errors */ 60 | uint32_t ipxs_tooshort; /* packet too short */ 61 | 62 | uint32_t ips_packets; /* total number of ip packets */ 63 | uint32_t ips_bytes; /* total number of ip bytes */ 64 | uint32_t ips_badsum; /* checksum errors */ 65 | uint32_t ips_tooshort; /* packet too short */ 66 | uint32_t ips_toosmall; /* not enough data */ // XXX UNUSED 67 | uint32_t ips_badhlen; /* ip hlen < data size */ // XXX UNUSED 68 | uint32_t ips_badlen; /* ip len < ip hlen */ // XXX UNUSED 69 | uint32_t ips_fragments; /* fragments received */ 70 | 71 | uint32_t ip6s_packets; /* total number of ip packets */ 72 | uint32_t ip6s_bytes; /* total number of ip bytes */ 73 | uint32_t ip6s_ext; /* hop by hop headers */ 74 | uint32_t ip6s_rte; /* routing headers */ 75 | uint32_t ip6s_tooshort; /* packet too short */ 76 | uint32_t ip6s_toosmall; /* not enough data */ // XXX UNUSED 77 | uint32_t ip6s_badlen; /* ip len < ip hlen */ // XXX UNUSED 78 | uint32_t ip6s_fragments; /* fragments received */ 79 | 80 | uint32_t tcps_packets; /* total tcp packets */ 81 | uint32_t tcps_bytes; /* total tcp bytes */ 82 | uint32_t tcps_badsum; /* checksum errors */ 83 | uint32_t tcps_badoff; /* bad offset */ // XXX UNUSED 84 | uint32_t tcps_tooshort; /* not enough data */ 85 | 86 | uint32_t udps_packets; /* total udp packets */ 87 | uint32_t udps_bytes; /* total udp bytes */ 88 | uint32_t udps_badsum; /* checksum errors */ 89 | uint32_t udps_nosum; /* no checksum */ 90 | uint32_t udps_tooshort; /* not enough data */ 91 | 92 | uint32_t icmps_packets; /* total icmp packets */ 93 | uint32_t icmps_bytes; /* total icmp bytes */ 94 | uint32_t icmps_badsum; /* checksum errors */ 95 | uint32_t icmps_badtype; /* bad icmp code */ 96 | uint32_t icmps_badcode; /* bad icmp type */ 97 | uint32_t icmps_tooshort; /* not enough data */ 98 | 99 | uint32_t sctps_packets; /* total sctp packets */ 100 | uint32_t sctps_bytes; /* total sctp bytes */ 101 | uint32_t sctps_badsum; /* checksum errors */ 102 | uint32_t sctps_badtype; /* bad chunk type */ // XXX UNUSED 103 | uint32_t sctps_tooshort; /* not enough data */ 104 | }; 105 | 106 | #ifdef __cplusplus 107 | }; 108 | #endif 109 | 110 | #endif /* PACKET_STATS_H */ 111 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_STANDARD 11) 2 | 3 | add_library( 4 | packet 5 | SHARED 6 | ) 7 | 8 | set_target_properties( 9 | packet 10 | PROPERTIES 11 | VERSION 0.2.2 12 | SOVERSION 0 13 | ) 14 | 15 | target_sources( 16 | packet 17 | PRIVATE 18 | checksum.c 19 | checksum.h 20 | crc32.h 21 | eth.c 22 | eth.h 23 | ip4.c 24 | ip4.h 25 | ip6.c 26 | ip6.h 27 | ipx.c 28 | ipx.h 29 | mpls.c 30 | mpls.h 31 | packet.c 32 | packet_private.c 33 | packet_private.h 34 | ppp.c 35 | ppp.h 36 | pppoe.c 37 | pppoe.h 38 | raw.c 39 | raw.h 40 | sctp.c 41 | sctp.h 42 | spx.c 43 | spx.h 44 | tcp.c 45 | tcp.h 46 | udp.c 47 | udp.h 48 | icmp4.c 49 | icmp4.h 50 | icmp6.c 51 | icmp6.h 52 | vlan.c 53 | vlan.h 54 | ) 55 | 56 | target_include_directories( 57 | packet 58 | BEFORE 59 | PRIVATE "${CMAKE_SOURCE_DIR}/include" 60 | PRIVATE "${CMAKE_SOURCE_DIR}" 61 | ) 62 | 63 | install( 64 | TARGETS packet 65 | LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" 66 | ) 67 | -------------------------------------------------------------------------------- /src/checksum.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include 31 | #include "checksum.h" 32 | 33 | /** Checksum 34 | * Pseudo header is sized for ipv6 which is fine for ipv4 as well. 35 | * As long as I remember to zero out the extra address space. 36 | */ 37 | 38 | uint16_t 39 | checksum(uint16_t *addr, struct pseudo_hdr *pseudo, unsigned len) 40 | { 41 | uint32_t sum = 0; 42 | 43 | if (pseudo != NULL) 44 | { 45 | uint16_t *p16 = (uint16_t *)pseudo; 46 | 47 | sum += p16[0]; 48 | sum += p16[1]; 49 | sum += p16[2]; 50 | sum += p16[3]; 51 | sum += p16[4]; 52 | sum += p16[5]; 53 | sum += p16[6]; 54 | sum += p16[7]; 55 | sum += p16[8]; 56 | sum += p16[9]; 57 | sum += p16[10]; 58 | sum += p16[11]; 59 | sum += p16[12]; 60 | sum += p16[13]; 61 | sum += p16[14]; 62 | sum += p16[15]; 63 | sum += p16[16]; 64 | sum += p16[17]; 65 | } 66 | 67 | while (len > 1) 68 | { 69 | sum += *addr++; 70 | len -= 2; 71 | } 72 | 73 | if (len == 1) 74 | sum += *(unsigned char *) addr; 75 | 76 | sum = (sum >> 16) + (sum & 0xffff); 77 | sum += (sum >> 16); 78 | 79 | return ~sum; 80 | } 81 | -------------------------------------------------------------------------------- /src/checksum.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef CHECKSUM_H 31 | #define CHECKSUM_H 32 | 33 | #include 34 | #include 35 | 36 | struct pseudo_hdr 37 | { 38 | struct ipaddr srcaddr; 39 | struct ipaddr dstaddr; 40 | uint8_t zero; 41 | uint8_t protocol; 42 | uint16_t len; 43 | }; 44 | 45 | uint16_t checksum(uint16_t *, struct pseudo_hdr *, unsigned); 46 | 47 | #endif /* CHECKSUM_H */ 48 | -------------------------------------------------------------------------------- /src/crc32.h: -------------------------------------------------------------------------------- 1 | #ifndef CRC32CR_TABLE_H 2 | #define CRC32CR_TABLE_H 3 | 4 | #define CRC32C_POLY 0x1EDC6F41 5 | #define CRC32C(c,d) (c=(c>>8)^crc32_c[(c^(d))&0xFF]) 6 | 7 | unsigned long crc32_c[256] = { 8 | 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 9 | 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 10 | 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 11 | 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, 12 | 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, 13 | 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 14 | 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 15 | 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, 16 | 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, 17 | 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, 18 | 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 19 | 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 20 | 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 21 | 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, 22 | 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 23 | 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 24 | 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 25 | 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, 26 | 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 27 | 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, 28 | 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 29 | 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 30 | 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, 31 | 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, 32 | 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, 33 | 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 34 | 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 35 | 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, 36 | 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 37 | 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, 38 | 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 39 | 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 40 | 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 41 | 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, 42 | 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 43 | 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 44 | 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 45 | 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, 46 | 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 47 | 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, 48 | 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 49 | 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 50 | 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, 51 | 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, 52 | 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, 53 | 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 54 | 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 55 | 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, 56 | 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 57 | 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, 58 | 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 59 | 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 60 | 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 61 | 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, 62 | 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 63 | 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 64 | 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 65 | 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, 66 | 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, 67 | 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, 68 | 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 69 | 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 70 | 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, 71 | 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L, 72 | }; 73 | 74 | #endif /* CRC32CR_TABLE_H */ 75 | -------------------------------------------------------------------------------- /src/eth.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef __OpenBSD__ 37 | #include 38 | #include 39 | #else 40 | #include 41 | #endif 42 | 43 | #include 44 | 45 | #ifdef __linux__ 46 | #include 47 | #endif 48 | 49 | #include "packet_private.h" 50 | #include "vlan.h" 51 | #include "mpls.h" 52 | #include "pppoe.h" 53 | #include "ipx.h" 54 | #include "ip4.h" 55 | #include "ip6.h" 56 | 57 | #ifndef ETHERTYPE_MPLS 58 | # define ETHERTYPE_MPLS 0x8847 59 | #endif 60 | 61 | #ifndef ETHERTYPE_PPPOE 62 | # define ETHERTYPE_PPPOE 0x8864 63 | #endif 64 | 65 | #ifndef ETHERTYPE_IPX 66 | # define ETHERTYPE_IPX 0x8137 67 | #endif 68 | 69 | int 70 | bind_eth(int proto, const unsigned char *pkt, unsigned len, 71 | Packet *packet) 72 | { 73 | int ret = -1; 74 | 75 | switch (proto) 76 | { 77 | case ETHERTYPE_IP: 78 | ret = decode_ip(pkt, len, packet); 79 | break; 80 | case ETHERTYPE_IPV6: 81 | ret = decode_ip6(pkt, len, packet); 82 | break; 83 | case ETHERTYPE_VLAN: 84 | ret = decode_vlan(packet, pkt, len); 85 | break; 86 | case ETHERTYPE_MPLS: 87 | ret = decode_mpls(packet, pkt, len); 88 | break; 89 | case ETHERTYPE_PPPOE: 90 | ret = decode_pppoe(packet, pkt, len); 91 | break; 92 | case ETHERTYPE_IPX: 93 | ret = decode_ipx(packet, pkt, len); 94 | break; 95 | } 96 | 97 | return ret; 98 | } 99 | 100 | int 101 | decode_dlt_eth(const unsigned char *pkt, unsigned len, Packet *packet) 102 | { 103 | struct ether_header *eth = (struct ether_header *)pkt; 104 | 105 | if (len < sizeof *eth) 106 | return -1; 107 | 108 | packet->payload += sizeof *eth; 109 | packet->paysize -= sizeof *eth; 110 | 111 | packet_layer_ins(packet, pkt, sizeof *eth, PROTO_ETH); 112 | 113 | return bind_eth(ntohs(eth->ether_type), pkt + sizeof(*eth), 114 | len - sizeof(*eth), packet); 115 | } 116 | 117 | -------------------------------------------------------------------------------- /src/eth.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_ETH_H 31 | #define DECODE_ETH_H 32 | 33 | #define DLT_EN10MB 1 34 | 35 | int bind_eth(int proto, const unsigned char *pkt, unsigned len, 36 | Packet *packet); 37 | 38 | int decode_dlt_eth(const unsigned char *, unsigned, Packet *); 39 | 40 | #endif /* DECODE_ETH_H */ 41 | -------------------------------------------------------------------------------- /src/icmp4.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | #define __FAVOR_BSD 38 | #include 39 | 40 | #include "packet_private.h" 41 | 42 | #include "checksum.h" 43 | 44 | extern struct packet_stats s_stats; 45 | 46 | int 47 | decode_icmp4(const uint8_t *pkt, const uint32_t len, Packet *p) 48 | { 49 | struct icmp *icmp = (struct icmp *)pkt; 50 | 51 | s_stats.icmps_packets++; 52 | s_stats.icmps_bytes+=len; 53 | 54 | if (len < sizeof *icmp) 55 | { 56 | s_stats.icmps_tooshort++; 57 | return -1; 58 | } 59 | 60 | packet_layer_ins(p, pkt, sizeof *icmp, PROTO_ICMP); 61 | p->transport = packet_layer_current(p); 62 | 63 | p->srcport = icmp->icmp_type; 64 | p->dstport = icmp->icmp_code; 65 | 66 | /* Create the pseudo header before adjusting paysize */ 67 | struct pseudo_hdr pseudo; 68 | pseudo.srcaddr = p->srcaddr; 69 | pseudo.dstaddr = p->dstaddr; 70 | pseudo.zero = 0; 71 | pseudo.protocol = p->protocol; 72 | pseudo.len = htons(p->paysize); 73 | 74 | p->payload += sizeof *icmp; 75 | p->paysize -= sizeof *icmp; 76 | 77 | if (checksum((uint16_t *)icmp, &pseudo, ntohs(pseudo.len)) != 0) 78 | { 79 | s_stats.icmps_badsum++; 80 | } 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /src/icmp4.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2023, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_ICMP4_H 31 | #define DECODE_ICMP4_H 32 | 33 | int decode_icmp4(const uint8_t *pkt, const uint32_t len, Packet *p); 34 | 35 | #endif /* DECODE_ICMP4_H */ 36 | -------------------------------------------------------------------------------- /src/icmp6.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | /* TODO: When processing errors like "destination unreachable", "network 32 | * unreachable", etc., we should attempt to extract the partial packet stub 33 | * in the icmp payload. 34 | * 35 | * The goal is to send these router messages to the Snort instance that would 36 | * have processed packet which the message pertains too. Even though Snort does 37 | * not process ICMP messages to terminate flows (this would be a huge evasion 38 | * loophole), these messages are extremely interesting. 39 | * 40 | * NOTICE: This is a level of security focused packet steering potentially 41 | * worthy of patent or copyright. 42 | */ 43 | #include 44 | #include 45 | #include 46 | 47 | #include 48 | #include 49 | 50 | #define __FAVOR_BSD 51 | #include 52 | 53 | #include "packet_private.h" 54 | 55 | #include "checksum.h" 56 | 57 | 58 | struct icmp6 59 | { 60 | uint8_t type; 61 | uint8_t code; 62 | uint16_t cksum; 63 | union 64 | { 65 | uint32_t data32[1]; 66 | uint16_t data16[2]; 67 | uint8_t data8[4]; 68 | }; 69 | }; 70 | 71 | 72 | #define ICMP6_ECHO_REQUEST 128 73 | #define ICMP6_ECHO_REPLY 129 74 | #define MLD_LISTENER_QUERY 130 75 | #define MLD_LISTENER_REPORT 131 76 | #define MLD_LISTENER_REDUCTION 132 77 | #define ICMPV6_EXT_ECHO_REQUEST 160 78 | #define ICMPV6_EXT_ECHO_REPLY 161 79 | 80 | #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ 81 | #define ICMP6_DST_UNREACH_ADMIN 1 /* communication with destination */ 82 | /* administratively prohibited */ 83 | #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ 84 | #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ 85 | #define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */ 86 | 87 | #define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */ 88 | #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */ 89 | 90 | #define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ 91 | #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */ 92 | #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */ 93 | 94 | # 95 | 96 | 97 | extern struct packet_stats s_stats; 98 | 99 | int 100 | decode_icmp6(const uint8_t *pkt, const uint32_t len, Packet *p) 101 | { 102 | struct icmp6 *icmp = (struct icmp6 *)pkt; 103 | 104 | s_stats.icmps_packets++; 105 | s_stats.icmps_bytes+=len; 106 | 107 | if (len < sizeof *icmp) 108 | { 109 | s_stats.icmps_tooshort++; 110 | return -1; 111 | } 112 | 113 | packet_layer_ins(p, pkt, sizeof *icmp, PROTO_ICMP6); 114 | p->transport = packet_layer_current(p); 115 | 116 | p->srcport = icmp->type; 117 | p->dstport = icmp->code; 118 | 119 | /* Create the pseudo header before adjusting paysize */ 120 | struct pseudo_hdr pseudo; 121 | pseudo.srcaddr = p->srcaddr; 122 | pseudo.dstaddr = p->dstaddr; 123 | pseudo.zero = 0; 124 | pseudo.protocol = p->protocol; 125 | pseudo.len = htons(p->paysize); 126 | 127 | p->payload += sizeof *icmp; 128 | p->paysize -= sizeof *icmp; 129 | 130 | if (checksum((uint16_t *)icmp, &pseudo, ntohs(pseudo.len)) != 0) 131 | { 132 | s_stats.icmps_badsum++; 133 | } 134 | 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /src/icmp6.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2023, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_ICMP6_H 31 | #define DECODE_ICMP6_H 32 | 33 | int decode_icmp6(const uint8_t *pkt, const uint32_t len, Packet *p); 34 | 35 | #endif /* DECODE_ICMP6_H */ 36 | -------------------------------------------------------------------------------- /src/ip4.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef __OpenBSD__ 37 | # define IPPROTO_SCTP 132 38 | # include 39 | # include 40 | #endif 41 | 42 | #ifndef __USE_MISC 43 | #define __USE_MISC 44 | #endif 45 | #include 46 | #include 47 | 48 | #include "packet_private.h" 49 | 50 | #include "checksum.h" 51 | #include "ip4.h" 52 | #include "ip6.h" 53 | #include "tcp.h" 54 | #include "udp.h" 55 | #include "icmp4.h" 56 | #include "sctp.h" 57 | 58 | extern struct packet_stats s_stats; 59 | 60 | static inline int 61 | bind_ip(const uint8_t * pkt, const uint32_t len, Packet *p) 62 | { 63 | int ret = -1; 64 | 65 | switch (p->protocol) 66 | { 67 | case IPPROTO_TCP: 68 | ret = decode_tcp(pkt, len, p); 69 | break; 70 | case IPPROTO_UDP: 71 | ret = decode_udp(pkt, len, p); 72 | break; 73 | case IPPROTO_ICMP: 74 | ret = decode_icmp4(pkt, len, p); 75 | break; 76 | case IPPROTO_SCTP: 77 | ret = decode_sctp(pkt, len, p); 78 | break; 79 | case IPPROTO_IPIP: 80 | ret = decode_ip(pkt, len, p); 81 | break; 82 | case IPPROTO_IPV6: 83 | ret = decode_ip6(pkt, len, p); 84 | break; 85 | } 86 | 87 | return ret; 88 | } 89 | 90 | int 91 | decode_ip(const uint8_t * pkt, const uint32_t len, Packet *p) 92 | { 93 | struct ip *ip = (struct ip *) pkt; 94 | unsigned hlen = ip->ip_hl * 4; 95 | unsigned pay_len = ntohs((uint16_t) ip->ip_len) - hlen; 96 | 97 | s_stats.ips_packets++; 98 | s_stats.ips_bytes += len; 99 | 100 | p->version = 4; 101 | 102 | if (len < hlen || len < pay_len) 103 | { 104 | s_stats.ips_tooshort++; 105 | return -1; 106 | } 107 | 108 | packet_layer_ins(p, pkt, hlen, PROTO_IP4); 109 | 110 | p->offset = ntohs(ip->ip_off); 111 | 112 | p->df = (uint8_t) ((p->offset & 0x4000) >> 14); 113 | p->mf = (uint8_t) ((p->offset & 0x2000) >> 13); 114 | 115 | p->offset &= IP_OFFMASK; 116 | 117 | p->payload += hlen; 118 | p->paysize = pay_len; 119 | 120 | // FIXME-L Count the number of trailing bytes `(len - (pay_len + hlen))`. 121 | // While rare, it is possible to capture the Ethernet FCS. 122 | // trailing_bytes = (len - (pay_len - hlen)); 123 | 124 | p->id = ip->ip_id; 125 | p->tos = ip->ip_tos; 126 | p->ttl = ip->ip_ttl; 127 | 128 | p->srcaddr.addr32[0] = ip->ip_src.s_addr; 129 | p->dstaddr.addr32[0] = ip->ip_dst.s_addr; 130 | 131 | p->protocol = ip->ip_p; 132 | 133 | if (checksum((uint16_t *)ip, NULL, hlen) != 0) 134 | { 135 | s_stats.ips_badsum++; 136 | } 137 | 138 | if (p->offset || p->mf) 139 | { 140 | s_stats.ips_fragments++; 141 | return 0; 142 | } 143 | 144 | return bind_ip(pkt + hlen, len - hlen, p); 145 | } 146 | -------------------------------------------------------------------------------- /src/ip4.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_IP4_H 31 | #define DECODE_IP4_H 32 | 33 | int decode_ip(const uint8_t *pkt, const uint32_t len, Packet *p); 34 | 35 | #endif /* DECODE_IP4_H */ 36 | -------------------------------------------------------------------------------- /src/ip6.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef __OpenBSD__ 37 | # define IPPROTO_SCTP 132 38 | # include 39 | # include 40 | #endif 41 | 42 | #define __FAVOR_BSD 43 | #include 44 | #include 45 | 46 | #include "packet_private.h" 47 | 48 | #include "ip4.h" 49 | #include "ip6.h" 50 | #include "tcp.h" 51 | #include "udp.h" 52 | #include "sctp.h" 53 | #include "icmp6.h" 54 | 55 | extern struct packet_stats s_stats; 56 | 57 | struct ip6_rte 58 | { 59 | uint8_t ip6r_nxt; 60 | uint8_t ip6r_len; 61 | uint8_t ip6r_type; 62 | uint8_t ip6r_segleft; 63 | uint32_t ip6r_res; 64 | }; 65 | 66 | static inline int 67 | bind_ip6(const uint8_t *pkt, const uint32_t len, Packet *p) 68 | { 69 | int ret = -1; 70 | 71 | /* not calling bind_ip because icmp won't be a 72 | * valid ip6 protocol */ 73 | switch (p->protocol) 74 | { 75 | case IPPROTO_ROUTING: 76 | ret = decode_ip6_rte(pkt, len, p); 77 | break; 78 | case IPPROTO_FRAGMENT: 79 | ret = decode_ip6_frag(pkt, len, p); 80 | break; 81 | case IPPROTO_DSTOPTS: 82 | case IPPROTO_HOPOPTS: 83 | ret = decode_ip6_ext(pkt, len, p); 84 | break; 85 | case IPPROTO_ICMPV6: 86 | ret = decode_icmp6(pkt, len, p); 87 | break; 88 | case IPPROTO_TCP: 89 | ret = decode_tcp(pkt, len, p); 90 | break; 91 | case IPPROTO_UDP: 92 | ret = decode_udp(pkt, len, p); 93 | break; 94 | case IPPROTO_SCTP: 95 | ret = decode_sctp(pkt, len, p); 96 | break; 97 | case IPPROTO_IPIP: 98 | ret = decode_ip(pkt, len, p); 99 | break; 100 | case IPPROTO_IPV6: 101 | ret = decode_ip6(pkt, len, p); 102 | break; 103 | // NOTE: We should take a hard stance and drop all 104 | // technically anomolous packets 105 | //case IPPROTO_ICMP: 106 | // ret = decode_icmp4(pkt, len, p); 107 | // break; 108 | } 109 | 110 | return ret; 111 | } 112 | 113 | /* IPv6 Routing Header 114 | * 115 | */ 116 | int 117 | decode_ip6_rte(const uint8_t *pkt, const uint32_t len, Packet *p) 118 | { 119 | struct ip6_rte *rte = (struct ip6_rte *) pkt; 120 | unsigned rte_len; 121 | 122 | s_stats.ip6s_rte++; 123 | 124 | if (len < sizeof *rte) 125 | return -1; 126 | 127 | rte_len = rte->ip6r_len * 8 + 8; 128 | 129 | if (len < rte_len) 130 | return -1; 131 | 132 | p->payload += rte_len; 133 | p->paysize -= rte_len; 134 | 135 | packet_layer_ins(p, pkt, rte_len, PROTO_IP6_RTE); 136 | 137 | p->protocol = rte->ip6r_nxt; 138 | 139 | if (rte->ip6r_segleft > 0) 140 | memcpy(&p->dstaddr, pkt + rte_len - 16, sizeof(p->dstaddr)); 141 | 142 | return bind_ip6(pkt + rte_len, len - rte_len, p); 143 | } 144 | 145 | /* IPv6 Fragment Header 146 | * 147 | */ 148 | int 149 | decode_ip6_frag(const uint8_t *pkt, const uint32_t len, Packet *p) 150 | { 151 | struct ip6_frag *frag = (struct ip6_frag *) pkt; 152 | 153 | s_stats.ip6s_fragments++; 154 | 155 | if (len < sizeof *frag) 156 | return -1; 157 | 158 | int ip6_off = ntohs(frag->ip6f_offlg); 159 | 160 | p->offset = (ip6_off & IP6F_OFF_MASK); 161 | p->mf = (ip6_off & IP6F_MORE_FRAG); 162 | p->protocol = frag->ip6f_nxt; 163 | p->id = frag->ip6f_ident; 164 | 165 | p->payload += sizeof *frag; 166 | p->paysize -= sizeof *frag; 167 | 168 | packet_layer_ins(p, pkt, sizeof *frag, PROTO_IP6_FRAG); 169 | 170 | if (p->offset || p->mf) 171 | return 0; 172 | 173 | return bind_ip6(pkt + sizeof(*frag), len - sizeof(*frag), p); 174 | } 175 | 176 | /* IPv6 HOP or DST options 177 | * 178 | */ 179 | int 180 | decode_ip6_ext(const uint8_t *pkt, const uint32_t len, Packet *p) 181 | { 182 | struct ip6_ext *ext = (struct ip6_ext *) pkt; 183 | unsigned ext_len; 184 | 185 | s_stats.ip6s_ext++; 186 | 187 | if (len < sizeof *ext) 188 | return -1; 189 | 190 | ext_len = (ext->ip6e_len << 3) + 8; 191 | 192 | if (len < ext_len) 193 | return -1; 194 | 195 | p->paysize -= ntohs(ext_len); 196 | p->payload += ntohs(ext_len); 197 | p->protocol = ext->ip6e_nxt; 198 | 199 | p->payload += ext_len; 200 | p->paysize -= ext_len; 201 | 202 | packet_layer_ins(p, pkt, ext_len, PROTO_IP6_EXT); 203 | 204 | return bind_ip6(pkt + ext_len, len - ext_len, p); 205 | } 206 | 207 | /* IPv6 Header, also decoder entry 208 | * 209 | */ 210 | int 211 | decode_ip6(const uint8_t *pkt, const uint32_t len, Packet *p) 212 | { 213 | struct ip6_hdr *ip6 = (struct ip6_hdr *) pkt; 214 | 215 | s_stats.ip6s_packets++; 216 | s_stats.ip6s_bytes += len; 217 | 218 | if (len < sizeof *ip6) 219 | { 220 | s_stats.ip6s_tooshort++; 221 | return -1; 222 | } 223 | 224 | p->version = 6; 225 | p->protocol = ip6->ip6_nxt; 226 | 227 | // assignment of payload is different here because pay_len is not 228 | // influenced by potential ethernet padding. 229 | p->payload += sizeof *ip6; 230 | p->paysize = ntohs(ip6->ip6_plen); 231 | 232 | packet_layer_ins(p, pkt, sizeof *ip6, PROTO_IP6); 233 | 234 | p->ttl = ip6->ip6_hops; 235 | 236 | memcpy(&p->srcaddr, &ip6->ip6_src, sizeof p->srcaddr); 237 | memcpy(&p->dstaddr, &ip6->ip6_dst, sizeof p->dstaddr); 238 | 239 | return bind_ip6(pkt + sizeof(*ip6), len - sizeof(*ip6), p); 240 | } 241 | -------------------------------------------------------------------------------- /src/ip6.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_IP6_H 31 | #define DECODE_IP6_H 32 | 33 | int decode_ip6_rte(const uint8_t *, const uint32_t, Packet *); 34 | int decode_ip6_frag(const uint8_t *, const uint32_t, Packet *); 35 | int decode_ip6_ext(const uint8_t *, const uint32_t, Packet *); 36 | int decode_ip6(const uint8_t *, const uint32_t, Packet *); 37 | 38 | #endif /* DECODE_IP6_H */ 39 | -------------------------------------------------------------------------------- /src/ipx.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | /* XXX 31 | * 6/28/12 - IPX support needs substantial work done to make it robust. 32 | */ 33 | 34 | #include 35 | 36 | #include "packet_private.h" 37 | #include "spx.h" 38 | 39 | struct ipx 40 | { 41 | uint16_t ipx_cks; // unimplemented always ffff 42 | uint16_t ipx_len; 43 | uint8_t ipx_ttl; 44 | uint8_t ipx_type; 45 | /* Network number 0x00000000 means current network. 46 | * Network number 0xffffffff is broadcast address. */ 47 | uint8_t ipx_dst_net[4]; 48 | uint8_t ipx_dst_node[6]; // mac address 49 | uint16_t ipx_dst_socket; // Dest Port :| 50 | uint8_t ipx_src_net[4]; 51 | uint8_t ipx_src_node[6]; 52 | uint16_t ipx_src_socket; 53 | }; 54 | 55 | #define IPXPROTO_UNKWN 0 56 | #define IPXPROTO_RI 1 57 | #define IPXPROTO_PXP 4 58 | #define IPXPROTO_SPX 5 59 | #define IPXPROTO_NCP 17 60 | #define IPXPROTO_NETBIOS 20 61 | #define IPXPROTO_RAW 255 62 | 63 | extern struct packet_stats s_stats; 64 | 65 | static inline int 66 | bind_ipx(Packet *p, const uint8_t * pkt, const uint32_t len) 67 | { 68 | int ret = -1; 69 | 70 | switch (p->protocol) 71 | { 72 | case IPXPROTO_SPX: 73 | ret = decode_spx(p, pkt, len); 74 | break; 75 | 76 | default: 77 | ret = 0; 78 | } 79 | 80 | return ret; 81 | } 82 | 83 | int 84 | decode_ipx(Packet *p, const uint8_t * pkt, const uint32_t len) 85 | { 86 | struct ipx *ipx = (struct ipx *) pkt; 87 | 88 | s_stats.ipxs_packets++; 89 | s_stats.ipxs_bytes+=len; 90 | 91 | if (len < sizeof *ipx) 92 | { 93 | s_stats.ipxs_tooshort++; 94 | return -1; 95 | } 96 | 97 | packet_layer_ins(p, pkt, sizeof *ipx, PROTO_IPX); 98 | 99 | p->payload += sizeof *ipx; 100 | p->paysize -= sizeof *ipx; 101 | 102 | if (ipx->ipx_cks != 0xffff) 103 | { 104 | s_stats.ipxs_badsum++; 105 | //return -1; 106 | } 107 | 108 | /* processing ends here for now, need to implement: 109 | * RIP, 110 | * SAP, 111 | * SPX, 112 | * NLSP 113 | */ 114 | 115 | return bind_ipx(p, pkt + sizeof *ipx, len - sizeof *ipx); 116 | } 117 | -------------------------------------------------------------------------------- /src/ipx.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_IPX_H 31 | #define DECODE_IPX_H 32 | 33 | int decode_ipx(Packet *p, const uint8_t *pkt, const uint32_t len); 34 | 35 | #endif /* DECODE_IPX_H */ 36 | -------------------------------------------------------------------------------- /src/mpls.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | /* 31 | * TODO implement heuristics with reserved mpls labels 32 | * 33 | * 34 | */ 35 | #include 36 | 37 | #include "packet_private.h" 38 | #include "mpls.h" 39 | #include "ip4.h" 40 | #include "ip6.h" 41 | 42 | extern struct packet_stats s_stats; 43 | 44 | static inline int 45 | bind_mpls(Packet *packet, unsigned char nib, bool bos, 46 | const uint8_t *pkt, unsigned len) 47 | { 48 | if (!bos) 49 | decode_mpls(packet, pkt, len); 50 | 51 | switch (nib) { 52 | case 4: 53 | decode_ip(pkt, len, packet); 54 | break; 55 | case 6: 56 | decode_ip6(pkt, len, packet); 57 | break; 58 | } 59 | return 0; 60 | } 61 | 62 | int 63 | decode_mpls(Packet *packet, const uint8_t *pkt, unsigned len) 64 | { 65 | uint32_t *mpls = (uint32_t *)pkt; 66 | 67 | s_stats.mplss_packets++; 68 | s_stats.mplss_bytes+=len; 69 | 70 | if (len < sizeof(*mpls)) 71 | { 72 | s_stats.mplss_tooshort++; 73 | return -1; 74 | } 75 | 76 | uint8_t nibble, bos; 77 | 78 | /* ip version nibble */ 79 | nibble = (char)*(mpls+1) >> 4; 80 | bos = (*mpls & 0x10000) >> 16; 81 | 82 | packet->payload += sizeof *mpls; 83 | packet->paysize -= sizeof *mpls; 84 | 85 | packet_layer_ins(packet, pkt, sizeof *mpls, PROTO_MPLS); 86 | 87 | return bind_mpls(packet, nibble, bos, pkt + sizeof(*mpls), 88 | len - sizeof(*mpls)); 89 | } 90 | -------------------------------------------------------------------------------- /src/mpls.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_MPLS_H 31 | #define DECODE_MPLS_H 32 | 33 | int decode_mpls(Packet *packet, const uint8_t *pkt, unsigned len); 34 | 35 | #endif /* DECODE_MPLS_H */ 36 | -------------------------------------------------------------------------------- /src/packet.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef HAVE_PCAP_H 37 | #include 38 | #endif 39 | 40 | #ifndef __USE_MISC 41 | #define __USE_MISC 42 | #endif 43 | #include 44 | 45 | #include "packet_private.h" 46 | 47 | #include "raw.h" 48 | #include "eth.h" 49 | #include "ip4.h" 50 | #include "ip6.h" 51 | #include "tcp.h" 52 | #include "udp.h" 53 | #include "sctp.h" 54 | 55 | struct packet_stats s_stats; 56 | 57 | static int 58 | (*decode_dlt)(const uint8_t *pkt, unsigned len, Packet *packet) = &decode_dlt_eth; 59 | 60 | Packet * 61 | packet_create() 62 | { 63 | Packet *packet = malloc(sizeof *packet); 64 | if (packet == NULL) 65 | return NULL; 66 | 67 | memset(packet, 0, PKT_ZERO_LEN); 68 | return packet; 69 | } 70 | 71 | void 72 | packet_clear(Packet* packet) 73 | { 74 | memset(packet, 0, PKT_ZERO_LEN); 75 | } 76 | 77 | void 78 | packet_destroy(Packet *packet) 79 | { 80 | if (packet == NULL) 81 | return; 82 | 83 | // FIXME-H: When the user attaches alt_payload, as in the case of 84 | // `extra/defragment.c` also attach a "destroy callback". 85 | // If a destroy callback is set, call it here to release the alternate payload. 86 | if (packet->alt_payload != NULL) abort(); 87 | 88 | free(packet); 89 | } 90 | 91 | int 92 | packet_set_datalink(unsigned datalink) 93 | { 94 | switch(datalink) 95 | { 96 | case DLT_EN10MB: 97 | decode_dlt = &decode_dlt_eth; 98 | return 0; 99 | 100 | case DLT_RAW: 101 | decode_dlt = &decode_dlt_raw; 102 | return 0; 103 | } 104 | 105 | return -1; 106 | } 107 | 108 | int 109 | packet_decode(Packet *packet, const uint8_t *pkt, unsigned len) 110 | { 111 | if (packet == NULL || pkt == NULL || len == 0) 112 | return -1; 113 | 114 | s_stats.total_packets++; 115 | s_stats.total_bytes += len; 116 | 117 | packet->payload = pkt; 118 | packet->paysize = len; 119 | 120 | int ret = decode_dlt(pkt, len, packet); 121 | 122 | if (ret) s_stats.total_errors ++; 123 | 124 | return ret; 125 | } 126 | 127 | #ifdef HAVE_PCAP_H 128 | int 129 | packet_decode_pcap(Packet *packet, const uint8_t *pkt, 130 | const struct pcap_pkthdr *pkthdr) 131 | { 132 | if (pkthdr == NULL) 133 | return -1; 134 | 135 | return packet_decode(packet, pkt, pkthdr->caplen); 136 | } 137 | #endif /* HAVE_PCAP_H */ 138 | 139 | /* 140 | * Library routines 141 | */ 142 | 143 | #include 144 | static const char packet_version_string[] = 145 | PACKAGE " version " PACKAGE_VERSION; 146 | 147 | const char * 148 | packet_lib_version(void) 149 | { 150 | return packet_version_string; 151 | } 152 | 153 | void 154 | packet_stats(const struct packet_stats **ps) 155 | { 156 | *ps = &s_stats; 157 | } 158 | 159 | /* 160 | * Packet Layer Accessors/Iterators 161 | */ 162 | Protocol *packet_proto_first(Packet *packet, unsigned *iterator) 163 | { 164 | *iterator = 0; 165 | 166 | if (packet->layer_count > 0) 167 | return &packet->layer[0]; 168 | 169 | return NULL; 170 | } 171 | 172 | Protocol *packet_proto_next(Packet *packet, unsigned *iterator) 173 | { 174 | *iterator = *iterator + 1; 175 | 176 | if (*iterator < packet->layer_count) 177 | return &packet->layer[*iterator]; 178 | 179 | return NULL; 180 | } 181 | 182 | Protocol *packet_proto_layer(Packet *packet, unsigned layer) 183 | { 184 | if (layer < packet->layer_count) 185 | return &packet->layer[layer]; 186 | 187 | return NULL; 188 | } 189 | 190 | unsigned packet_proto_count(Packet *packet) 191 | { 192 | return packet->layer_count; 193 | } 194 | 195 | int packet_proto_size(Protocol *proto) 196 | { 197 | return proto->size; 198 | } 199 | 200 | const uint8_t *packet_proto_data(Protocol *proto) 201 | { 202 | return proto->start; 203 | } 204 | 205 | PROTOCOL packet_proto_proto(Protocol *proto) 206 | { 207 | return proto->protocol; 208 | } 209 | 210 | /* XXX Needs to remain in the same order as PROTOCOL in 211 | * $(srcdir)/include/packet/protocol.h */ 212 | static const char *proto_map[PROTO_MAX] = { 213 | "eth", 214 | "ppp", 215 | "vlan", 216 | "mpls", 217 | "pppoe", 218 | "ipx", 219 | "spx", 220 | "ip4", 221 | "ip6", 222 | "rte6", 223 | "frag6", 224 | "ext6", 225 | "gre", 226 | "tcp", 227 | "udp", 228 | "sctp", 229 | "icmp", 230 | "icmp6" 231 | }; 232 | 233 | #define ENUM2STR(num, map) \ 234 | ((num < sizeof(map)/sizeof(map[0])) ? map[num] : "undefined") 235 | 236 | const char *packet_proto_name(Protocol *proto) 237 | { 238 | return ENUM2STR(proto->protocol, proto_map); 239 | } 240 | 241 | /* IP Protocol Accessors */ 242 | int packet_version(Packet *packet) 243 | { 244 | return packet->version; 245 | } 246 | 247 | struct ipaddr packet_srcaddr(Packet *packet) 248 | { 249 | return packet->srcaddr; 250 | } 251 | 252 | struct ipaddr packet_dstaddr(Packet *packet) 253 | { 254 | return packet->dstaddr; 255 | } 256 | 257 | bool packet_is_fragment(Packet *packet) 258 | { 259 | return packet->offset || packet->mf; 260 | } 261 | 262 | bool packet_frag_mf(Packet *packet) 263 | { 264 | return packet->mf; 265 | } 266 | 267 | bool packet_frag_df(Packet *packet) 268 | { 269 | return packet->df; 270 | } 271 | 272 | uint16_t packet_frag_offset(Packet *packet) 273 | { 274 | return packet->offset; 275 | } 276 | 277 | uint8_t packet_protocol(Packet *packet) 278 | { 279 | return packet->protocol; 280 | } 281 | 282 | uint32_t packet_id(Packet *packet) 283 | { 284 | return packet->id; 285 | } 286 | 287 | uint8_t packet_ttl(Packet *packet) 288 | { 289 | return packet->ttl; 290 | } 291 | 292 | uint8_t packet_tos(Packet *packet) 293 | { 294 | return packet->tos; 295 | } 296 | 297 | /* Transport Protocol Accessors */ 298 | uint16_t packet_srcport(Packet *packet) 299 | { 300 | return packet->srcport; 301 | } 302 | 303 | uint16_t packet_dstport(Packet *packet) 304 | { 305 | return packet->dstport; 306 | } 307 | 308 | uint8_t packet_icmp_type(Packet *packet) 309 | { 310 | return packet->srcport; 311 | } 312 | 313 | uint8_t packet_icmp_code(Packet *packet) 314 | { 315 | return packet->dstport; 316 | } 317 | 318 | /* TCP Accessors */ 319 | uint16_t packet_mss(Packet *packet) 320 | { 321 | if (!validate_transport_protocol(packet, PROTO_TCP)) 322 | return 0; 323 | 324 | // TODO implement me 325 | return 0; 326 | } 327 | 328 | uint16_t packet_win(Packet *packet) 329 | { 330 | if (!validate_transport_protocol(packet, PROTO_TCP)) 331 | return 0; 332 | 333 | return ntohs(((struct tcphdr *)(packet->transport->start))->th_win); 334 | } 335 | 336 | uint16_t packet_winscale(Packet *packet) 337 | { 338 | if (!validate_transport_protocol(packet, PROTO_TCP)) 339 | return 0; 340 | 341 | // TODO implement me 342 | return 0; 343 | } 344 | 345 | uint32_t packet_seq(Packet *packet) 346 | { 347 | if (!validate_transport_protocol(packet, PROTO_TCP)) 348 | return 0; 349 | 350 | return ntohl(((struct tcphdr *)(packet->transport->start))->th_seq); 351 | } 352 | 353 | uint32_t packet_ack(Packet *packet) 354 | { 355 | if (!validate_transport_protocol(packet, PROTO_TCP)) 356 | return 0; 357 | 358 | return ntohl(((struct tcphdr *)(packet->transport->start))->th_ack); 359 | } 360 | 361 | /* TCP Flags Accessors */ 362 | int packet_tcpflags(Packet *packet) 363 | { 364 | if (!validate_transport_protocol(packet, PROTO_TCP)) 365 | return 0; 366 | 367 | return ((struct tcphdr *)packet->transport->start)->th_flags; 368 | } 369 | 370 | bool packet_tcp_fin(Packet *packet) 371 | { 372 | if (!validate_transport_protocol(packet, PROTO_TCP)) 373 | return false; 374 | 375 | return ((struct tcphdr *)packet->transport->start)->th_flags & TH_FIN; 376 | } 377 | 378 | bool packet_tcp_syn(Packet *packet) 379 | { 380 | if (!validate_transport_protocol(packet, PROTO_TCP)) 381 | return false; 382 | 383 | return ((struct tcphdr *)packet->transport->start)->th_flags & TH_SYN; 384 | } 385 | 386 | bool packet_tcp_rst(Packet *packet) 387 | { 388 | if (!validate_transport_protocol(packet, PROTO_TCP)) 389 | return false; 390 | 391 | return ((struct tcphdr *)packet->transport->start)->th_flags & TH_RST; 392 | } 393 | 394 | bool packet_tcp_push(Packet *packet) 395 | { 396 | if (!validate_transport_protocol(packet, PROTO_TCP)) 397 | return false; 398 | 399 | return ((struct tcphdr *)packet->transport->start)->th_flags & TH_PUSH; 400 | } 401 | 402 | bool packet_tcp_ack(Packet *packet) 403 | { 404 | if (!validate_transport_protocol(packet, PROTO_TCP)) 405 | return false; 406 | 407 | return ((struct tcphdr *)packet->transport->start)->th_flags & TH_ACK; 408 | } 409 | 410 | bool packet_tcp_urg(Packet *packet) 411 | { 412 | if (!validate_transport_protocol(packet, PROTO_TCP)) 413 | return false; 414 | 415 | return ((struct tcphdr *)packet->transport->start)->th_flags & TH_URG; 416 | } 417 | 418 | void packet_set_payload(Packet *packet, void *_payload, uint32_t paysize) 419 | { 420 | uint8_t *payload = (uint8_t *)_payload; 421 | packet->alt_payload = payload; 422 | packet->alt_paysize = paysize; 423 | return; 424 | } 425 | 426 | bool packet_has_alt_payload(Packet *packet) 427 | { 428 | /* should not be necessary to check both of these values */ 429 | return (packet->alt_payload || packet->alt_paysize); 430 | } 431 | 432 | /* just return the raw values for this packet 433 | * this could provide a subtle performance increase if used correctly */ 434 | uint32_t packet_raw_paysize(Packet *packet) 435 | { 436 | return packet->paysize; 437 | } 438 | 439 | const uint8_t *packet_raw_payload(Packet *packet) 440 | { 441 | return packet->payload; 442 | } 443 | 444 | /* these functions will return the alternate payload if it exists 445 | * otherwise they return the raw payload */ 446 | uint32_t packet_paysize(Packet *packet) 447 | { 448 | return (packet->alt_paysize ? packet->alt_paysize : packet->paysize); 449 | } 450 | 451 | const uint8_t *packet_payload(Packet *packet) 452 | { 453 | return (packet->alt_payload ? packet->alt_payload : packet->payload); 454 | } 455 | -------------------------------------------------------------------------------- /src/packet_private.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | #include "packet_private.h" 35 | 36 | /* convenient helper */ 37 | #define current_layer (packet->layer_count-1) 38 | 39 | /* Insert a protocol layer into the packet */ 40 | inline int 41 | packet_layer_ins(Packet *packet, const uint8_t *start, unsigned size, 42 | PROTOCOL proto) 43 | { 44 | if (packet->layer_count == MAX_LAYERS) 45 | { 46 | return -1; 47 | } 48 | 49 | packet->layer_count++; 50 | 51 | /* index is count - 1 */ 52 | packet->layer[current_layer].protocol = proto; 53 | packet->layer[current_layer].start = start; 54 | packet->layer[current_layer].size = size; 55 | 56 | return 0; 57 | } 58 | 59 | /* Remove a protocol layer from the packet 60 | * 61 | * NOTE: to remove a layer all you need to do is reduce the count. 62 | * this saves time by not having to memset the structure */ 63 | inline int 64 | packet_layer_rem(Packet *packet) 65 | { 66 | if (packet->layer_count == 0) 67 | { 68 | return -1; 69 | } 70 | 71 | packet->layer_count--; 72 | 73 | return 0; 74 | } 75 | 76 | /* Assign a pointer to the current layer 77 | * 78 | */ 79 | inline Protocol * 80 | packet_layer_current(Packet *packet) 81 | { 82 | if (packet->layer_count == 0) 83 | { 84 | return NULL; 85 | } 86 | 87 | return &packet->layer[current_layer]; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/packet_private.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef PACKET_PRIVATE_H 31 | #define PACKET_PRIVATE_H 32 | 33 | #ifdef DEBUG 34 | #define inline 35 | #endif 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #ifndef __USE_MISC 44 | #define __USE_MISC 45 | #endif 46 | #include 47 | 48 | #include "packet.h" 49 | #include "checksum.h" 50 | 51 | #if 0 52 | struct _PacketLayer 53 | { 54 | PROTOCOL protocol; 55 | unsigned size; 56 | const uint8_t *start; 57 | }; 58 | 59 | #ifndef MAX_LAYERS 60 | # define MAX_LAYERS 32 61 | #endif 62 | 63 | #ifndef MAX_TCPOPTLEN 64 | //# warning "MAX_TCPOPTLEN value 40 is only a guessed value to fix compilation" 65 | # define MAX_TCPOPTLEN 40 66 | #endif 67 | 68 | struct _Packet 69 | { 70 | unsigned version; 71 | struct ipaddr srcaddr; 72 | struct ipaddr dstaddr; 73 | uint16_t srcport; 74 | uint16_t dstport; 75 | uint8_t protocol; 76 | bool mf, df; 77 | uint16_t offset; 78 | uint32_t id; 79 | uint8_t ttl; 80 | uint8_t tos; 81 | uint16_t mss; 82 | uint8_t wscale; 83 | unsigned paysize; 84 | const uint8_t *payload; 85 | 86 | /* Alt payload is set outside of libpacket */ 87 | unsigned alt_paysize; 88 | uint8_t *alt_payload; 89 | 90 | Protocol *transport; 91 | unsigned layer_count; 92 | unsigned tcpopt_count; 93 | 94 | /* Start of some static lists */ 95 | Protocol layer[MAX_LAYERS]; 96 | Option tcp_option[MAX_TCPOPTLEN]; 97 | }; 98 | #endif 99 | 100 | #define PKT_ZERO_LEN offsetof(Packet, tcpopt_count) 101 | 102 | int packet_layer_ins(Packet *packet, const uint8_t *start, 103 | unsigned size, PROTOCOL proto); 104 | 105 | int packet_layer_rem(Packet *packet); 106 | 107 | Protocol * packet_layer_current(Packet *packet); 108 | 109 | /* Inline packet helpers */ 110 | static inline bool 111 | validate_transport_protocol(Packet *packet, PROTOCOL protocol) 112 | { 113 | if (packet->transport == NULL) 114 | return false; 115 | 116 | if (packet->transport->protocol != protocol) 117 | return false; 118 | 119 | return true; 120 | } 121 | 122 | #endif /* PACKET_PRIVATE_H */ 123 | -------------------------------------------------------------------------------- /src/ppp.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include 31 | 32 | #include "packet_private.h" 33 | #include "ip4.h" 34 | #include "ip6.h" 35 | #include "ipx.h" 36 | 37 | #define PPP_IP4 0x0021 38 | #define PPP_IPX 0x002b 39 | #define PPP_IP6 0x0057 40 | 41 | extern struct packet_stats s_stats; 42 | 43 | static inline int 44 | bind_ppp(uint16_t ppp, Packet *packet, const uint8_t *pkt, unsigned len) 45 | { 46 | int ret = -1; 47 | 48 | switch(ppp) 49 | { 50 | case PPP_IP4: 51 | ret = decode_ip(pkt, len, packet); 52 | break; 53 | 54 | case PPP_IP6: 55 | ret = decode_ip6(pkt, len, packet); 56 | break; 57 | 58 | case PPP_IPX: 59 | ret = decode_ipx(packet, pkt, len); 60 | break; 61 | }; 62 | 63 | return ret; 64 | } 65 | 66 | int 67 | decode_ppp(Packet *packet, const uint8_t *pkt, unsigned len) 68 | { 69 | uint16_t *ppp = (uint16_t *) pkt; 70 | 71 | s_stats.ppps_packets++; 72 | s_stats.ppps_bytes+=len; 73 | 74 | if (len < sizeof *ppp) 75 | { 76 | s_stats.ppps_tooshort++; 77 | return -1; 78 | } 79 | 80 | packet->payload += sizeof *ppp; 81 | packet->paysize -= sizeof *ppp; 82 | 83 | packet_layer_ins(packet, pkt, sizeof *ppp, PROTO_PPP); 84 | 85 | /* same protocols */ 86 | return bind_ppp(ntohs(*ppp), packet, pkt + sizeof(*ppp), 87 | len - sizeof(*ppp)); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/ppp.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_PPPOE_H 31 | #define DECODE_PPPOE_H 32 | 33 | int decode_ppp(Packet *, const unsigned char *, unsigned); 34 | 35 | #endif /* DECODE_PPPOEH */ 36 | -------------------------------------------------------------------------------- /src/pppoe.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include 31 | 32 | #include "packet_private.h" 33 | #include "ppp.h" 34 | 35 | /* struct pppoe 36 | * { 37 | * int pppoe_ver:4; 38 | * int pppoe_type:4; 39 | * uint8_t pppoe_code; 40 | * uint16_t pppoe_sid; 41 | * uint16_t pppoe_len; 42 | * }; 43 | */ 44 | #define PPPOE_SIZE 6 45 | 46 | extern struct packet_stats s_stats; 47 | 48 | int 49 | decode_pppoe(Packet *packet, const uint8_t *pkt, unsigned len) 50 | { 51 | s_stats.pppoes_packets++; 52 | s_stats.pppoes_bytes+=len; 53 | 54 | if (len < PPPOE_SIZE) 55 | { 56 | s_stats.pppoes_tooshort++; 57 | return -1; 58 | } 59 | 60 | packet->payload += PPPOE_SIZE; 61 | packet->paysize -= PPPOE_SIZE; 62 | 63 | packet_layer_ins(packet, pkt, PPPOE_SIZE, PROTO_PPPOE); 64 | 65 | return decode_ppp(packet, pkt + PPPOE_SIZE, len - PPPOE_SIZE); 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/pppoe.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_PPPOE_H 31 | #define DECODE_PPPOE_H 32 | 33 | int decode_pppoe(Packet *, const unsigned char *, unsigned); 34 | 35 | #endif /* DECODE_PPPOEH */ 36 | -------------------------------------------------------------------------------- /src/raw.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "packet_private.h" 37 | #include "ip4.h" 38 | #include "ip6.h" 39 | 40 | #define DLT_RAW_IP6 6 41 | #define DLT_RAW_IP4 4 42 | 43 | static inline int 44 | bind_dlt_raw(int proto, const unsigned char *pkt, unsigned len, 45 | Packet *packet) 46 | { 47 | int ret = -1; 48 | 49 | switch (proto) { 50 | case DLT_RAW_IP4: 51 | ret = decode_ip(pkt, len, packet); 52 | break; 53 | 54 | case DLT_RAW_IP6: 55 | ret = decode_ip6(pkt, len, packet); 56 | break; 57 | } 58 | 59 | return ret; 60 | } 61 | 62 | int 63 | decode_dlt_raw(const unsigned char *pkt, unsigned len, Packet *packet) 64 | { 65 | uint8_t proto = (*((uint8_t *)pkt) & 0xf0) >> 4; 66 | return bind_dlt_raw(proto, pkt, len, packet); 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/raw.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_RAW_H 31 | #define DECODE_RAW_H 32 | 33 | #define DLT_RAW 12 34 | int decode_dlt_raw(const unsigned char *pkt, unsigned len, Packet *packet); 35 | 36 | #endif /* DECODE_RAW_H */ 37 | -------------------------------------------------------------------------------- /src/sctp.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | /* XXX 31 | * 6/28/12 - SCTP support needs substantial work done to make it robust. 32 | */ 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #include "packet_private.h" 41 | 42 | #include "crc32.h" 43 | 44 | struct sctp { 45 | uint16_t sport; 46 | uint16_t dport; 47 | uint32_t vtag; 48 | uint32_t sum; 49 | }; 50 | 51 | struct sctp_chunk { 52 | uint8_t type; 53 | uint8_t flags; 54 | uint16_t len; 55 | }; 56 | 57 | extern struct packet_stats s_stats; 58 | 59 | static uint32_t 60 | crc32c(void *_buffer, unsigned len) 61 | { 62 | uint8_t *buffer = (uint8_t *)_buffer; 63 | 64 | uint32_t crc32 = ~0L; 65 | uint32_t result; 66 | uint8_t byte0, byte1, byte2, byte3; 67 | 68 | for (unsigned i = 0; i < len; i++) 69 | CRC32C(crc32, buffer[i]); 70 | 71 | result = ~crc32; 72 | 73 | byte0 = result & 0xff; 74 | byte1 = (result >> 8) & 0xff; 75 | byte2 = (result >> 16) & 0xff; 76 | byte3 = (result >> 24) & 0xff; 77 | 78 | crc32 = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); 79 | return crc32; 80 | } 81 | 82 | int 83 | decode_sctp(const uint8_t *pkt, const uint32_t len, Packet *p) 84 | { 85 | struct sctp *sctp = (struct sctp *)pkt; 86 | 87 | s_stats.sctps_packets++; 88 | s_stats.sctps_bytes += len; 89 | 90 | if (len < sizeof *sctp) 91 | { 92 | s_stats.sctps_tooshort++; 93 | return -1; 94 | } 95 | 96 | p->srcport = ntohs(sctp->sport); 97 | p->dstport = ntohs(sctp->dport); 98 | 99 | p->payload += sizeof *sctp; 100 | p->paysize -= sizeof *sctp; 101 | 102 | packet_layer_ins(p, pkt, sizeof *sctp, PROTO_SCTP); 103 | p->transport = packet_layer_current(p); 104 | 105 | uint32_t cks = ntohl(sctp->sum); 106 | sctp->sum = 0; 107 | 108 | //if (crc32c(sctp, len) != cks) 109 | //{ 110 | // s_stats.sctps_badsum++; 111 | //} 112 | 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /src/sctp.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_SCTP_H 31 | #define DECODE_SCTP_H 32 | 33 | int decode_sctp(const uint8_t *pkt, const uint32_t len, Packet *p); 34 | 35 | #endif /* DECODE_SCTP_H */ 36 | -------------------------------------------------------------------------------- /src/spx.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | 33 | #include "packet_private.h" 34 | 35 | /* spx structure as seen in FreeBSD's netipx/spx.h */ 36 | struct spx 37 | { 38 | uint8_t spx_cc; 39 | uint8_t spx_dt; 40 | #define SPX_SP 0x80 41 | #define SPX_SA 0x40 42 | #define SPX_OB 0x20 43 | #define SPX_EM 0x10 44 | uint16_t spx_sid; 45 | uint16_t spx_did; 46 | uint16_t spx_seq; 47 | uint16_t spx_ack; 48 | uint16_t spx_alo; 49 | }; 50 | 51 | int 52 | decode_spx(Packet *p, const uint8_t * pkt, const uint32_t len) 53 | { 54 | struct spx *spx = (struct spx *) pkt; 55 | 56 | if (len < sizeof *spx) 57 | { 58 | return -1; 59 | } 60 | 61 | packet_layer_ins(p, pkt, sizeof *spx, PROTO_SPX); 62 | 63 | p->payload += sizeof *spx; 64 | p->paysize -= sizeof *spx; 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /src/spx.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_SPX_H 31 | #define DECODE_SPX_H 32 | 33 | int decode_spx(Packet *p, const uint8_t *pkt, const uint32_t len); 34 | 35 | #endif /* DECODE_SPX_H */ 36 | -------------------------------------------------------------------------------- /src/tcp.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include 31 | #include 32 | #include 33 | 34 | #ifndef __USE_MISC 35 | #define __USE_MISC 36 | #endif 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include "packet_private.h" 43 | 44 | #include "checksum.h" 45 | 46 | extern struct packet_stats s_stats; 47 | 48 | /* Table that maps ordinal (option type) to option length. 49 | * Refer to link for more information. 50 | * http://www.iana.org/assignments/tcp-parameters/tcp-parameters.xml 51 | * 52 | * Note that we only bother ourselves with the first 8 option types. 53 | * In the future, I may build a full table 0-254. 54 | * 55 | * NOTE: See below, I only really care about Window Scale and MSS. 56 | * 57 | * 0 - No length (EOL, NOP) 58 | * >0 - Fixed length 59 | * -1 - Variable length 60 | */ 61 | static const int8_t tcpopt_len_tbl[] = 62 | { 63 | 0, 0, 4, 3, 2, -1, 6, 6, 10 64 | }; 65 | 66 | 67 | #define TCPOPT_MAX (sizeof(tcpopt_len_tbl)/sizeof(tcpopt_len_tbl[0])) 68 | 69 | /* Some sort of state machine for parsing tcp options. */ 70 | /* This was allot harder than it should have been. */ 71 | static inline void 72 | _decode_tcp_options(Packet *p, const uint8_t *start, const unsigned len) 73 | { 74 | if (len > MAX_TCPOPTLEN) 75 | return; 76 | 77 | const uint8_t *opt_start = start; 78 | unsigned depth = 0; 79 | 80 | while (opt_start < start + len) 81 | { 82 | uint8_t jmp_len, opt_len; 83 | 84 | /* Useless option code detected */ 85 | if (*opt_start >= TCPOPT_MAX) 86 | { 87 | if (!((len-depth) > 0)) 88 | return; 89 | 90 | jmp_len = *(opt_start + 1); 91 | 92 | /* skip processing and retrieve next option, abort otherwise */ 93 | if (len < jmp_len) 94 | goto nxt_tcp_opt; 95 | else 96 | return; 97 | } 98 | 99 | int8_t expected = tcpopt_len_tbl[*opt_start]; 100 | 101 | switch (expected) 102 | { 103 | /* Variable length option */ 104 | case -1: 105 | if (!((len-depth) > 0)) return; 106 | jmp_len = *(opt_start + 1); 107 | opt_len = jmp_len - 2; 108 | break; 109 | 110 | /* EOL or NOP */ 111 | case 0: 112 | jmp_len = 1; 113 | opt_len = expected; 114 | break; 115 | 116 | /* Fixed size */ 117 | default: 118 | if (!((len-depth) > 0)) return; 119 | jmp_len = *(opt_start + 1); 120 | 121 | /* Validate it is the correct length */ 122 | if (jmp_len != expected) return; 123 | opt_len = jmp_len - 2; 124 | break; 125 | } 126 | 127 | /* Add this option to the tcp opts array */ 128 | p->tcp_option[p->tcpopt_count].type = *opt_start; 129 | p->tcp_option[p->tcpopt_count].len = opt_len; 130 | p->tcp_option[p->tcpopt_count].value = opt_len ? (opt_start + 2): NULL; 131 | p->tcpopt_count++; 132 | 133 | nxt_tcp_opt: 134 | depth += jmp_len; 135 | opt_start += jmp_len; 136 | } 137 | 138 | return; 139 | } 140 | 141 | #ifndef TCPOPT_MAXSEG 142 | #define TCPOPT_MAXSEG 2 143 | #endif 144 | 145 | #ifndef TCPOPT_MAXSEG 146 | #define TCPOPT_WINDOW 3 147 | #endif 148 | 149 | static inline void 150 | decode_tcp_options(Packet *p, const uint8_t *start, const unsigned len) 151 | { 152 | // Let the state machine build and populate the TCP options table. 153 | _decode_tcp_options(p, start, len); 154 | 155 | // Post-processing and assignment to the Packet struct. 156 | for (size_t i = 0; i < p->tcpopt_count; i++) 157 | { 158 | Option *op = &p->tcp_option[i]; 159 | switch (op->type) 160 | { 161 | case TCPOPT_WINDOW: 162 | p->wscale = *(uint32_t*)op->value; 163 | break; 164 | 165 | case TCPOPT_MAXSEG: 166 | p->mss = *(uint16_t*)op->value; 167 | break; 168 | } 169 | } 170 | } 171 | 172 | int 173 | decode_tcp(const uint8_t *pkt, const uint32_t len, Packet *p) 174 | { 175 | struct tcphdr *tcp = (struct tcphdr *)pkt; 176 | 177 | s_stats.tcps_packets++; 178 | s_stats.tcps_bytes += len; 179 | 180 | if (len < sizeof *tcp) 181 | { 182 | s_stats.tcps_tooshort++; 183 | return -1; 184 | } 185 | 186 | unsigned hlen = tcp->th_off * 4; 187 | if (len < hlen) 188 | { 189 | s_stats.tcps_tooshort++; 190 | return -1; 191 | } 192 | 193 | packet_layer_ins(p, pkt, hlen, PROTO_TCP); 194 | p->transport = packet_layer_current(p); 195 | 196 | p->srcport = ntohs(tcp->th_sport); 197 | p->dstport = ntohs(tcp->th_dport); 198 | 199 | /* Create the pseudo header before adjusting paysize */ 200 | struct pseudo_hdr pseudo; 201 | pseudo.srcaddr = p->srcaddr; 202 | pseudo.dstaddr = p->dstaddr; 203 | pseudo.zero = 0; 204 | pseudo.protocol = p->protocol; 205 | pseudo.len = htons(p->paysize); 206 | 207 | p->payload += hlen; 208 | p->paysize -= hlen; 209 | 210 | /* decode tcp options */ 211 | unsigned short optlen = hlen - sizeof *tcp; 212 | if (optlen) 213 | { 214 | decode_tcp_options(p, pkt + hlen - optlen, optlen); 215 | } 216 | 217 | /* Lastly check the checksum */ 218 | if (checksum((uint16_t *)tcp, &pseudo, ntohs(pseudo.len)) != 0) 219 | { 220 | s_stats.tcps_badsum++; 221 | } 222 | 223 | return 0; 224 | } 225 | -------------------------------------------------------------------------------- /src/tcp.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_TCP_H 31 | #define DECODE_TCP_H 32 | 33 | int decode_tcp(const uint8_t *pkt, const uint32_t len, Packet *p); 34 | 35 | #endif /* DECODE_TCP_H */ 36 | -------------------------------------------------------------------------------- /src/udp.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | #define __FAVOR_BSD 38 | #include 39 | 40 | #include "packet_private.h" 41 | 42 | #include "checksum.h" 43 | 44 | extern struct packet_stats s_stats; 45 | 46 | int 47 | decode_udp(const uint8_t *pkt, const uint32_t len, Packet *p) 48 | { 49 | struct udphdr *udp = (struct udphdr *)pkt; 50 | 51 | s_stats.udps_packets++; 52 | s_stats.udps_bytes+=len; 53 | 54 | if (len < sizeof *udp) 55 | { 56 | s_stats.udps_tooshort++; 57 | return -1; 58 | } 59 | 60 | packet_layer_ins(p, pkt, sizeof *udp, PROTO_UDP); 61 | p->transport = packet_layer_current(p); 62 | 63 | p->srcport = ntohs(udp->uh_sport); 64 | p->dstport = ntohs(udp->uh_dport); 65 | 66 | /* Create the pseudo header before adjusting paysize */ 67 | struct pseudo_hdr pseudo; 68 | pseudo.srcaddr = p->srcaddr; 69 | pseudo.dstaddr = p->dstaddr; 70 | pseudo.zero = 0; 71 | pseudo.protocol = p->protocol; 72 | pseudo.len = htons(p->paysize); 73 | 74 | p->payload += sizeof *udp; 75 | p->paysize -= sizeof *udp; 76 | 77 | /* UDP checksum is mandatory for ipv6 */ 78 | if (udp->uh_sum == 0 && p->version == 6) 79 | { 80 | s_stats.udps_badsum++; 81 | //return -1; 82 | } 83 | else if (udp->uh_sum == 0) 84 | { 85 | return 0; 86 | } 87 | 88 | if (checksum((uint16_t *)udp, &pseudo, ntohs(pseudo.len)) != 0) 89 | { 90 | s_stats.udps_badsum++; 91 | } 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /src/udp.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_UDP_H 31 | #define DECODE_UDP_H 32 | 33 | int decode_udp(const uint8_t *pkt, const uint32_t len, Packet *p); 34 | 35 | #endif /* DECODE_UDP_H */ 36 | -------------------------------------------------------------------------------- /src/vlan.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include 31 | 32 | #include "packet_private.h" 33 | #include "eth.h" 34 | 35 | struct vlan 36 | { 37 | int vlan_id:12; 38 | int vlan_cfi:1; 39 | int vlan_pri:3; 40 | uint16_t vlan_type; 41 | }; 42 | 43 | int 44 | decode_vlan(Packet *packet, const uint8_t *pkt, unsigned len) 45 | { 46 | struct vlan *vlan = (struct vlan *)pkt; 47 | 48 | if (len < sizeof *vlan) 49 | return -1; 50 | 51 | packet->payload += sizeof *vlan; 52 | packet->paysize -= sizeof *vlan; 53 | 54 | packet_layer_ins(packet, pkt, sizeof *vlan, PROTO_VLAN); 55 | 56 | /* same protocols */ 57 | return bind_eth(ntohs(vlan->vlan_type), pkt + sizeof(*vlan), 58 | len - sizeof(*vlan), packet); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/vlan.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2012, Victor J. Roemer. All Rights Reserved. 2 | * 3 | * Redistribution and use in source and binary forms, with or without 4 | * modification, are permitted provided that the following conditions 5 | * are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * 3. The name of the author may not be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef DECODE_VLAN_H 31 | #define DECODE_VLAN_H 32 | 33 | int decode_vlan(Packet *packet, const uint8_t *pkt, unsigned len); 34 | 35 | #endif /* DECODE_VLAN_H */ 36 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | project(libpacket_tests) 3 | 4 | # Locate and include Google Test 5 | find_package(GTest REQUIRED) 6 | include(GoogleTest) 7 | 8 | # Create an executable for the tests 9 | add_executable(check_packet_accessors check_packet_accessors.cpp) 10 | target_link_libraries(check_packet_accessors PRIVATE GTest::GTest GTest::Main packet) 11 | gtest_discover_tests(check_packet_accessors) 12 | 13 | # Create an executable for the tests 14 | add_executable(check_packet_alt_payload check_packet_alt_payload.cpp) 15 | target_link_libraries(check_packet_alt_payload PRIVATE GTest::GTest GTest::Main packet) 16 | gtest_discover_tests(check_packet_alt_payload) 17 | 18 | 19 | # Create an executable for the tests 20 | add_executable(check_packet_create check_packet_create.cpp) 21 | target_link_libraries(check_packet_create PRIVATE GTest::GTest GTest::Main packet) 22 | gtest_discover_tests(check_packet_create) 23 | 24 | # Create an executable for the tests 25 | add_executable(check_packet_decode check_packet_decode.cpp) 26 | target_link_libraries(check_packet_decode PRIVATE GTest::GTest GTest::Main packet) 27 | gtest_discover_tests(check_packet_decode) 28 | 29 | # Set the working directory for the tests 30 | set_target_properties( 31 | check_packet_accessors 32 | check_packet_alt_payload 33 | check_packet_create 34 | check_packet_decode 35 | PROPERTIES 36 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" 37 | ) 38 | 39 | # Optionally, you can enable CTest integration to run the tests with 'make test' 40 | enable_testing() 41 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test build clean 2 | 3 | test: build 4 | make -C build test 5 | 6 | build: 7 | cmake -B build . 8 | cmake --build build 9 | 10 | clean: 11 | rm -rf build/ 12 | -------------------------------------------------------------------------------- /tests/check_packet_accessors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | const uint8_t pkt10[] = { 7 | 0x02, 0x09, 0x08, 0x07, 0x06, 0x05, 0x02, 0x01, 0x02, 0x03, 8 | 0x04, 0x05, 0x88, 0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0xC0, 9 | 0x00, 0x21, 0x45, 0x00, 0x00, 0xBE, 0x00, 0x06, 0x00, 0x00, 10 | 0x40, 0x06, 0x5C, 0x21, 0x0A, 0x01, 0x02, 0x03, 0x0A, 0x09, 11 | 0x08, 0x07, 0xBD, 0xEC, 0x00, 0x08, 0x00, 0x00, 0x01, 0xC4, 12 | 0x00, 0x00, 0x00, 0x02, 0x50, 0x18, 0x01, 0x00, 0xC8, 0xB2, 13 | 0x00, 0x00, 0x6C, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x64, 0x69, 14 | 0x64, 0x20, 0x64, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 15 | 0x65, 0x61, 0x64, 0x65, 0x72, 0x2E, 0x0A, 0x47, 0x4F, 0x52, 16 | 0x45, 0x3A, 0x20, 0x54, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 17 | 0x64, 0x65, 0x72, 0x3F, 0x0A, 0x42, 0x49, 0x44, 0x45, 0x4E, 18 | 0x3A, 0x20, 0x41, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 19 | 0x74, 0x72, 0x61, 0x69, 0x6C, 0x65, 0x72, 0x20, 0x2D, 0x2D, 20 | 0x20, 0x62, 0x75, 0x74, 0x20, 0x73, 0x68, 0x65, 0x20, 0x69, 21 | 0x73, 0x20, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 22 | 0x21, 0x0A, 0x43, 0x52, 0x4F, 0x57, 0x44, 0x3A, 0x20, 0x52, 23 | 0x6F, 0x75, 0x74, 0x65, 0x20, 0x68, 0x65, 0x72, 0x21, 0x20, 24 | 0x20, 0x50, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x21, 0x20, 0x20, 25 | 0x50, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x21, 0x20, 0x20, 0x52, 26 | 0x6F, 0x75, 0x74, 0x65, 0x20, 0x68, 0x65, 0x72, 0x21, 0x0A, 27 | 0x47, 0x4F, 0x52, 0x45, 0x3A, 0x20, 0x44, 0x69, 0x64, 0x20, 28 | 0x79, 0x6F 29 | }; 30 | 31 | void teardown() 32 | { 33 | } 34 | 35 | TEST(PacketAccessorsTest, PacketVersion) 36 | { 37 | Packet * packet = packet_create(); 38 | packet_decode(packet, pkt10, sizeof(pkt10)); 39 | 40 | ASSERT_EQ(packet_version(packet), 4) << "bad IP version"; 41 | 42 | packet_destroy(packet); 43 | } 44 | 45 | TEST(PacketAccessorsTest, PacketSrcAddr) 46 | { 47 | Packet * packet = packet_create(); 48 | packet_decode(packet, pkt10, sizeof(pkt10)); 49 | 50 | char srcaddr[INET_ADDRSTRLEN]; 51 | struct ipaddr saddr = packet_srcaddr(packet); 52 | inet_ntop(AF_INET, &saddr, srcaddr, INET_ADDRSTRLEN); 53 | ASSERT_STREQ(srcaddr, "10.1.2.3") << "bad source address"; 54 | 55 | packet_destroy(packet); 56 | } 57 | 58 | TEST(PacketAccessorsTest, PacketDstAddr) 59 | { 60 | Packet * packet = packet_create(); 61 | packet_decode(packet, pkt10, sizeof(pkt10)); 62 | 63 | char dstaddr[INET_ADDRSTRLEN]; 64 | struct ipaddr daddr = packet_dstaddr(packet); 65 | inet_ntop(AF_INET, &daddr, dstaddr, INET_ADDRSTRLEN); 66 | ASSERT_STREQ(dstaddr, "10.9.8.7") << "bad destination address"; 67 | 68 | packet_destroy(packet); 69 | } 70 | 71 | TEST(PacketAccessorsTest, PacketIsFragment) 72 | { 73 | Packet * packet = packet_create(); 74 | packet_decode(packet, pkt10, sizeof(pkt10)); 75 | 76 | // Just MF 77 | packet->mf = true; 78 | ASSERT_TRUE(packet_is_fragment(packet)) << "packet_is_fragment returned false"; 79 | 80 | packet->mf = false; 81 | ASSERT_FALSE(packet_is_fragment(packet)) << "packet_is_fragment returned true"; 82 | 83 | // Just OFF 84 | packet->offset = 8 * 2; 85 | ASSERT_TRUE(packet_is_fragment(packet)) << "packet_is_fragment returned false"; 86 | 87 | packet->offset = 0; 88 | ASSERT_FALSE(packet_is_fragment(packet)) << "packet_is_fragment returned true"; 89 | 90 | // Both 91 | packet->offset = 8 * 2; 92 | packet->mf = true; 93 | ASSERT_TRUE(packet_is_fragment(packet)) << "packet_is_fragment returned false"; 94 | 95 | packet->offset = 0; 96 | packet->mf = false; 97 | ASSERT_FALSE(packet_is_fragment(packet)) << "packet_is_fragment returned true"; 98 | 99 | packet_destroy(packet); 100 | } 101 | 102 | TEST(PacketAccessorsTest, PacketFragMf) 103 | { 104 | Packet * packet = packet_create(); 105 | packet_decode(packet, pkt10, sizeof(pkt10)); 106 | 107 | packet->mf = true; 108 | ASSERT_TRUE(packet_frag_mf(packet)) << "packet_frag_mf returned false"; 109 | 110 | packet->mf = false; 111 | ASSERT_FALSE(packet_frag_mf(packet)) << "packet_frag_mf returned true"; 112 | 113 | packet_destroy(packet); 114 | } 115 | 116 | TEST(PacketAccessorsTest, PacketFragDf) 117 | { 118 | Packet * packet = packet_create(); 119 | packet_decode(packet, pkt10, sizeof(pkt10)); 120 | 121 | packet->df = true; 122 | ASSERT_TRUE(packet_frag_df(packet)) << "packet_frag_df returned false"; 123 | 124 | packet->df = false; 125 | ASSERT_FALSE(packet_frag_df(packet)) << "packet_frag_df returned true"; 126 | 127 | packet_destroy(packet); 128 | } 129 | 130 | TEST(PacketAccessorsTest, PacketFragOffset) 131 | { 132 | Packet * packet = packet_create(); 133 | packet_decode(packet, pkt10, sizeof(pkt10)); 134 | 135 | packet->offset = 8 * 2; 136 | ASSERT_TRUE(packet_is_fragment(packet)) << "packet_is_fragment returned false"; 137 | 138 | packet->offset = 0; 139 | ASSERT_FALSE(packet_is_fragment(packet)) << "packet_is_fragment returned true"; 140 | 141 | packet_destroy(packet); 142 | } 143 | 144 | TEST(PacketAccessorsTest, PacketProtocol) 145 | { 146 | Packet * packet = packet_create(); 147 | packet_decode(packet, pkt10, sizeof(pkt10)); 148 | 149 | ASSERT_EQ(packet_protocol(packet), IPPROTO_TCP) << "packet_proto did not return TCP"; 150 | 151 | packet_destroy(packet); 152 | } 153 | 154 | TEST(PacketAccessorsTest, PacketId) 155 | { 156 | Packet * packet = packet_create(); 157 | packet_decode(packet, pkt10, sizeof(pkt10)); 158 | 159 | ASSERT_EQ(packet_id(packet), 1536) << "packet_id did not return 1536"; 160 | 161 | packet_destroy(packet); 162 | } 163 | 164 | TEST(PacketAccessorsTest, PacketTtl) 165 | { 166 | Packet * packet = packet_create(); 167 | packet_decode(packet, pkt10, sizeof(pkt10)); 168 | 169 | 170 | ASSERT_EQ(packet_ttl(packet), 64) << "packet_ttl did not return 64"; 171 | 172 | packet_destroy(packet); 173 | } 174 | 175 | TEST(PacketAccessorsTest, PacketTos) 176 | { 177 | Packet * packet = packet_create(); 178 | packet_decode(packet, pkt10, sizeof(pkt10)); 179 | 180 | 181 | ASSERT_EQ(packet_tos(packet), 0) << "packet_tos did not return 0"; 182 | } 183 | 184 | TEST(PacketAccessorsTest, PacketSrcPort) 185 | { 186 | Packet * packet = packet_create(); 187 | packet_decode(packet, pkt10, sizeof(pkt10)); 188 | 189 | 190 | ASSERT_EQ(packet_srcport(packet), 48620) << "packet_srcport did not return 48620"; 191 | 192 | packet_destroy(packet); 193 | } 194 | 195 | TEST(PacketAccessorsTest, PacketDstPort) 196 | { 197 | Packet * packet = packet_create(); 198 | packet_decode(packet, pkt10, sizeof(pkt10)); 199 | 200 | 201 | ASSERT_EQ(packet_dstport(packet), 8) << "packet_dstport did not return 8"; 202 | 203 | packet_destroy(packet); 204 | } 205 | 206 | TEST(PacketAccessorsTest, PacketMss) 207 | { 208 | // XXX We don't populate this yet 209 | } 210 | 211 | TEST(PacketAccessorsTest, PacketWin) 212 | { 213 | // implementation 214 | } 215 | 216 | TEST(PacketAccessorsTest, PacketWinscale) 217 | { 218 | // XXX We don't populate this yet 219 | } 220 | 221 | TEST(PacketAccessorsTest, PacketSeq) 222 | { 223 | Packet * packet = packet_create(); 224 | packet_decode(packet, pkt10, sizeof(pkt10)); 225 | 226 | 227 | ASSERT_EQ(packet_seq(packet), 452) << "packet_seq did not return 452"; 228 | } 229 | 230 | TEST(PacketAccessorsTest, PacketAck) 231 | { 232 | Packet * packet = packet_create(); 233 | packet_decode(packet, pkt10, sizeof(pkt10)); 234 | 235 | 236 | ASSERT_EQ(packet_ack(packet), 2) << "packet_ack did not return 2"; 237 | 238 | packet_destroy(packet); 239 | } 240 | 241 | TEST(PacketAccessorsTest, PacketTcpFin) 242 | { 243 | Packet * packet = packet_create(); 244 | packet_decode(packet, pkt10, sizeof(pkt10)); 245 | 246 | 247 | ASSERT_FALSE(packet_tcp_fin(packet)) << "packet_tcp_fin returned true"; 248 | 249 | packet_destroy(packet); 250 | } 251 | 252 | TEST(PacketAccessorsTest, PacketTcpSyn) 253 | { 254 | Packet * packet = packet_create(); 255 | packet_decode(packet, pkt10, sizeof(pkt10)); 256 | 257 | 258 | ASSERT_FALSE(packet_tcp_syn(packet)) << "packet_tcp_syn returned true"; 259 | 260 | packet_destroy(packet); 261 | } 262 | 263 | TEST(PacketAccessorsTest, PacketTcpRst) 264 | { 265 | Packet * packet = packet_create(); 266 | packet_decode(packet, pkt10, sizeof(pkt10)); 267 | 268 | 269 | ASSERT_FALSE(packet_tcp_rst(packet)) << "packet_tcp_rst returned true"; 270 | 271 | packet_destroy(packet); 272 | } 273 | 274 | TEST(PacketAccessorsTest, PacketTcpPush) 275 | { 276 | Packet * packet = packet_create(); 277 | packet_decode(packet, pkt10, sizeof(pkt10)); 278 | 279 | 280 | ASSERT_TRUE(packet_tcp_push(packet)) << "packet_tcp_push returned false"; 281 | 282 | packet_destroy(packet); 283 | } 284 | 285 | TEST(PacketAccessorsTest, PacketTcpAck) 286 | { 287 | Packet * packet = packet_create(); 288 | packet_decode(packet, pkt10, sizeof(pkt10)); 289 | 290 | 291 | ASSERT_TRUE(packet_tcp_ack(packet)) << "packet_tcp_push returned false"; 292 | 293 | packet_destroy(packet); 294 | } 295 | 296 | TEST(PacketAccessorsTest, PacketTcpUrg) 297 | { 298 | Packet * packet = packet_create(); 299 | packet_decode(packet, pkt10, sizeof(pkt10)); 300 | 301 | 302 | ASSERT_FALSE(packet_tcp_urg(packet)) << "packet_tcp_urg returned true"; 303 | 304 | packet_destroy(packet); 305 | } 306 | 307 | TEST(PacketAccessorsTest, PacketPayload) 308 | { 309 | Packet * packet = packet_create(); 310 | packet_decode(packet, pkt10, sizeof(pkt10)); 311 | 312 | 313 | ASSERT_TRUE(packet_payload(packet) != NULL) << "packet_payload returned NULL"; 314 | 315 | packet_destroy(packet); 316 | } 317 | 318 | TEST(PacketAccessorsTest, PacketPaySize) 319 | { 320 | Packet * packet = packet_create(); 321 | packet_decode(packet, pkt10, sizeof(pkt10)); 322 | 323 | ASSERT_TRUE(packet_paysize(packet)) << "packet_paysize returned 0"; 324 | 325 | packet_destroy(packet); 326 | } 327 | 328 | int main(int argc, char** argv) 329 | { 330 | testing::InitGoogleTest(&argc, argv); 331 | return RUN_ALL_TESTS(); 332 | } 333 | -------------------------------------------------------------------------------- /tests/check_packet_alt_payload.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | const uint8_t pkt10[] = { 8 | 0x02, 0x09, 0x08, 0x07, 0x06, 0x05, 0x02, 0x01, 0x02, 0x03, 9 | 0x04, 0x05, 0x88, 0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0xC0, 10 | 0x00, 0x21, 0x45, 0x00, 0x00, 0xBE, 0x00, 0x06, 0x00, 0x00, 11 | 0x40, 0x06, 0x5C, 0x21, 0x0A, 0x01, 0x02, 0x03, 0x0A, 0x09, 12 | 0x08, 0x07, 0xBD, 0xEC, 0x00, 0x08, 0x00, 0x00, 0x01, 0xC4, 13 | 0x00, 0x00, 0x00, 0x02, 0x50, 0x18, 0x01, 0x00, 0xC8, 0xB2, 14 | 0x00, 0x00, 0x6C, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x64, 0x69, 15 | 0x64, 0x20, 0x64, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 16 | 0x65, 0x61, 0x64, 0x65, 0x72, 0x2E, 0x0A, 0x47, 0x4F, 0x52, 17 | 0x45, 0x3A, 0x20, 0x54, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 18 | 0x64, 0x65, 0x72, 0x3F, 0x0A, 0x42, 0x49, 0x44, 0x45, 0x4E, 19 | 0x3A, 0x20, 0x41, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 20 | 0x74, 0x72, 0x61, 0x69, 0x6C, 0x65, 0x72, 0x20, 0x2D, 0x2D, 21 | 0x20, 0x62, 0x75, 0x74, 0x20, 0x73, 0x68, 0x65, 0x20, 0x69, 22 | 0x73, 0x20, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 23 | 0x21, 0x0A, 0x43, 0x52, 0x4F, 0x57, 0x44, 0x3A, 0x20, 0x52, 24 | 0x6F, 0x75, 0x74, 0x65, 0x20, 0x68, 0x65, 0x72, 0x21, 0x20, 25 | 0x20, 0x50, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x21, 0x20, 0x20, 26 | 0x50, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x21, 0x20, 0x20, 0x52, 27 | 0x6F, 0x75, 0x74, 0x65, 0x20, 0x68, 0x65, 0x72, 0x21, 0x0A, 28 | 0x47, 0x4F, 0x52, 0x45, 0x3A, 0x20, 0x44, 0x69, 0x64, 0x20, 29 | 0x79, 0x6F 30 | }; 31 | 32 | const char* alt_payload = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 33 | 34 | TEST(PacketAltPayloadTest, AlternatePayloadSize) 35 | { 36 | Packet* packet = packet_create(); 37 | packet_decode(packet, pkt10, sizeof(pkt10)); 38 | packet_set_payload(packet, (uint8_t*)alt_payload, strlen(alt_payload)); 39 | 40 | int len1 = packet_paysize(packet); 41 | int len2 = strlen(alt_payload); 42 | ASSERT_EQ(len1, len2) << "Alternate payload size is wrong"; 43 | 44 | packet_set_payload(packet, NULL, 0); 45 | packet_destroy(packet); 46 | } 47 | 48 | TEST(PacketAltPayloadTest, AlternatePayload) 49 | { 50 | Packet* packet = packet_create(); 51 | packet_decode(packet, pkt10, sizeof(pkt10)); 52 | packet_set_payload(packet, (uint8_t*)alt_payload, strlen(alt_payload)); 53 | 54 | const uint8_t* pay = packet_payload(packet); 55 | int paysize = strlen((char*)pay); 56 | 57 | ASSERT_EQ(memcmp(pay, (const uint8_t*)alt_payload, paysize), 0) 58 | << "Alternate payload is wrong"; 59 | 60 | packet_set_payload(packet, NULL, 0); 61 | packet_destroy(packet); 62 | } 63 | 64 | TEST(PacketAltPayloadTest, HasAlternatePayload) 65 | { 66 | Packet* packet = packet_create(); 67 | packet_decode(packet, pkt10, sizeof(pkt10)); 68 | packet_set_payload(packet, (uint8_t*)alt_payload, strlen(alt_payload)); 69 | 70 | ASSERT_TRUE(packet_has_alt_payload(packet)) 71 | << "Packet claims to have no alternate payload"; 72 | 73 | packet_set_payload(packet, NULL, 0); 74 | packet_destroy(packet); 75 | } 76 | 77 | TEST(PacketAltPayloadTest, RawPayload) 78 | { 79 | Packet* packet = packet_create(); 80 | packet_decode(packet, pkt10, sizeof(pkt10)); 81 | packet_set_payload(packet, (uint8_t*)alt_payload, strlen(alt_payload)); 82 | 83 | const uint8_t* raw = packet_raw_payload(packet); 84 | const uint8_t* alt = packet_payload(packet); 85 | ASSERT_NE(raw, alt) << "Packet raw payload is incorrect"; 86 | 87 | packet_set_payload(packet, NULL, 0); 88 | packet_destroy(packet); 89 | } 90 | 91 | TEST(PacketAltPayloadTest, RawPayloadSize) 92 | { 93 | Packet* packet = packet_create(); 94 | packet_decode(packet, pkt10, sizeof(pkt10)); 95 | packet_set_payload(packet, (uint8_t*)alt_payload, strlen(alt_payload)); 96 | 97 | const uint32_t raw = packet_raw_paysize(packet); 98 | const uint32_t alt = packet_paysize(packet); 99 | ASSERT_NE(raw, alt) << "Packet raw payload size is incorrect"; 100 | 101 | packet_set_payload(packet, NULL, 0); 102 | packet_destroy(packet); 103 | } 104 | 105 | int main(int argc, char** argv) 106 | { 107 | testing::InitGoogleTest(&argc, argv); 108 | return RUN_ALL_TESTS(); 109 | } 110 | -------------------------------------------------------------------------------- /tests/check_packet_create.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | TEST(PacketCreateTest, PacketCreate) 5 | { 6 | Packet *packet = packet_create(); 7 | 8 | ASSERT_TRUE(packet != NULL); 9 | 10 | packet_destroy(packet); 11 | } 12 | 13 | int main(int argc, char** argv) 14 | { 15 | testing::InitGoogleTest(&argc, argv); 16 | return RUN_ALL_TESTS(); 17 | } 18 | -------------------------------------------------------------------------------- /tests/check_packet_decode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //#include 4 | 5 | /* eth:pppoe:ppp:ip4:tcp */ 6 | const uint8_t pkt10[] = { 7 | 0x02, 0x09, 0x08, 0x07, 0x06, 0x05, 0x02, 0x01, 0x02, 0x03, 8 | 0x04, 0x05, 0x88, 0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0xC0, 9 | 0x00, 0x21, 0x45, 0x00, 0x00, 0xBE, 0x00, 0x06, 0x00, 0x00, 10 | 0x40, 0x06, 0x5C, 0x21, 0x0A, 0x01, 0x02, 0x03, 0x0A, 0x09, 11 | 0x08, 0x07, 0xBD, 0xEC, 0x00, 0x08, 0x00, 0x00, 0x01, 0xC4, 12 | 0x00, 0x00, 0x00, 0x02, 0x50, 0x18, 0x01, 0x00, 0xC8, 0xB2, 13 | 0x00, 0x00, 0x6C, 0x2C, 0x20, 0x77, 0x65, 0x20, 0x64, 0x69, 14 | 0x64, 0x20, 0x64, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 15 | 0x65, 0x61, 0x64, 0x65, 0x72, 0x2E, 0x0A, 0x47, 0x4F, 0x52, 16 | 0x45, 0x3A, 0x20, 0x54, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 17 | 0x64, 0x65, 0x72, 0x3F, 0x0A, 0x42, 0x49, 0x44, 0x45, 0x4E, 18 | 0x3A, 0x20, 0x41, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 19 | 0x74, 0x72, 0x61, 0x69, 0x6C, 0x65, 0x72, 0x20, 0x2D, 0x2D, 20 | 0x20, 0x62, 0x75, 0x74, 0x20, 0x73, 0x68, 0x65, 0x20, 0x69, 21 | 0x73, 0x20, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 22 | 0x21, 0x0A, 0x43, 0x52, 0x4F, 0x57, 0x44, 0x3A, 0x20, 0x52, 23 | 0x6F, 0x75, 0x74, 0x65, 0x20, 0x68, 0x65, 0x72, 0x21, 0x20, 24 | 0x20, 0x50, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x21, 0x20, 0x20, 25 | 0x50, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x21, 0x20, 0x20, 0x52, 26 | 0x6F, 0x75, 0x74, 0x65, 0x20, 0x68, 0x65, 0x72, 0x21, 0x0A, 27 | 0x47, 0x4F, 0x52, 0x45, 0x3A, 0x20, 0x44, 0x69, 0x64, 0x20, 28 | 0x79, 0x6F 29 | }; 30 | 31 | TEST(PacketDecodeTest, WithNullPacket) 32 | { 33 | Packet *packet = packet_create(); 34 | 35 | int err = packet_decode(NULL, pkt10, sizeof(pkt10)); 36 | 37 | ASSERT_TRUE(packet != NULL); 38 | ASSERT_TRUE(err != 0); 39 | 40 | packet_destroy(packet); 41 | } 42 | 43 | TEST(PacketDecodeTest, WithNullDataPointer) 44 | { 45 | Packet *packet = packet_create(); 46 | 47 | int err = packet_decode(packet, NULL, sizeof(pkt10)); 48 | 49 | ASSERT_TRUE(err != 0); 50 | 51 | packet_destroy(packet); 52 | } 53 | 54 | TEST(PacketDecodeTest, WithZeroSize) 55 | { 56 | Packet *packet = packet_create(); 57 | 58 | int err = packet_decode(packet, pkt10, 0); 59 | 60 | ASSERT_TRUE(err != 0); 61 | 62 | packet_destroy(packet); 63 | } 64 | 65 | TEST(PacketDecodeTest, ProtoCount) 66 | { 67 | Packet *packet = packet_create(); 68 | 69 | int err = packet_decode(packet, pkt10, sizeof(pkt10)); 70 | 71 | ASSERT_TRUE(err == 0); 72 | 73 | err = packet_proto_count(packet); 74 | ASSERT_EQ(err, 5); 75 | 76 | unsigned i; 77 | Protocol *proto = packet_proto_first(packet, &i); 78 | ASSERT_EQ(packet_proto_proto(proto), PROTO_ETH); 79 | 80 | proto = packet_proto_next(packet, &i); 81 | ASSERT_EQ(packet_proto_proto(proto), PROTO_PPPOE); 82 | 83 | proto = packet_proto_next(packet, &i); 84 | ASSERT_EQ(packet_proto_proto(proto), PROTO_PPP); 85 | 86 | proto = packet_proto_next(packet, &i); 87 | ASSERT_EQ(packet_proto_proto(proto), PROTO_IP4); 88 | 89 | proto = packet_proto_next(packet, &i); 90 | ASSERT_EQ(packet_proto_proto(proto), PROTO_TCP); 91 | 92 | packet_destroy(packet); 93 | } 94 | 95 | int main(int argc, char** argv) 96 | { 97 | testing::InitGoogleTest(&argc, argv); 98 | return RUN_ALL_TESTS(); 99 | } 100 | -------------------------------------------------------------------------------- /tests/testme.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | int s_error = 0; 9 | 10 | #define PERLINE 10 11 | void print_cbuf(const uint8_t *data, int length) 12 | { 13 | int i, x, j, c; 14 | int w = 0; 15 | 16 | for( i=0; length>0; length -= PERLINE ) 17 | { 18 | c = length >= PERLINE ? PERLINE : length; 19 | 20 | printf(" "); 21 | for( j=0; jcaplen); 42 | printf("};\n"); 43 | #endif 44 | 45 | int error = packet_decode(packet, pkt, ph->caplen); 46 | 47 | if (error) 48 | { 49 | s_error = error; 50 | } 51 | 52 | /* not cute */ 53 | #if 0 54 | /* Print the packet layers */ 55 | unsigned it; 56 | Protocol *proto; 57 | 58 | for (proto = packet_proto_first(packet, &it); proto != NULL; 59 | proto = packet_proto_next(packet, &it)) 60 | { 61 | printf("%s:", packet_proto_name(proto)); 62 | } 63 | printf("\n"); 64 | #endif 65 | 66 | packet_destroy(packet); 67 | } 68 | 69 | int main(int argc, char *argv[]) 70 | { 71 | char errbuf[PCAP_ERRBUF_SIZE]; 72 | 73 | if (argc < 2) 74 | { 75 | fprintf(stderr, "Usage: testme \n\n"); 76 | return 1; 77 | } 78 | 79 | pcap_t *pcap = pcap_open_offline(argv[1], errbuf); 80 | 81 | if (!pcap) 82 | { 83 | fprintf(stderr, "%s\n", errbuf); 84 | return 2; 85 | } 86 | 87 | if (pcap_loop(pcap, -1, packet_callback, NULL) == -1) 88 | { 89 | fprintf(stderr, "%s\n", pcap_geterr(pcap)); 90 | s_error = 2; 91 | } 92 | 93 | const struct packet_stats *ps; 94 | packet_stats(&ps); 95 | 96 | printf("Processed %u packets\n", ps->total_packets); 97 | printf("Rejected %u packets\n", ps->total_errors); 98 | 99 | printf("Analyzed %u pppoe packets\n", ps->pppoes_packets); 100 | printf("Analyzed %u ppp packets\n", ps->ppps_packets); 101 | printf("Analyzed %u ip packets\n", ps->ips_packets); 102 | printf("Analyzed %u ip6 packets\n", ps->ip6s_packets); 103 | printf("Analyzed %u ipx packets\n", ps->ipxs_packets); 104 | printf("Analyzed %u tcp packets\n", ps->tcps_packets); 105 | printf("Analyzed %u udp packets\n", ps->udps_packets); 106 | printf("Analyzed %u sctp packets\n", ps->sctps_packets); 107 | 108 | printf("Bad ip checksum: %u\n", ps->ips_badsum); 109 | printf("Bad tcp checksum: %u\n", ps->tcps_badsum); 110 | printf("Bad udp checksum: %u\n", ps->udps_badsum); 111 | printf("Bad sctp checksum: %u\n", ps->sctps_badsum); 112 | 113 | pcap_close(pcap); 114 | 115 | return s_error; 116 | } 117 | --------------------------------------------------------------------------------