1 /*- 2 * Copyright (c) 2002, 2003, 2004 Lev Walkin <vlm@lionet.info>. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $Id: storage.h,v 1.11 2004/11/12 06:38:03 vlm Exp $ 27 */ 28 29 #ifndef __STORAGE_H__ 30 #define __STORAGE_H__ 31 32 #include "headers.h" 33 34 /* 35 * Structure describing the single flow. 36 */ 37 typedef struct flow_s { 38 /* 39 * Flow source and destination. 40 */ 41 struct in_addr src; /* Source IP address */ 42 struct in_addr dst; /* Destination IP address */ 43 44 /* Ports gathered when "capture-ports enable" is set */ 45 int src_port; /* Source IP port (-1 if not available) */ 46 int dst_port; /* Destination IP port (-1 if not available) */ 47 48 /* 49 * Flow counters. 50 */ 51 unsigned long long bytes; 52 size_t packets; 53 54 /* 55 * Things meaningful if NetFlow is enabled. 56 */ 57 void *ifSource; /* Packet source */ 58 u_char src_mask; /* Source IP prefix mask bits */ 59 u_char dst_mask; /* Destination IP prefix mask bits */ 60 u_char ip_p; /* IP Protocol */ 61 u_char ip_tos; /* IP TypeOfService */ 62 u_char tcp_flags; /* TCP flags */ 63 int ifInIndex; /* SNMP index of the input interface, 0-based */ 64 int ifOutIndex; /* SNMP index of the output interface */ 65 66 double seen_first; /* First packet in the flow */ 67 double seen_last; /* Last packet in the flow */ 68 69 char ifInName[IFNAMSIZ]; 70 char ifOutName[IFNAMSIZ]; 71 } flow_t; 72 #define FLOW_EMPTY_VALUE { {0}, {0}, -1, -1 } /* Used in static inits */ 73 74 /* 75 * Wrapper to include the flow into a hash. 76 */ 77 typedef struct flow_el_s { 78 79 flow_t flow; /* Flow itself */ 80 81 /* 82 * Hash value of the flow. 83 */ 84 int hash_value; 85 86 /* 87 * Place in the bucket. 88 */ 89 struct flow_el_s *bucket_prev; 90 struct flow_el_s *bucket_next; 91 92 /* 93 * Place in the global list. 94 */ 95 struct flow_el_s *hash_next; 96 } flow_el_t; 97 98 99 /* 100 * Hash of flows. 101 */ 102 typedef struct flow_storage_s { 103 flow_el_t **buckets; /* Hash buckets */ 104 flow_el_t *head; /* Linked list of elements */ 105 int numbuckets; /* Number of bytes allocated */ 106 int entries; /* Number of flow elements linked in */ 107 108 time_t create_time; /* Hash creation time */ 109 110 time_t first_miss; /* Time when problems started to happen */ 111 long long missed_packets; /* Number of lost packets */ 112 long long missed_bytes; /* Number of lost bytes */ 113 uint32_t missed_flows; /* Missed NetFlow flows */ 114 uint32_t flows_count; /* Number of NetFlow flows seen so far */ 115 116 pthread_mutex_t storage_lock; 117 } flow_storage_t; 118 119 /* 120 * Active, checkpoint and NetFlow storages (flow caches). 121 */ 122 extern flow_storage_t active_storage; 123 extern flow_storage_t checkpoint_storage; 124 extern flow_storage_t netflow_storage; 125 126 #define lock_storage(foo) pthread_mutex_lock(&(foo)->storage_lock) 127 #define unlock_storage(foo) pthread_mutex_unlock(&(foo)->storage_lock) 128 129 /* 130 * Atomically add flow counters into the list of flows. 131 * flow will NOT be consumed (yet may be modified): you may allocate it 132 * on the stack. The function may allocate new flow_el_t object or update 133 * existing one. 134 * If allocation fails, it will increase .missed_* counters in the storage 135 * and return -1. 136 */ 137 typedef enum { 138 AGG_NONE = 0x00, /* Do not aggregate */ 139 AGG_IPS = 0x01, /* Aggregate IP addresses */ 140 AGG_PORTS = 0x02, /* Aggregate Port numbers */ 141 AGG_ALL = 0x03, /* Aggregate everything */ 142 } agg_e; 143 int flow_update(flow_storage_t *storage, flow_t *flow, agg_e aggregate_flow); 144 145 146 /* 147 * Remove flows from the storage. 148 * Operation is atomic. 149 */ 150 void clear_storage(flow_storage_t *storage, int do_not_lock_storage); 151 152 /* 153 * Move main storage in place of checkpoint. 154 * Operation is atomic. 155 */ 156 void save_checkpoint(flow_storage_t *main, flow_storage_t *checkpoint); 157 158 /* 159 * Get a table with flows (array of flow_t). 160 * If return value is 0, r_flows and r_size will be initialized 161 * to point to a newly allocated table of flows. 162 * You must lock storage before calling this function! 163 */ 164 int get_flow_table(flow_storage_t *storage, flow_t **r_flows, int *r_size); 165 166 #endif /* __STORAGE_H__ */ 167