parent
661f8b7cb6
commit
418beef4bc
@ -9,37 +9,26 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=libiptbwctl
|
||||
PKG_VERSION:=$(GARGOYLE_VERSION)
|
||||
ifeq ($(GARGOYLE_VERSION),)
|
||||
PKG_VERSION:=1.0.0
|
||||
endif
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/libiptbwctl
|
||||
PKG_MAINTAINER:=Eric Bishop <eric@gargoyle-router.com>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/libiptbwctl
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=+iptables-mod-bandwidth
|
||||
TITLE:=IPT bandwidth control library
|
||||
URL:=http://www.gargoyle-router.com
|
||||
MAINTAINER:=Eric Bishop <eric@gargoyle-router.com>
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
SUBMENU:=Networking
|
||||
DEPENDS:=+iptables-mod-bandwidth
|
||||
TITLE:=IPT bandwidth control library
|
||||
URL:=http://www.gargoyle-router.com
|
||||
endef
|
||||
|
||||
|
||||
define Package/libiptbwctl/description
|
||||
IPT bandwidth control library
|
||||
endef
|
||||
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
@ -51,13 +40,13 @@ define Build/Compile
|
||||
CFLAGS="$(TARGET_CFLAGS) -I $(STAGING_DIR)/usr/include" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS) -L $(STAGING_DIR)/usr/lib" \
|
||||
all
|
||||
|
||||
|
||||
mkdir -p $(STAGING_DIR)/usr/include/
|
||||
$(CP) $(PKG_BUILD_DIR)/*.h $(STAGING_DIR)/usr/include/
|
||||
|
||||
mkdir -p $(STAGING_DIR)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/*.so* $(STAGING_DIR)/usr/lib/
|
||||
|
||||
|
||||
$(MAKE) -C $(PKG_BUILD_DIR)/utils \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
STAGING_DIR="$(STAGING_DIR)" \
|
||||
@ -66,11 +55,8 @@ define Build/Compile
|
||||
all
|
||||
endef
|
||||
|
||||
|
||||
|
||||
define Package/libiptbwctl/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_DIR) $(1)/usr/bin $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/*.so* $(1)/usr/lib/
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/utils/bw_get $(1)/usr/bin/bw_get
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/utils/bw_set $(1)/usr/bin/bw_set
|
||||
@ -78,6 +64,4 @@ define Package/libiptbwctl/install
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/utils/set_kernel_timezone $(1)/usr/bin/set_kernel_timezone
|
||||
endef
|
||||
|
||||
|
||||
$(eval $(call BuildPackage,libiptbwctl))
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
VERSION=1
|
||||
|
||||
|
||||
ifeq ($(CC),)
|
||||
CC=gcc
|
||||
endif
|
||||
@ -17,8 +16,6 @@ ifeq ($(RANLIB),)
|
||||
RANLIB=ranlib
|
||||
endif
|
||||
|
||||
|
||||
|
||||
OS=$(shell uname)
|
||||
ifeq ($(OS),Darwin)
|
||||
LINK=$(LD)
|
||||
@ -35,22 +32,18 @@ endif
|
||||
CFLAGS:=$(CFLAGS) -Os
|
||||
WARNING_FLAGS=-Wall -Wstrict-prototypes
|
||||
|
||||
|
||||
|
||||
all: libiptbwctl
|
||||
|
||||
libiptbwctl: libiptbwctl.$(SHLIB_EXT) libiptbwctl.a
|
||||
|
||||
|
||||
libiptbwctl.a: ipt_bwctl_static.o ipt_bwctl_safe_malloc_static.o
|
||||
if [ -e $@ ] ; then rm $@ ; fi
|
||||
$(AR) rc $@ $^
|
||||
$(RANLIB) $@
|
||||
|
||||
|
||||
libiptbwctl.$(SHLIB_EXT) : ipt_bwctl_dyn.o ipt_bwctl_safe_malloc_dyn.o
|
||||
if [ -e libiptbwctl.$(SHLIB_EXT) ] ; then rm libiptbwctl.$(SHLIB_EXT)* ; fi
|
||||
$(LINK) $(LDFLAGS) $(SHLIB_FLAGS) -o $(SHLIB_FILE) $^ -lc
|
||||
$(LINK) $(LDFLAGS) $(SHLIB_FLAGS) -o $(SHLIB_FILE) $^ -lc
|
||||
ln -s $(SHLIB_FILE) libiptbwctl.$(SHLIB_EXT)
|
||||
|
||||
%_dyn.o: %.c
|
||||
@ -59,9 +52,6 @@ libiptbwctl.$(SHLIB_EXT) : ipt_bwctl_dyn.o ipt_bwctl_safe_malloc_dyn.o
|
||||
%_static.o: %.c
|
||||
$(CC) $(CFLAGS) $(WARNING_FLAGS) -o $@ -c $^
|
||||
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
cd utils
|
||||
rm -rf bw_get bw_set *.a *.o *~ .*sw*
|
||||
|
||||
@ -18,25 +18,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "ipt_bwctl.h"
|
||||
#define malloc ipt_bwctl_safe_malloc
|
||||
#define strdup ipt_bwctl_safe_strdup
|
||||
|
||||
|
||||
static int bandwidth_semaphore = -1;
|
||||
|
||||
union semun
|
||||
union semun
|
||||
{
|
||||
int val; // Value for SETVAL
|
||||
struct semid_ds *buf; // Buffer for IPC_STAT, IPC_SET
|
||||
unsigned short *array; // Array for GETALL, SETALL
|
||||
struct seminfo *__buf; // Buffer for IPC_INFO (Linux specific)
|
||||
int val; // Value for SETVAL
|
||||
struct semid_ds *buf; // Buffer for IPC_STAT, IPC_SET
|
||||
unsigned short *array; // Array for GETALL, SETALL
|
||||
struct seminfo *__buf; // Buffer for IPC_INFO (Linux specific)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* semaphore functions */
|
||||
static int get_sem_val(int sid, int member);
|
||||
static int get_sem(int *sid, key_t key);
|
||||
@ -47,65 +42,63 @@ static int unlock(void);
|
||||
|
||||
|
||||
/* needed to calculate history time intervals */
|
||||
static time_t get_next_node_start_time( time_t current_start_time,
|
||||
time_t reset_interval,
|
||||
time_t reset_time,
|
||||
static time_t get_next_node_start_time( time_t current_start_time,
|
||||
time_t reset_interval,
|
||||
time_t reset_time,
|
||||
unsigned char is_constant_interval
|
||||
);
|
||||
|
||||
/* functions used to get data from kernel module */
|
||||
static void parse_returned_ip_data( void *out_data,
|
||||
uint32_t* out_index,
|
||||
unsigned char* in_buffer,
|
||||
uint32_t* in_index,
|
||||
unsigned char get_history,
|
||||
time_t reset_interval,
|
||||
time_t reset_time,
|
||||
static void parse_returned_ip_data( void *out_data,
|
||||
uint32_t* out_index,
|
||||
unsigned char* in_buffer,
|
||||
uint32_t* in_index,
|
||||
unsigned char get_history,
|
||||
time_t reset_interval,
|
||||
time_t reset_time,
|
||||
unsigned char is_constant_interval
|
||||
);
|
||||
|
||||
static int get_bandwidth_data( char* id,
|
||||
unsigned char get_history,
|
||||
char* ip,
|
||||
unsigned long* num_ips,
|
||||
void** data,
|
||||
static int get_bandwidth_data( char* id,
|
||||
unsigned char get_history,
|
||||
char* ip,
|
||||
unsigned long* num_ips,
|
||||
void** data,
|
||||
unsigned long max_wait_milliseconds
|
||||
);
|
||||
|
||||
|
||||
/* functions used to send/restore data to kernel module */
|
||||
static int set_ip_block( void* ip_block_data,
|
||||
unsigned char is_history,
|
||||
unsigned char* output_buffer,
|
||||
uint32_t* current_output_index,
|
||||
static int set_ip_block( void* ip_block_data,
|
||||
unsigned char is_history,
|
||||
unsigned char* output_buffer,
|
||||
uint32_t* current_output_index,
|
||||
uint32_t output_buffer_length
|
||||
);
|
||||
|
||||
static int set_bandwidth_data( char* id,
|
||||
unsigned char zero_unset,
|
||||
unsigned char set_history,
|
||||
unsigned long num_ips,
|
||||
time_t last_backup,
|
||||
void* data,
|
||||
static int set_bandwidth_data( char* id,
|
||||
unsigned char zero_unset,
|
||||
unsigned char set_history,
|
||||
unsigned long num_ips,
|
||||
time_t last_backup,
|
||||
void* data,
|
||||
unsigned long max_wait_milliseconds
|
||||
);
|
||||
|
||||
/* utility i/o functions when saving/restoring data to/from file */
|
||||
static unsigned char* read_entire_file( FILE* in,
|
||||
unsigned long read_block_size,
|
||||
static unsigned char* read_entire_file( FILE* in,
|
||||
unsigned long read_block_size,
|
||||
unsigned long *length
|
||||
);
|
||||
|
||||
static char** split_on_separators( char* line,
|
||||
char* separators,
|
||||
int num_separators,
|
||||
int max_pieces,
|
||||
int include_remainder_at_max,
|
||||
static char** split_on_separators( char* line,
|
||||
char* separators,
|
||||
int num_separators,
|
||||
int max_pieces,
|
||||
int include_remainder_at_max,
|
||||
unsigned long *pieces_read
|
||||
);
|
||||
|
||||
|
||||
|
||||
static int get_sem_val(int sid, int member)
|
||||
{
|
||||
int semval;
|
||||
@ -119,12 +112,12 @@ static int get_sem(int *sid, key_t key)
|
||||
union semun semopts;
|
||||
int members = 1;
|
||||
|
||||
|
||||
|
||||
int success = ((*sid = semget(key, members, IPC_CREAT|IPC_EXCL|0777))== -1) ? 0 : 1;
|
||||
if(success)
|
||||
{
|
||||
semopts.val = 1;
|
||||
/* Initialize all members (could be done with SETALL) */
|
||||
/* Initialize all members (could be done with SETALL) */
|
||||
for(cntr=0; cntr<members; cntr++)
|
||||
{
|
||||
semctl(*sid, cntr, SETVAL, semopts);
|
||||
@ -137,13 +130,12 @@ static int get_sem(int *sid, key_t key)
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
static int lock_sem(int sid)
|
||||
{
|
||||
int member = 0;
|
||||
struct sembuf sem_lock={ 0, -1, IPC_NOWAIT};
|
||||
int success = 0;
|
||||
|
||||
|
||||
//printf("locking sem, member count = %d\n", get_sem_member_count(sid) );
|
||||
|
||||
/* Attempt to lock the semaphore set */
|
||||
@ -164,11 +156,11 @@ static int unlock_sem(int sid)
|
||||
{
|
||||
int member = 0;
|
||||
struct sembuf sem_unlock={ member, 1, IPC_NOWAIT};
|
||||
|
||||
/* will fail if we can't can't unlock semaphore for some reason,
|
||||
|
||||
/* will fail if we can't can't unlock semaphore for some reason,
|
||||
* will NOT fail if semaphore is already unlocked
|
||||
*/
|
||||
int success = 1;
|
||||
int success = 1;
|
||||
|
||||
|
||||
/* Is the semaphore set locked? */
|
||||
@ -182,8 +174,6 @@ static int unlock_sem(int sid)
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int lock(unsigned long max_wait_milliseconds)
|
||||
{
|
||||
int locked = 0;
|
||||
@ -218,13 +208,11 @@ static int unlock(void)
|
||||
unlocked = unlock_sem(bandwidth_semaphore);
|
||||
}
|
||||
return unlocked;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static time_t get_next_node_start_time( time_t current_start_time,
|
||||
time_t reset_interval,
|
||||
time_t reset_time,
|
||||
static time_t get_next_node_start_time( time_t current_start_time,
|
||||
time_t reset_interval,
|
||||
time_t reset_time,
|
||||
unsigned char is_constant_interval
|
||||
)
|
||||
{
|
||||
@ -286,18 +274,18 @@ static time_t get_next_node_start_time( time_t current_start_time,
|
||||
next = mktime(curr);
|
||||
}
|
||||
}
|
||||
next = next + reset_time;
|
||||
next = next + reset_time;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
static void parse_returned_ip_data( void *out_data,
|
||||
uint32_t* out_index,
|
||||
unsigned char* in_buffer,
|
||||
uint32_t* in_index,
|
||||
unsigned char get_history,
|
||||
time_t reset_interval,
|
||||
time_t reset_time,
|
||||
static void parse_returned_ip_data( void *out_data,
|
||||
uint32_t* out_index,
|
||||
unsigned char* in_buffer,
|
||||
uint32_t* in_index,
|
||||
unsigned char get_history,
|
||||
time_t reset_interval,
|
||||
time_t reset_time,
|
||||
unsigned char is_constant_interval
|
||||
)
|
||||
{
|
||||
@ -324,7 +312,7 @@ static void parse_returned_ip_data( void *out_data,
|
||||
history->last_end = ip_bw_data->last_end;
|
||||
|
||||
history->history_bws = (uint64_t*)malloc( (history->num_nodes+1)*sizeof(uint64_t) );
|
||||
|
||||
|
||||
/* read bws */
|
||||
int node_index = 0;
|
||||
*in_index += 32;
|
||||
@ -334,8 +322,7 @@ static void parse_returned_ip_data( void *out_data,
|
||||
(history->history_bws)[node_index] = ip_bw_data->ipbw_data[node_index];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* We now need to deal with DST
|
||||
*
|
||||
* The problem is that the kernel can't tell the difference
|
||||
@ -344,7 +331,7 @@ static void parse_returned_ip_data( void *out_data,
|
||||
* shifts values in the bandwidth history to reflect the time
|
||||
* as it would be if the current offset from UTC had always been
|
||||
* in effect. So, we need to go backwards through the history and
|
||||
* anytime we go from DST to non-DST (or visa-versa) implement a
|
||||
* anytime we go from DST to non-DST (or visa-versa) implement a
|
||||
* shift so that returned times reflect reality.
|
||||
*/
|
||||
time_t now;
|
||||
@ -357,10 +344,9 @@ static void parse_returned_ip_data( void *out_data,
|
||||
*out_index = *out_index + 1;
|
||||
}
|
||||
|
||||
|
||||
static int get_bandwidth_data(char* id, unsigned char get_history, char* ip, unsigned long* num_ips, void** data, unsigned long max_wait_milliseconds)
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
unsigned char buf[BANDWIDTH_QUERY_LENGTH];
|
||||
memset(buf, '\0', BANDWIDTH_QUERY_LENGTH);
|
||||
int done = 0;
|
||||
@ -369,7 +355,6 @@ static int get_bandwidth_data(char* id, unsigned char get_history, char* ip, uns
|
||||
*data = NULL;
|
||||
*num_ips = 0;
|
||||
|
||||
|
||||
int got_lock = lock(max_wait_milliseconds);
|
||||
int sockfd = -1;
|
||||
if(got_lock)
|
||||
@ -377,7 +362,6 @@ static int get_bandwidth_data(char* id, unsigned char get_history, char* ip, uns
|
||||
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||
}
|
||||
|
||||
|
||||
uint32_t* request_ip = (uint32_t*)buf;
|
||||
uint32_t* request_index = (uint32_t*)(buf + 4);
|
||||
unsigned char* request_history =(unsigned char*)(buf + 8);
|
||||
@ -393,6 +377,7 @@ static int get_bandwidth_data(char* id, unsigned char get_history, char* ip, uns
|
||||
inet_aton(ip, &addr);
|
||||
*request_ip = (uint32_t)addr.s_addr;
|
||||
}
|
||||
|
||||
*request_index = 0;
|
||||
*request_history = get_history;
|
||||
sprintf(request_id, "%s", id);
|
||||
@ -419,7 +404,7 @@ static int get_bandwidth_data(char* id, unsigned char get_history, char* ip, uns
|
||||
time_t reset_interval = ip_bw_data->reset_interval;
|
||||
time_t reset_time = ip_bw_data->reset_time;
|
||||
unsigned char is_constant_interval = ip_bw_data->reset_is_constant_interval;
|
||||
|
||||
|
||||
if(!data_initialized)
|
||||
{
|
||||
*num_ips = total_ips;
|
||||
@ -490,7 +475,6 @@ static int get_bandwidth_data(char* id, unsigned char get_history, char* ip, uns
|
||||
return got_lock && (error == 0);
|
||||
}
|
||||
|
||||
|
||||
static int set_ip_block(void* ip_block_data, unsigned char is_history, unsigned char* output_buffer, uint32_t* current_output_index, uint32_t output_buffer_length)
|
||||
{
|
||||
if(is_history)
|
||||
@ -501,15 +485,14 @@ static int set_ip_block(void* ip_block_data, unsigned char is_history, unsigned
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
*( (uint32_t*)(output_buffer + *current_output_index) ) = history->ip;
|
||||
*current_output_index = *current_output_index + 4;
|
||||
|
||||
*( (uint32_t*)(output_buffer + *current_output_index) ) = history->num_nodes;
|
||||
*current_output_index = *current_output_index + 4;
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* We now need to deal with DST
|
||||
*
|
||||
* The problem is that the kernel module can't tell the difference
|
||||
@ -517,9 +500,9 @@ static int set_ip_block(void* ip_block_data, unsigned char is_history, unsigned
|
||||
* time. Whenever the time offset from UTC shifts, the kernel module
|
||||
* shifts values in the bandwidth history to reflect the time
|
||||
* as it would be if the current offset from UTC had always been
|
||||
* in effect. In order to keep all data in the kernel module
|
||||
* in effect. In order to keep all data in the kernel module
|
||||
* consistent we need to make sure values we send kernel module
|
||||
* are adjusted for current offset from UTC, not the real one,
|
||||
* are adjusted for current offset from UTC, not the real one,
|
||||
* where the offset may be inconsistent because of DST.
|
||||
*
|
||||
* Also note we ignore all but the first, second and last values in the
|
||||
@ -529,7 +512,7 @@ static int set_ip_block(void* ip_block_data, unsigned char is_history, unsigned
|
||||
* values are returned. However, when setting data, it's perfectly ok
|
||||
* to just have the three necessary values and set everything else to zero
|
||||
*/
|
||||
time_t first_start = history->first_start;
|
||||
time_t first_start = history->first_start;
|
||||
time_t first_end = history->first_end;
|
||||
time_t last_end = history->last_end;
|
||||
|
||||
@ -539,8 +522,8 @@ static int set_ip_block(void* ip_block_data, unsigned char is_history, unsigned
|
||||
first_start = first_start + (get_minutes_west(first_start)-current_minutes_west);
|
||||
first_end = first_end + (get_minutes_west(first_end)-current_minutes_west);
|
||||
last_end = last_end + (get_minutes_west(last_end)-current_minutes_west);
|
||||
|
||||
|
||||
|
||||
|
||||
*( (uint64_t*)(output_buffer + *current_output_index) ) = (uint64_t)first_start;
|
||||
*current_output_index = *current_output_index + 8;
|
||||
|
||||
@ -563,13 +546,12 @@ static int set_ip_block(void* ip_block_data, unsigned char is_history, unsigned
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ip_bw* ib = (ip_bw*)ip_block_data;
|
||||
*( (uint32_t*)(output_buffer + *current_output_index) ) = ib->ip;
|
||||
*current_output_index = *current_output_index + 4;
|
||||
*( (uint64_t*)(output_buffer + *current_output_index) ) = ib->bw;
|
||||
|
||||
|
||||
/*
|
||||
struct in_addr addr;
|
||||
addr.s_addr = ib->ip;
|
||||
@ -588,7 +570,6 @@ static int set_bandwidth_data(char* id, unsigned char zero_unset, unsigned char
|
||||
memset(buf, 0, BANDWIDTH_QUERY_LENGTH);
|
||||
int done = 0;
|
||||
|
||||
|
||||
int got_lock = lock(max_wait_milliseconds);
|
||||
int sockfd = -1;
|
||||
if(got_lock)
|
||||
@ -604,7 +585,6 @@ static int set_bandwidth_data(char* id, unsigned char zero_unset, unsigned char
|
||||
uint64_t* last_backup_time = (uint64_t*)(buf+14);
|
||||
unsigned char* set_id = (unsigned char*)(buf+22);
|
||||
|
||||
|
||||
*total_ips = num_ips;
|
||||
*next_ip_index = 0;
|
||||
*num_ips_in_buffer = 0;
|
||||
@ -685,13 +665,13 @@ static unsigned char* read_entire_file(FILE* in, unsigned long read_block_size,
|
||||
/*
|
||||
* line is the line to be parsed -- it is not modified in any way
|
||||
* max_pieces indicates number of pieces to return, if negative this is determined dynamically
|
||||
* include_remainder_at_max indicates whether the last piece, when max pieces are reached,
|
||||
* include_remainder_at_max indicates whether the last piece, when max pieces are reached,
|
||||
* should be what it would normally be (0) or the entire remainder of the line (1)
|
||||
* if max_pieces < 0 this parameter is ignored
|
||||
*
|
||||
*
|
||||
* returns all non-separator pieces in a line
|
||||
* result is dynamically allocated, MUST be freed after call-- even if
|
||||
* result is dynamically allocated, MUST be freed after call-- even if
|
||||
* line is empty (you still get a valid char** pointer to to a NULL char*)
|
||||
*/
|
||||
static char** split_on_separators(char* line, char* separators, int num_separators, int max_pieces, int include_remainder_at_max, unsigned long *pieces_read)
|
||||
@ -727,7 +707,6 @@ static char** split_on_separators(char* line, char* separators, int num_separato
|
||||
split_index = 0;
|
||||
split[split_index] = NULL;
|
||||
|
||||
|
||||
dup_line = strdup(line);
|
||||
start = dup_line;
|
||||
non_separator_found = 0;
|
||||
@ -763,7 +742,7 @@ static char** split_on_separators(char* line, char* separators, int num_separato
|
||||
first_separator_index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* copy next piece to split array */
|
||||
if(first_separator_index > 0)
|
||||
{
|
||||
@ -784,7 +763,6 @@ static char** split_on_separators(char* line, char* separators, int num_separato
|
||||
*pieces_read = split_index;
|
||||
}
|
||||
|
||||
|
||||
/* find next non-separator index, indicating start of next piece */
|
||||
start = start+ first_separator_index;
|
||||
non_separator_found = 0;
|
||||
@ -804,7 +782,7 @@ static char** split_on_separators(char* line, char* separators, int num_separato
|
||||
}
|
||||
}
|
||||
free(dup_line);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -814,14 +792,13 @@ static char** split_on_separators(char* line, char* separators, int num_separato
|
||||
return split;
|
||||
}
|
||||
|
||||
|
||||
time_t* get_interval_starts_for_history(ip_bw_history history)
|
||||
{
|
||||
time_t *start_times = NULL;
|
||||
if(history.num_nodes > 0)
|
||||
{
|
||||
start_times = (time_t*)malloc(history.num_nodes*sizeof(time_t));
|
||||
int node_index =0;
|
||||
int node_index =0;
|
||||
time_t next_start = history.first_start;
|
||||
time_t next_end = get_next_node_start_time(next_start, history.reset_interval, history.reset_time, history.is_constant_interval);
|
||||
for(node_index=0; node_index < history.num_nodes; node_index++)
|
||||
@ -834,8 +811,6 @@ time_t* get_interval_starts_for_history(ip_bw_history history)
|
||||
return start_times;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void free_ip_bw_histories(ip_bw_history* histories, int num_histories)
|
||||
{
|
||||
if(histories == NULL)
|
||||
@ -853,31 +828,28 @@ void free_ip_bw_histories(ip_bw_history* histories, int num_histories)
|
||||
free(histories);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int get_all_bandwidth_history_for_rule_id(char* id, unsigned long* num_ips, ip_bw_history** data, unsigned long max_wait_milliseconds)
|
||||
{
|
||||
return get_bandwidth_data(id, 1, "ALL", num_ips, (void*)data, max_wait_milliseconds);
|
||||
}
|
||||
|
||||
int get_ip_bandwidth_history_for_rule_id(char* id, char* ip, ip_bw_history** data, unsigned long max_wait_milliseconds)
|
||||
{
|
||||
unsigned long num_ips;
|
||||
return get_bandwidth_data(id, 1, ip, &num_ips, (void*)data, max_wait_milliseconds);
|
||||
}
|
||||
|
||||
int get_all_bandwidth_usage_for_rule_id(char* id, unsigned long* num_ips, ip_bw** data, unsigned long max_wait_milliseconds)
|
||||
{
|
||||
return get_bandwidth_data(id, 0, "ALL", num_ips, (void*)data, max_wait_milliseconds);
|
||||
}
|
||||
|
||||
int get_ip_bandwidth_usage_for_rule_id(char* id, char* ip, ip_bw** data, unsigned long max_wait_milliseconds)
|
||||
{
|
||||
unsigned long num_ips;
|
||||
return get_bandwidth_data(id, 0, ip, &num_ips, (void*)data, max_wait_milliseconds);
|
||||
}
|
||||
|
||||
|
||||
int set_bandwidth_history_for_rule_id(char* id, unsigned char zero_unset, unsigned long num_ips, ip_bw_history* data, unsigned long max_wait_milliseconds)
|
||||
{
|
||||
return set_bandwidth_data(id, zero_unset, 1, num_ips, 0, data, max_wait_milliseconds);
|
||||
@ -888,15 +860,10 @@ int set_bandwidth_usage_for_rule_id(char* id, unsigned char zero_unset, unsigned
|
||||
return set_bandwidth_data(id, zero_unset, 0, num_ips, last_backup, data, max_wait_milliseconds);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* save single id in ascii */
|
||||
int save_usage_to_file(ip_bw* data, unsigned long num_ips, char* out_file_path)
|
||||
{
|
||||
|
||||
|
||||
int success = 0;
|
||||
FILE* out_file = fopen(out_file_path, "w");
|
||||
if(out_file != NULL)
|
||||
@ -904,8 +871,8 @@ int save_usage_to_file(ip_bw* data, unsigned long num_ips, char* out_file_path)
|
||||
//dump backup time
|
||||
time_t now;
|
||||
time(&now);
|
||||
fprintf(out_file, "%-15ld\n", now);
|
||||
|
||||
fprintf(out_file, "%-15lld\n", now);
|
||||
|
||||
//dump ips
|
||||
int out_index=0;
|
||||
for(out_index=0; out_index < num_ips; out_index++)
|
||||
@ -928,7 +895,7 @@ int save_history_to_file(ip_bw_history* data, unsigned long num_ips, char* out_f
|
||||
FILE* out_file = fopen(out_file_path, "wb");
|
||||
if(out_file != NULL)
|
||||
{
|
||||
//dump number of ips & history interval parameter
|
||||
//dump number of ips & history interval parameter
|
||||
//note that we assume interval is same for all histories
|
||||
//(which will be the case if they all come from the same rule id)
|
||||
fwrite((uint32_t*)(&num_ips), 4, 1, out_file);
|
||||
@ -961,7 +928,7 @@ int save_history_to_file(ip_bw_history* data, unsigned long num_ips, char* out_f
|
||||
for(out_index=0; out_index < num_ips; out_index++)
|
||||
{
|
||||
ip_bw_history next = data[out_index];
|
||||
|
||||
|
||||
fwrite( &(next.ip), 4, 1, out_file);
|
||||
fwrite( &(next.num_nodes), 4, 1, out_file);
|
||||
if(next.num_nodes == 0)
|
||||
@ -986,7 +953,6 @@ int save_history_to_file(ip_bw_history* data, unsigned long num_ips, char* out_f
|
||||
bw_bits = bw_bits == 32 && (bw < INT32_MAX) ? 32 : 64;
|
||||
}
|
||||
|
||||
|
||||
fwrite( &first_start, 8, 1, out_file);
|
||||
fwrite( &first_end, 8, 1, out_file);
|
||||
fwrite( &last_end, 8, 1, out_file);
|
||||
@ -1013,7 +979,6 @@ int save_history_to_file(ip_bw_history* data, unsigned long num_ips, char* out_f
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
ip_bw* load_usage_from_file(char* in_file_path, unsigned long* num_ips, time_t* last_backup)
|
||||
{
|
||||
ip_bw* data = NULL;
|
||||
@ -1040,7 +1005,7 @@ ip_bw* load_usage_from_file(char* in_file_path, unsigned long* num_ips, time_t*
|
||||
struct in_addr ipaddr;
|
||||
if(data_part_index == 0)
|
||||
{
|
||||
sscanf(data_parts[data_part_index], "%ld", last_backup);
|
||||
sscanf(data_parts[data_part_index], "%lld", last_backup);
|
||||
//printf("last_backup = %ld\n", *last_backup);
|
||||
data_part_index++;
|
||||
}
|
||||
@ -1067,19 +1032,18 @@ ip_bw* load_usage_from_file(char* in_file_path, unsigned long* num_ips, time_t*
|
||||
*num_ips = *num_ips + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* cleanup by freeing data_parts */
|
||||
for(data_part_index = 0; data_part_index < num_data_parts; data_part_index++)
|
||||
{
|
||||
free(data_parts[data_part_index]);
|
||||
}
|
||||
|
||||
|
||||
free(data_parts);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
ip_bw_history* load_history_from_file(char* in_file_path, unsigned long* num_ips)
|
||||
{
|
||||
ip_bw_history* data = NULL;
|
||||
@ -1090,7 +1054,7 @@ ip_bw_history* load_history_from_file(char* in_file_path, unsigned long* num_ips
|
||||
uint64_t reset_interval;
|
||||
uint64_t reset_time;
|
||||
unsigned char is_constant_interval;
|
||||
|
||||
|
||||
uint32_t nips = 0;
|
||||
fread(&nips, 4, 1, in_file);
|
||||
*num_ips = (unsigned long)nips;
|
||||
@ -1109,7 +1073,7 @@ ip_bw_history* load_history_from_file(char* in_file_path, unsigned long* num_ips
|
||||
|
||||
uint32_t ip;
|
||||
uint32_t num_nodes;
|
||||
uint64_t first_start;
|
||||
uint64_t first_start;
|
||||
uint64_t first_end;
|
||||
uint64_t last_end;
|
||||
unsigned char bw_bits;
|
||||
@ -1159,7 +1123,6 @@ ip_bw_history* load_history_from_file(char* in_file_path, unsigned long* num_ips
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void print_usage(FILE* out, ip_bw* usage, unsigned long num_ips)
|
||||
{
|
||||
unsigned long usage_index;
|
||||
@ -1186,7 +1149,7 @@ void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned lon
|
||||
for(history_index=0; history_index < num_histories; history_index++)
|
||||
{
|
||||
ip_bw_history history = histories[history_index];
|
||||
|
||||
|
||||
int history_initialized = 1;
|
||||
if( history.first_start == 0 && history.first_end == 0 && history.last_end == 0)
|
||||
{
|
||||
@ -1198,7 +1161,6 @@ void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned lon
|
||||
char *ip_str = NULL;
|
||||
time_t *times = NULL;
|
||||
|
||||
|
||||
if(history.ip != 0)
|
||||
{
|
||||
struct in_addr ipaddr;
|
||||
@ -1209,8 +1171,7 @@ void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned lon
|
||||
{
|
||||
ip_str = strdup("COMBINED");
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(output_type == 'm' || output_type == 'h')
|
||||
{
|
||||
fprintf(out, "%s %-15s\n", id, ip_str);
|
||||
@ -1218,9 +1179,9 @@ void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned lon
|
||||
|
||||
if(output_type == 'm')
|
||||
{
|
||||
printf("%ld\n", history.first_start);
|
||||
printf("%ld\n", history.first_end);
|
||||
printf("%ld\n", history.last_end);
|
||||
printf("%lld\n", history.first_start);
|
||||
printf("%lld\n", history.first_end);
|
||||
printf("%lld\n", history.last_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1240,7 +1201,7 @@ void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned lon
|
||||
{
|
||||
time_t start = times[hindex];
|
||||
time_t end = hindex+1 < history.num_nodes ? times[hindex+1] : 0 ;
|
||||
|
||||
|
||||
char* start_str = strdup(asctime(localtime(&start)));
|
||||
char* end_str = end == 0 ? strdup("(Now)") : strdup(asctime(localtime(&end)));
|
||||
char* nl = strchr(start_str, '\n');
|
||||
@ -1253,17 +1214,16 @@ void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned lon
|
||||
{
|
||||
*nl = '\0';
|
||||
}
|
||||
|
||||
|
||||
if(output_type == 'h')
|
||||
{
|
||||
fprintf(out, "%lld\t%s\t%s\n", (unsigned long long int)bw, start_str, end_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out, "%s,%s,%ld,%ld,%lld\n", id, ip_str, start, end, (unsigned long long int)bw );
|
||||
fprintf(out, "%s,%s,%lld,%lld,%lld\n", id, ip_str, start, end, (unsigned long long int)bw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
free(start_str);
|
||||
free(end_str);
|
||||
}
|
||||
@ -1275,9 +1235,6 @@ void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned lon
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void unlock_bandwidth_semaphore(void)
|
||||
{
|
||||
unlock();
|
||||
@ -1322,13 +1279,12 @@ int get_minutes_west(time_t now)
|
||||
|
||||
utc_day = utc_day < tz_day - 1 ? tz_day + 1 : utc_day;
|
||||
tz_day = tz_day < utc_day - 1 ? utc_day + 1 : tz_day;
|
||||
|
||||
|
||||
minuteswest = (24*60*utc_day + 60*utc_hour + utc_minute) - (24*60*tz_day + 60*tz_hour + tz_minute) ;
|
||||
|
||||
return minuteswest;
|
||||
}
|
||||
|
||||
|
||||
void set_kernel_timezone(void)
|
||||
{
|
||||
time_t now;
|
||||
@ -1342,8 +1298,8 @@ void set_kernel_timezone(void)
|
||||
|
||||
/* Get tv to pass to settimeofday(2) to be sure we avoid hour-sized warp */
|
||||
/* (see gettimeofday(2) man page, or /usr/src/linux/kernel/time.c) */
|
||||
syscall(SYS_gettimeofday, &tv, &old_tz);
|
||||
gettimeofday(&tv, &old_tz);
|
||||
|
||||
/* set timezone */
|
||||
syscall(SYS_settimeofday, &tv, &new_tz);
|
||||
settimeofday(&tv, &new_tz);
|
||||
}
|
||||
|
||||
@ -32,16 +32,16 @@
|
||||
#include <signal.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <errno.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#define BANDWIDTH_QUERY_LENGTH 16384
|
||||
|
||||
/* socket id parameters (for userspace i/o) */
|
||||
#define BANDWIDTH_SET 2048
|
||||
#define BANDWIDTH_GET 2049
|
||||
|
||||
|
||||
/* max id length */
|
||||
#define BANDWIDTH_MAX_ID_LENGTH 50
|
||||
|
||||
@ -57,7 +57,6 @@
|
||||
#define BANDWIDTH_MONTH 84
|
||||
#define BANDWIDTH_NEVER 85
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct ip_bw_struct
|
||||
{
|
||||
@ -87,7 +86,7 @@ typedef struct ip_bw_kernel_data_item_struct
|
||||
uint64_t ipbw_data[0];
|
||||
}ip_bw_kernel_data_item;
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint8_t error;
|
||||
uint32_t ip_total;
|
||||
@ -126,36 +125,25 @@ extern int get_ip_bandwidth_history_for_rule_id(char* id, char* ip, ip_bw_histor
|
||||
extern int get_all_bandwidth_usage_for_rule_id(char* id, unsigned long* num_ips, ip_bw** data, unsigned long max_wait_milliseconds);
|
||||
extern int get_ip_bandwidth_usage_for_rule_id(char* id, char* ip, ip_bw** data, unsigned long max_wait_milliseconds);
|
||||
|
||||
|
||||
|
||||
extern int set_bandwidth_history_for_rule_id(char* id, unsigned char zero_unset, unsigned long num_ips, ip_bw_history* data, unsigned long max_wait_milliseconds);
|
||||
extern int set_bandwidth_usage_for_rule_id(char* id, unsigned char zero_unset, unsigned long num_ips, time_t last_backup, ip_bw* data, unsigned long max_wait_milliseconds);
|
||||
|
||||
|
||||
|
||||
extern int save_usage_to_file(ip_bw* data, unsigned long num_ips, char* out_file_path);
|
||||
extern int save_history_to_file(ip_bw_history* data, unsigned long num_ips, char* out_file_path);
|
||||
|
||||
|
||||
|
||||
extern ip_bw* load_usage_from_file(char* in_file_path, unsigned long* num_ips, time_t* last_backup);
|
||||
extern ip_bw_history* load_history_from_file(char* in_file_path, unsigned long* num_ips);
|
||||
|
||||
extern void print_usage(FILE* out, ip_bw* usage, unsigned long num_ips);
|
||||
extern void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned long num_histories, char output_type);
|
||||
|
||||
|
||||
|
||||
|
||||
extern void unlock_bandwidth_semaphore(void);
|
||||
extern void unlock_bandwidth_semaphore_on_exit(void);
|
||||
|
||||
|
||||
/* sets kernel timezone minuteswest to match user timezone */
|
||||
extern int get_minutes_west(time_t now);
|
||||
extern void set_kernel_timezone(void);
|
||||
|
||||
|
||||
/* safe malloc & strdup functions used to handle malloc errors cleanly */
|
||||
extern void* ipt_bwctl_safe_malloc(size_t size);
|
||||
extern char* ipt_bwctl_safe_strdup(const char* str);
|
||||
|
||||
@ -18,12 +18,10 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <ipt_bwctl.h>
|
||||
#define malloc ipt_bwctl_safe_malloc
|
||||
#define strdup ipt_bwctl_safe_strdup
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *id = NULL;
|
||||
@ -40,7 +38,7 @@ int main(int argc, char **argv)
|
||||
int c;
|
||||
struct in_addr read_addr;
|
||||
while((c = getopt(argc, argv, "i:I:a:A:f:F:tThHmMuU")) != -1)
|
||||
{
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case 'i':
|
||||
@ -96,16 +94,15 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(id == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: you must specify an id to query\n\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
set_kernel_timezone();
|
||||
|
||||
set_kernel_timezone();
|
||||
unlock_bandwidth_semaphore_on_exit();
|
||||
|
||||
|
||||
if(get_history == 0)
|
||||
{
|
||||
if(address == NULL)
|
||||
@ -136,7 +133,6 @@ int main(int argc, char **argv)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
if(out_file_path != NULL)
|
||||
{
|
||||
if(get_history == 0)
|
||||
|
||||
@ -34,10 +34,9 @@ int main(int argc, char **argv)
|
||||
int last_backup_from_cl = 0;
|
||||
int is_history_file = 0;
|
||||
|
||||
|
||||
int c;
|
||||
while((c = getopt(argc, argv, "i:I:b:B:f:F:UuHh")) != -1)
|
||||
{
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case 'i':
|
||||
@ -55,7 +54,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
if(sscanf(optarg, "%ld", &last_backup) == 0)
|
||||
if(sscanf(optarg, "%lld", &last_backup) == 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: invalid backup time specified. Should be unix epoch seconds -- number of seconds since 1970 (UTC)\n");
|
||||
exit(0);
|
||||
@ -82,7 +81,6 @@ int main(int argc, char **argv)
|
||||
default:
|
||||
fprintf(stderr, "USAGE:\n\t%s -i [ID] -b [LAST_BACKUP_TIME] -f [IN_FILE_NAME] [ IP BANDWIDTH PAIRS, IF -f NOT SPECIFIED ]\n", argv[0]);
|
||||
exit(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,14 +89,15 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "ERROR: you must specify an id for which to set data\n\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if(in_file_path == NULL && is_history_file)
|
||||
{
|
||||
fprintf(stderr, "ERROR: you need to specify file to load history from\n\t\t(history format is too complex to load from command line)\n");
|
||||
}
|
||||
|
||||
|
||||
set_kernel_timezone();
|
||||
unlock_bandwidth_semaphore_on_exit();
|
||||
|
||||
int query_succeeded = 0;
|
||||
if(in_file_path != NULL)
|
||||
{
|
||||
@ -128,12 +127,11 @@ int main(int argc, char **argv)
|
||||
unsigned long num_data_parts;
|
||||
data_parts = argv+optind;
|
||||
num_data_parts = argc - optind;
|
||||
|
||||
|
||||
unsigned long num_ips = num_data_parts/2;
|
||||
ip_bw* buffer = (ip_bw*)malloc(num_ips*sizeof(ip_bw));
|
||||
ip_bw* buffer = (ip_bw*)malloc(num_ips*sizeof(ip_bw));
|
||||
unsigned long data_index = 0;
|
||||
unsigned long buffer_index = 0;
|
||||
|
||||
while(data_index < num_data_parts)
|
||||
{
|
||||
ip_bw next;
|
||||
@ -141,10 +139,10 @@ int main(int argc, char **argv)
|
||||
int valid = inet_aton(data_parts[data_index], &ipaddr);
|
||||
if((!valid) && (!last_backup_from_cl))
|
||||
{
|
||||
sscanf(data_parts[data_index], "%ld", &last_backup);
|
||||
sscanf(data_parts[data_index], "%lld", &last_backup);
|
||||
}
|
||||
data_index++;
|
||||
|
||||
|
||||
if(valid && data_index < num_data_parts)
|
||||
{
|
||||
next.ip = ipaddr.s_addr;
|
||||
@ -166,7 +164,7 @@ int main(int argc, char **argv)
|
||||
num_ips = buffer_index; /* number that were successfully read */
|
||||
query_succeeded = set_bandwidth_usage_for_rule_id(id, 1, num_ips, last_backup, buffer, 1000);
|
||||
}
|
||||
|
||||
|
||||
if(!query_succeeded)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Could not set data. Please try again.\n\n");
|
||||
@ -183,4 +181,3 @@ int main(int argc, char **argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user