Fixed bug in use of get_bandwidth_iwinfo() in AP kicking
Fix rounding of transmission rate calculations in get_bandwidth_iwinfo()
Restructure of get_bandwidth() while finding bug
Adjusted erroneus match test in ap_array_insert()
Removed brutal exit() for failed file path

LOGGING
Add dawnlog_* functions and macros to convert printf() family and perror() logging to syslog() family
Removed unnecessary sprintf() for building log strings (embed format directly)
Add local config settings for log level
Add command line parameters for log level and destination
Set default log level to suppress a lot of previously noisy messages
Restore some previously removed noisy messages as DEBUG level in case they help in future
Eliminate DAWN_NO_OUTPUT static code checks which are no longer used

MEMORY MANAGEMENT
Set pointers to NULL after free() to help force out memory handling errors
Add some extra memory / resource tracking to try and chase out latent bugs / leaks
Fixed a couple of memory traces that were misreporting

READABILITY / OTHER
Removed decide_function() which made some logic hard to follow
Removed kick_client() function to streamline code
Removed unnecessary linked-list length checks
Fixed some typos on function names / comments
Changed how test_storage forces SEGV due to new compiler warnings
This commit is contained in:
Ian Clowes 2021-12-14 00:23:47 +00:00
parent 3526fb8384
commit fd1ef0f55a
19 changed files with 1352 additions and 592 deletions

View file

@ -3,6 +3,7 @@
#include <gcrypt.h>
#include "utils.h"
#include "memory_utils.h"
#include "crypto.h"
@ -14,7 +15,7 @@ gcry_cipher_hd_t gcry_cipher_hd;
void gcrypt_init() {
if (!gcry_check_version(GCRYPT_VERSION)) {
fprintf(stderr, "gcrypt: library version mismatch");
dawnlog_error("gcrypt: library version mismatch");
}
gcry_error_t err = 0;
err = gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
@ -23,7 +24,7 @@ void gcrypt_init() {
err |= gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
if (err) {
fprintf(stderr, "gcrypt: failed initialization");
dawnlog_error("gcrypt: failed initialization");
}
}
@ -37,7 +38,7 @@ void gcrypt_set_key_and_iv(const char *key, const char *iv) {
GCRY_C_MODE, // int
0);
if (gcry_error_handle) {
fprintf(stderr, "gcry_cipher_open failed: %s/%s\n",
dawnlog_error("gcry_cipher_open failed: %s/%s\n",
gcry_strsource(gcry_error_handle),
gcry_strerror(gcry_error_handle));
return;
@ -45,7 +46,7 @@ void gcrypt_set_key_and_iv(const char *key, const char *iv) {
gcry_error_handle = gcry_cipher_setkey(gcry_cipher_hd, key, keylen);
if (gcry_error_handle) {
fprintf(stderr, "gcry_cipher_setkey failed: %s/%s\n",
dawnlog_error("gcry_cipher_setkey failed: %s/%s\n",
gcry_strsource(gcry_error_handle),
gcry_strerror(gcry_error_handle));
return;
@ -53,7 +54,7 @@ void gcrypt_set_key_and_iv(const char *key, const char *iv) {
gcry_error_handle = gcry_cipher_setiv(gcry_cipher_hd, iv, blklen);
if (gcry_error_handle) {
fprintf(stderr, "gcry_cipher_setiv failed: %s/%s\n",
dawnlog_error("gcry_cipher_setiv failed: %s/%s\n",
gcry_strsource(gcry_error_handle),
gcry_strerror(gcry_error_handle));
return;
@ -67,12 +68,12 @@ char *gcrypt_encrypt_msg(char *msg, size_t msg_length, int *out_length) {
char *out = dawn_malloc(msg_length);
if (!out){
fprintf(stderr, "gcry_cipher_encrypt error: not enought memory\n");
dawnlog_error("gcry_cipher_encrypt error: not enough memory\n");
return NULL;
}
gcry_error_handle = gcry_cipher_encrypt(gcry_cipher_hd, out, msg_length, msg, msg_length);
if (gcry_error_handle) {
fprintf(stderr, "gcry_cipher_encrypt failed: %s/%s\n",
dawnlog_error("gcry_cipher_encrypt failed: %s/%s\n",
gcry_strsource(gcry_error_handle),
gcry_strerror(gcry_error_handle));
return NULL;
@ -88,25 +89,28 @@ char *gcrypt_decrypt_msg(char *msg, size_t msg_length) {
char *out_buffer = dawn_malloc(msg_length);
if (!out_buffer){
fprintf(stderr, "gcry_cipher_decrypt error: not enought memory\n");
dawnlog_error("gcry_cipher_decrypt error: not enough memory\n");
return NULL;
}
gcry_error_handle = gcry_cipher_decrypt(gcry_cipher_hd, out_buffer, msg_length, msg, msg_length);
if (gcry_error_handle) {
fprintf(stderr, "gcry_cipher_decrypt failed: %s/%s\n",
dawnlog_error("gcry_cipher_decrypt failed: %s/%s\n",
gcry_strsource(gcry_error_handle),
gcry_strerror(gcry_error_handle));
dawn_free(out_buffer);
out_buffer = NULL;
return NULL;
}
char *out = dawn_malloc(strlen(out_buffer) + 1);
if (!out){
dawn_free(out_buffer);
fprintf(stderr, "gcry_cipher_decrypt error: not enought memory\n");
out_buffer = NULL;
dawnlog_error("gcry_cipher_decrypt error: not enough memory\n");
return NULL;
}
strcpy(out, out_buffer);
dawn_free(out_buffer);
out_buffer = NULL;
return out;
}

View file

@ -9,16 +9,9 @@
#include "mac_utils.h"
#include "utils.h"
// Core data storage array sizes
#define ARRAY_AP_LEN 100
#define ARRAY_CLIENT_LEN 300
#define PROBE_ARRAY_LEN 1000
#define DENY_REQ_ARRAY_LEN 100
/* Mac */
// ---------------- Defines -------------------
#define MAC_LIST_LENGTH 100
#define DEFAULT_RRM_MODE_ORDER "pat"
#define RRM_MODE_COUNT 3
@ -127,6 +120,10 @@ struct time_config_s {
time_t update_beacon_reports;
};
struct local_config_s {
int loglevel;
};
#define MAX_IP_LENGTH 46
#define MAX_KEY_LENGTH 65
@ -145,12 +142,10 @@ struct network_config_s {
extern struct network_config_s network_config;
extern struct time_config_s timeout_config;
extern struct local_config_s local_config;
extern struct probe_metric_s dawn_metric;
/*** Core DAWN data structures for tracking network devices and status ***/
// Define this to remove printing / reporing of fields, and hence observe
// which fields are evaluated in use at compile time.
// #define DAWN_NO_OUTPUT
// TODO notes:
// Never used? = No code reference
@ -174,11 +169,9 @@ typedef struct probe_entry_s {
uint8_t vht_capabilities; // eval_probe_metric()
time_t time; // remove_old...entries
int counter;
#ifndef DAWN_NO_OUTPUT
int deny_counter; // TODO: Never used?
uint8_t max_supp_datarate; // TODO: Never used?
uint8_t min_supp_datarate; // TODO: Never used?
#endif
uint32_t rcpi;
uint32_t rsni;
} probe_entry;
@ -316,7 +309,7 @@ void remove_old_probe_entries(time_t current_time, long long int threshold);
void print_probe_array();
void print_probe_entry(probe_entry *entry);
void print_probe_entry(int level, probe_entry *entry);
int eval_probe_metric(struct probe_entry_s * probe_entry, ap *ap_entry);
@ -326,7 +319,7 @@ auth_entry *insert_to_denied_req_array(auth_entry*entry, int inc_counter, time_t
void remove_old_denied_req_entries(time_t current_time, long long int threshold, int logmac);
void print_auth_entry(auth_entry *entry);
void print_auth_entry(int level, auth_entry *entry);
// ---------------- Functions ----------------
@ -350,7 +343,7 @@ client *client_array_delete(client *entry, int unlink_only);
void print_client_array();
void print_client_entry(client *entry);
void print_client_entry(int level, client *entry);
int is_connected_somehwere(struct dawn_mac client_addr);

View file

@ -28,6 +28,12 @@ struct probe_metric_s uci_get_dawn_metric();
*/
struct time_config_s uci_get_time_config();
/**
* Function that returns a struct with all the local config values.
* @return the local config values.
*/
struct local_config_s uci_get_local_config();
/**
* Function that returns all the network informations.
* @return the network config values.

View file

@ -21,7 +21,7 @@ struct network_con_s {
* @param port
* @return
*/
int add_tcp_conncection(char *ipv4, int port);
int add_tcp_connection(char *ipv4, int port);
/**
* Opens a tcp server and adds it to the uloop.

View file

@ -2,6 +2,7 @@
#define __DAWN_UTILS_H
#include <stdint.h>
#include <syslog.h>
/**
* Check if a string is greater than another one.
@ -11,4 +12,91 @@
*/
int string_is_greater(char *str, char *str_2);
/*
** Log handling for dawn process
*/
#define DAWNLOG_DEST_SYSLOG 0 // Send log output to syslog...
#define DAWNLOG_DEST_STDIO 1 // ... or stdout / stderr as appropriate
#define DAWNLOG_PERROR 0x08 // Bit flag to signal inclusion of errno from system calls
#define DAWNLOG_PRIMASK 0x07 // Bitmask to obtain only priority value
#define DAWNLOG_ERROR 5 // Serious malfunction / unexpected behaviour - eg: OS resource exhaustion
#define DAWNLOG_WARNING 4 // Something appears wrong, but recoverable - eg: data structures inconsistent
#define DAWNLOG_ALWAYS 3 // Standard behaviour always worth reporting - should be very low frequency messages
#define DAWNLOG_INFO 2 // Reporting on standard behaviour - should be comprehensible to user
#define DAWNLOG_TRACE 1 // More info to help trace where algorithms may be going wrong
#define DAWNLOG_DEBUG 0 // Deeper tracing to fix bugs
#define DAWNLOG_COMPILE_MIN DAWNLOG_DEBUG // Messages lower than this priority are not compiled
#define DAWNLOG_COMPILING(level) (level >= DAWNLOG_COMPILE_MIN)
#define dawnlog_perror(s, ...) dawnlog(DAWNLOG_ERROR|DAWNLOG_PERROR, "%s()=%s@%d %s - " s, __func__, dawnlog_basename(__FILE__), __LINE__, dawnlog_pbuf, ##__VA_ARGS__)
#define dawnlog_error(fmt, ...) dawnlog(DAWNLOG_ERROR, "%s()=%s@%d " fmt, __func__, dawnlog_basename(__FILE__), __LINE__, ##__VA_ARGS__)
#define dawnlog_warning(fmt, ...) dawnlog(DAWNLOG_WARNING, fmt, ##__VA_ARGS__)
#define dawnlog_always(fmt, ...) dawnlog(DAWNLOG_ALWAYS, fmt, ##__VA_ARGS__)
#if DAWNLOG_COMPILING(DAWNLOG_INFO)
#define dawnlog_info(fmt, ...) dawnlog(DAWNLOG_INFO, fmt, ##__VA_ARGS__)
#else
#define dawnlog_info(fmt, ...)
#endif
// Use the ..._func variants to get source code position added automatically: function, filename, line
#if DAWNLOG_COMPILING(DAWNLOG_TRACE)
#define dawnlog_trace(fmt, ...) dawnlog(DAWNLOG_TRACE, fmt, ##__VA_ARGS__)
#define dawnlog_trace_func(fmt, ...) dawnlog(DAWNLOG_TRACE, "%s()=%s@%d " fmt, __func__, dawnlog_basename(__FILE__), __LINE__, ##__VA_ARGS__)
#else
#define dawnlog_trace(fmt, ...)
#define dawnlog_trace_func(fmt, ...)
#endif
#if DAWNLOG_COMPILING(DAWNLOG_DEBUG)
#define dawnlog_debug(fmt, ...) dawnlog(DAWNLOG_DEBUG, fmt, ##__VA_ARGS__)
#define dawnlog_debug_func(fmt, ...) dawnlog(DAWNLOG_DEBUG, "%s()=%s@%d " fmt, __func__, dawnlog_basename(__FILE__), __LINE__, ##__VA_ARGS__)
#else
#define dawnlog_debug(fmt, ...)
#define dawnlog_debug_func(fmt, ...)
#endif
extern char dawnlog_pbuf[]; // Buffer for errno conversion for dawnlog_perror()
/**
* Set the output target for dawnlog()
* @param logdest: DAWNLOG_DEST_*
*/
void dawnlog_dest(int logdest);
/**
* Minimum priority level to be logged
* @param level: A priority level
*/
void dawnlog_minlevel(int level);
/**
* Check whether a priority level would be actually logged to allow callers
* to skip "expensive" preparation such as string manipulation or loops
* @param level
* @return TRUE if the priority level would be logged
*/
int dawnlog_showing(int level);
/**
* Log a message.
* @param level
* @param fmt
* @return
*/
void dawnlog(int level, const char* fmt, ...);
/**
* Return pointer to filename part of full path.
* @param file
* @return
*/
const char* dawnlog_basename(const char* file);
#endif

View file

@ -3,7 +3,6 @@
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include "memory_utils.h"
@ -49,15 +48,50 @@ void signal_handler(int sig) {
}
int main(int argc, char **argv) {
const char *ubus_socket = NULL;
argc -= optind;
argv += optind;
/* Load local config now so command line can override it */
uci_init();
local_config = uci_get_local_config();
openlog("dawn", LOG_PID|LOG_CONS, LOG_DAEMON);
syslog(LOG_INFO, "DAWN instance %d %s...", 0, "starting");
closelog();
int logdest = DAWNLOG_DEST_SYSLOG;
int opt = getopt(argc, argv, "l:o:");
while (opt != -1) {
switch (opt) {
case 'l':
if (!strcmp(optarg, "info"))
dawnlog_minlevel(DAWNLOG_INFO);
else if (!strcmp(optarg, "trace"))
dawnlog_minlevel(DAWNLOG_TRACE);
else if (!strcmp(optarg, "debug"))
dawnlog_minlevel(DAWNLOG_DEBUG);
else
dawnlog_warning("Unrecognised option for -l: %s\n", optarg);
break;
case 'o':
if (!strcmp(optarg, "stdio"))
logdest = DAWNLOG_DEST_STDIO;
else if (!strcmp(optarg, "syslog"))
logdest = DAWNLOG_DEST_SYSLOG;
else
dawnlog_warning("Unrecognised option for -o: %s\n", optarg);
break;
default: /* '?' */
dawnlog_warning("Unrecognised option (%s), aborting read of them\n", argv[0]);
break;
}
opt = getopt(argc, argv, "l:o:");
}
if (logdest == DAWNLOG_DEST_SYSLOG)
openlog("dawn", LOG_PID, LOG_DAEMON);
dawnlog_dest(logdest);
dawnlog_info("DAWN instance built around %s on %s starting...", __TIME__, __DATE__);
// connect signals
signal_action.sa_handler = signal_handler;
@ -67,7 +101,6 @@ closelog();
sigaction(SIGTERM, &signal_action, NULL);
sigaction(SIGINT, &signal_action, NULL);
uci_init();
// TODO: Why the extra loacl struct to retuen into?
struct network_config_s net_config = uci_get_dawn_network();
network_config = net_config;

View file

@ -2,6 +2,7 @@
#include <string.h>
#include <unistd.h>
#include "utils.h"
#include "broadcastsocket.h"
int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_port, struct sockaddr_in *addr) {
@ -10,7 +11,7 @@ int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_
// Create socket
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
fprintf(stderr, "Failed to create socket.\n");
dawnlog_error("Failed to create socket.\n");
return -1;
}
@ -18,7 +19,7 @@ int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_
broadcast_permission = 1;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcast_permission,
sizeof(broadcast_permission)) < 0) {
fprintf(stderr, "Failed to create socket.\n");
dawnlog_error("Failed to create socket.\n");
return -1;
}
@ -30,7 +31,7 @@ int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_
// Bind socket
while (bind(sock, (struct sockaddr *) addr, sizeof(*addr)) < 0) {
fprintf(stderr, "Binding socket failed!\n");
dawnlog_error("Binding socket failed!\n");
sleep(1);
}
return sock;

View file

@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include "utils.h"
#include "multicastsocket.h"
// based on: http://openbook.rheinwerk-verlag.de/linux_unix_programmierung/Kap11-018.htm
@ -18,7 +19,7 @@ int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_
addr->sin_port = htons (_multicast_port);
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket()");
dawnlog_perror("socket()");
exit(EXIT_FAILURE);
}
@ -28,13 +29,13 @@ int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_
SOL_SOCKET,
SO_REUSEADDR,
&loop, sizeof(loop)) < 0) {
perror("setsockopt:SO_REUSEADDR");
dawnlog_perror("setsockopt:SO_REUSEADDR");
exit(EXIT_FAILURE);
}
if (bind(sock,
(struct sockaddr *) addr,
sizeof(*addr)) < 0) {
perror("bind");
dawnlog_perror("bind");
exit(EXIT_FAILURE);
}
@ -44,7 +45,7 @@ int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_
IPPROTO_IP,
IP_MULTICAST_LOOP,
&loop, sizeof(loop)) < 0) {
perror("setsockopt:IP_MULTICAST_LOOP");
dawnlog_perror("setsockopt:IP_MULTICAST_LOOP");
exit(EXIT_FAILURE);
}
@ -52,14 +53,14 @@ int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_
command.imr_multiaddr.s_addr = inet_addr(_multicast_ip);
command.imr_interface.s_addr = htonl (INADDR_ANY);
if (command.imr_multiaddr.s_addr == -1) {
perror("Wrong multicast address!\n");
dawnlog_perror("Wrong multicast address!\n");
exit(EXIT_FAILURE);
}
if (setsockopt(sock,
IPPROTO_IP,
IP_ADD_MEMBERSHIP,
&command, sizeof(command)) < 0) {
perror("setsockopt:IP_ADD_MEMBERSHIP");
dawnlog_perror("setsockopt:IP_ADD_MEMBERSHIP");
}
return sock;
}
@ -69,7 +70,7 @@ int remove_multicast_socket(int socket) {
IPPROTO_IP,
IP_DROP_MEMBERSHIP,
&command, sizeof(command)) < 0) {
perror("setsockopt:IP_DROP_MEMBERSHIP");
dawnlog_perror("setsockopt:IP_DROP_MEMBERSHIP");
return -1;
}
return 0;

View file

@ -3,6 +3,7 @@
#include <string.h>
#include <libubox/blobmsg_json.h>
#include "utils.h"
#include "memory_utils.h"
#include "multicastsocket.h"
#include "broadcastsocket.h"
@ -37,9 +38,7 @@ int init_socket_runopts(const char *_ip, int _port, int _multicast_socket) {
multicast_socket = _multicast_socket;
if (multicast_socket) {
#ifndef DAWN_NO_OUTPUT
printf("Settingup multicastsocket!\n");
#endif
dawnlog_info("Settingup multicastsocket!\n");
sock = setup_multicast_socket(ip, port, &addr);
} else {
sock = setup_broadcast_socket(ip, port, &addr);
@ -48,19 +47,17 @@ int init_socket_runopts(const char *_ip, int _port, int _multicast_socket) {
pthread_t sniffer_thread;
if (network_config.use_symm_enc) {
if (pthread_create(&sniffer_thread, NULL, receive_msg_enc, NULL)) {
fprintf(stderr, "Could not create receiving thread!\n");
dawnlog_error("Could not create receiving thread!\n");
return -1;
}
} else {
if (pthread_create(&sniffer_thread, NULL, receive_msg, NULL)) {
fprintf(stderr, "Could not create receiving thread!\n");
dawnlog_error("Could not create receiving thread!\n");
return -1;
}
}
#ifndef DAWN_NO_OUTPUT
fprintf(stdout, "Connected to %s:%d\n", ip, port);
#endif
dawnlog_info("Connected to %s:%d\n", ip, port);
return 0;
}
@ -69,7 +66,7 @@ void *receive_msg(void *args) {
while (1) {
if ((recv_string_len =
recvfrom(sock, recv_string, MAX_RECV_STRING, 0, NULL, 0)) < 0) {
fprintf(stderr, "Could not receive message!");
dawnlog_error("Could not receive message!");
continue;
}
@ -83,9 +80,7 @@ void *receive_msg(void *args) {
}
recv_string[recv_string_len] = '\0';
#ifndef DAWN_NO_OUTPUT
printf("Received network message: %s\n", recv_string);
#endif
dawnlog_debug("Received network message: %s\n", recv_string);
handle_network_msg(recv_string);
}
}
@ -94,7 +89,7 @@ void *receive_msg_enc(void *args) {
while (1) {
if ((recv_string_len =
recvfrom(sock, recv_string, MAX_RECV_STRING, 0, NULL, 0)) < 0) {
fprintf(stderr, "Could not receive message!\n");
dawnlog_error("Could not receive message!\n");
continue;
}
@ -110,23 +105,24 @@ void *receive_msg_enc(void *args) {
char *base64_dec_str = dawn_malloc(B64_DECODE_LEN(strlen(recv_string)));
if (!base64_dec_str){
fprintf(stderr, "Received network error: not enough memory\n");
dawnlog_error("Received network error: not enough memory\n");
return 0;
}
int base64_dec_length = b64_decode(recv_string, base64_dec_str, B64_DECODE_LEN(strlen(recv_string)));
char *dec = gcrypt_decrypt_msg(base64_dec_str, base64_dec_length);
if (!dec){
dawn_free(base64_dec_str);
fprintf(stderr, "Received network error: not enough memory\n");
base64_dec_str = NULL;
dawnlog_error("Received network error: not enough memory\n");
return 0;
}
#ifndef DAWN_NO_OUTPUT
printf("Received network message: %s\n", dec);
#endif
dawnlog_debug("Received network message: %s\n", dec);
dawn_free(base64_dec_str);
base64_dec_str = NULL;
handle_network_msg(dec);
dawn_free(dec);
dec = NULL;
}
}
@ -140,7 +136,7 @@ int send_string(char *msg) {
0,
(struct sockaddr *) &addr,
sizeof(addr)) < 0) {
perror("sendto()");
dawnlog_perror("sendto()");
pthread_mutex_unlock(&send_mutex);
exit(EXIT_FAILURE);
}
@ -156,7 +152,7 @@ int send_string_enc(char *msg) {
size_t msglen = strlen(msg);
char *enc = gcrypt_encrypt_msg(msg, msglen + 1, &length_enc);
if (!enc){
fprintf(stderr, "sendto() error: not enough memory\n");
dawnlog_error("sendto() error: not enough memory\n");
pthread_mutex_unlock(&send_mutex);
exit(EXIT_FAILURE);
}
@ -164,7 +160,8 @@ int send_string_enc(char *msg) {
char *base64_enc_str = dawn_malloc(B64_ENCODE_LEN(length_enc));
if (!base64_enc_str){
dawn_free(enc);
fprintf(stderr, "sendto() error: not enough memory\n");
enc = NULL;
dawnlog_error("sendto() error: not enough memory\n");
pthread_mutex_unlock(&send_mutex);
exit(EXIT_FAILURE);
}
@ -176,12 +173,14 @@ int send_string_enc(char *msg) {
0,
(struct sockaddr *) &addr,
sizeof(addr)) < 0) {
perror("sendto()");
dawnlog_perror("sendto()");
pthread_mutex_unlock(&send_mutex);
exit(EXIT_FAILURE);
}
dawn_free(base64_enc_str);
base64_enc_str = NULL;
dawn_free(enc);
enc = NULL;
pthread_mutex_unlock(&send_mutex);
return 0;
}

View file

@ -40,26 +40,32 @@ struct client {
static void client_close(struct ustream *s) {
dawnlog_debug_func("Entering...");
struct client *cl = container_of(s, struct client, s.stream);
fprintf(stderr, "Connection closed\n");
dawnlog_warning("Connection closed\n");
ustream_free(s);
dawn_unregmem(s);
close(cl->s.fd.fd);
dawn_free(cl);
cl = NULL;
}
static void client_notify_write(struct ustream *s, int bytes) {
return;
}
static void client_notify_state(struct ustream *s) {
struct client *cl = container_of(s,
struct client, s.stream);
// FIXME: This void function tries to return a value sometimes...
static void client_notify_state(struct ustream *s) {
dawnlog_debug_func("Entering...");
struct client *cl = container_of(s, struct client, s.stream);
if (!s->eof)
return;
fprintf(stderr, "eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
dawnlog_error("eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
if (!s->w.data_bytes)
return client_close(s);
@ -67,23 +73,29 @@ static void client_notify_state(struct ustream *s) {
}
static void client_to_server_close(struct ustream *s) {
struct network_con_s *con = container_of(s,
struct network_con_s, stream.stream);
struct network_con_s *con = container_of(s, struct network_con_s, stream.stream);
fprintf(stderr, "Connection to server closed\n");
dawnlog_debug_func("Entering...");
dawnlog_warning("Connection to server closed\n");
ustream_free(s);
dawn_unregmem(s);
close(con->fd.fd);
list_del(&con->list);
dawn_free(con);
con = NULL;
}
static void client_to_server_state(struct ustream *s) {
struct client *cl = container_of(s, struct client, s.stream);
dawnlog_debug_func("Entering...");
if (!s->eof)
return;
fprintf(stderr, "eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
dawnlog_error("eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
if (!s->w.data_bytes)
return client_to_server_close(s);
@ -93,18 +105,22 @@ static void client_to_server_state(struct ustream *s) {
static void client_read_cb(struct ustream *s, int bytes) {
struct client *cl = container_of(s, struct client, s.stream);
dawnlog_debug_func("Entering...");
while(1) {
if (cl->state == READ_STATUS_READY)
{
dawnlog_debug("tcp_socket: commencing message...\n");
cl->str = dawn_malloc(HEADER_SIZE);
if (!cl->str) {
fprintf(stderr,"not enough memory (" STR_QUOTE(__LINE__) ")\n");
dawnlog_error("not enough memory (" STR_QUOTE(__LINE__) ")\n");
break;
}
uint32_t avail_len = ustream_pending_data(s, false);
if (avail_len < HEADER_SIZE){//ensure recv sizeof(uint32_t)
dawnlog_debug("not complete msg, len:%d\n", avail_len);
dawn_free(cl->str);
cl->str = NULL;
break;
@ -112,7 +128,7 @@ static void client_read_cb(struct ustream *s, int bytes) {
if (ustream_read(s, cl->str, HEADER_SIZE) != HEADER_SIZE) // read msg length bytes
{
fprintf(stdout,"msg length read failed\n");
dawnlog_error("msg length read failed\n");
dawn_free(cl->str);
cl->str = NULL;
break;
@ -125,7 +141,7 @@ static void client_read_cb(struct ustream *s, int bytes) {
// remains valid and may need to be deallocated.
char *str_tmp = dawn_realloc(cl->str, cl->final_len);
if (!str_tmp) {
fprintf(stderr,"not enough memory (%" PRIu32 " @ " STR_QUOTE(__LINE__) ")\n", cl->final_len);
dawnlog_error("not enough memory (%" PRIu32 " @ " STR_QUOTE(__LINE__) ")\n", cl->final_len);
dawn_free(cl->str);
cl->str = NULL;
break;
@ -138,6 +154,7 @@ static void client_read_cb(struct ustream *s, int bytes) {
if (cl->state == READ_STATUS_COMMENCED)
{
dawnlog_debug("tcp_socket: reading message...\n");
uint32_t read_len = ustream_pending_data(s, false);
if (read_len == 0)
@ -146,29 +163,33 @@ static void client_read_cb(struct ustream *s, int bytes) {
if (read_len > (cl->final_len - cl->curr_len))
read_len = cl->final_len - cl->curr_len;
dawnlog_debug("tcp_socket: reading %" PRIu32 " bytes to add to %" PRIu32 " of %" PRIu32 "...\n",
read_len, cl->curr_len, cl->final_len);
uint32_t this_read = ustream_read(s, cl->str + cl->curr_len, read_len);
cl->curr_len += this_read;
dawnlog_debug("tcp_socket: ...and we're back, now have %" PRIu32 " bytes\n", cl->curr_len);
if (cl->curr_len == cl->final_len){//ensure recv final_len bytes.
// Full message now received
cl->state = READ_STATUS_COMPLETE;
dawnlog_debug("tcp_socket: message completed\n");
}
}
if (cl->state == READ_STATUS_COMPLETE)
{
#ifndef DAWN_NO_OUTPUT
printf("tcp_socket: processing message...\n");
#endif
dawnlog_debug("tcp_socket: processing message...\n");
if (network_config.use_symm_enc) {
char *dec = gcrypt_decrypt_msg(cl->str + HEADER_SIZE, cl->final_len - HEADER_SIZE);//len of str is final_len
if (!dec) {
fprintf(stderr,"not enough memory (" STR_QUOTE(__LINE__) ")\n");
dawnlog_error("not enough memory (" STR_QUOTE(__LINE__) ")\n");
dawn_free(cl->str);
cl->str = NULL;
break;
}
handle_network_msg(dec);
dawn_free(dec);
dec = NULL;
} else {
handle_network_msg(cl->str + HEADER_SIZE);//len of str is final_len
}
@ -181,6 +202,7 @@ static void client_read_cb(struct ustream *s, int bytes) {
}
}
dawnlog_debug("tcp_socket: leaving\n");
return;
}
@ -189,6 +211,8 @@ static void server_cb(struct uloop_fd *fd, unsigned int events) {
unsigned int sl = sizeof(struct sockaddr_in);
int sfd;
dawnlog_debug_func("Entering...");
if (!next_client)
next_client = dawn_calloc(1, sizeof(*next_client));
@ -196,7 +220,7 @@ static void server_cb(struct uloop_fd *fd, unsigned int events) {
sfd = accept(server.fd, (struct sockaddr *) &cl->sin, &sl);
if (sfd < 0) {
fprintf(stderr, "Accept failed\n");
dawnlog_error("Accept failed\n");
return;
}
@ -205,18 +229,20 @@ static void server_cb(struct uloop_fd *fd, unsigned int events) {
cl->s.stream.notify_state = client_notify_state;
cl->s.stream.notify_write = client_notify_write;
ustream_fd_init(&cl->s, sfd);
dawn_regmem(&cl->s);
next_client = NULL; // TODO: Why is this here? To avoid resetting if above return happens?
fprintf(stderr, "New connection\n");
dawnlog_info("New connection\n");
}
int run_server(int port) {
dawnlog_debug("Adding socket!\n");
char port_str[12];
sprintf(port_str, "%d", port);
sprintf(port_str, "%d", port); // TODO: Manage buffer length
server.cb = server_cb;
server.fd = usock(USOCK_TCP | USOCK_SERVER | USOCK_IPV4ONLY | USOCK_NUMERIC, INADDR_ANY, port_str);
if (server.fd < 0) {
perror("usock");
dawnlog_perror("usock");
return 1;
}
@ -229,36 +255,47 @@ static void client_not_be_used_read_cb(struct ustream *s, int bytes) {
int len;
char buf[2048];
dawnlog_debug_func("Entering...");
len = ustream_read(s, buf, sizeof(buf));
buf[len] = '\0';
dawnlog_debug("Read %d bytes from SSL connection: %s\n", len, buf);
}
static void connect_cb(struct uloop_fd *f, unsigned int events) {
struct network_con_s *entry = container_of(f, struct network_con_s, fd);
dawnlog_debug_func("Entering...");
if (f->eof || f->error) {
fprintf(stderr, "Connection failed (%s)\n", f->eof ? "EOF" : "ERROR");
dawnlog_error("Connection failed (%s)\n", f->eof ? "EOF" : "ERROR");
close(entry->fd.fd);
list_del(&entry->list);
dawn_free(entry);
entry = NULL;
return;
}
dawnlog_debug("Connection established\n");
uloop_fd_delete(&entry->fd);
entry->stream.stream.notify_read = client_not_be_used_read_cb;
entry->stream.stream.notify_state = client_to_server_state;
ustream_fd_init(&entry->stream, entry->fd.fd);
dawn_regmem(&entry->stream);
entry->connected = 1;
}
int add_tcp_conncection(char *ipv4, int port) {
int add_tcp_connection(char *ipv4, int port) {
struct sockaddr_in serv_addr;
dawnlog_debug_func("Entering...");
char port_str[12];
sprintf(port_str, "%d", port);
sprintf(port_str, "%d", port); // TODO: Manage buffer length
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
@ -274,7 +311,8 @@ int add_tcp_conncection(char *ipv4, int port) {
// Delete already existing entry
close(tmp->fd.fd);
list_del(&tmp->list);
// TODO: Removed free(tmp) here - was it needed?
dawn_free(tmp);
tmp = NULL;
}
}
@ -284,25 +322,31 @@ int add_tcp_conncection(char *ipv4, int port) {
if (tcp_entry->fd.fd < 0) {
dawn_free(tcp_entry);
tcp_entry = NULL;
return -1;
}
tcp_entry->fd.cb = connect_cb;
uloop_fd_add(&tcp_entry->fd, ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
dawnlog_debug("New TCP connection to %s:%d\n", ipv4, port);
list_add(&tcp_entry->list, &tcp_sock_list);
return 0;
}
void send_tcp(char *msg) {
print_tcp_array();
dawnlog_debug_func("Entering...");
if (dawnlog_showing(DAWNLOG_DEBUG))
print_tcp_array();
struct network_con_s *con, *tmp;
if (network_config.use_symm_enc) {
int length_enc;
size_t msglen = strlen(msg)+1;
char *enc = gcrypt_encrypt_msg(msg, msglen, &length_enc);
if (!enc){
fprintf(stderr, "Ustream error: not enought memory (" STR_QUOTE(__LINE__) ")\n");
dawnlog_error("Ustream error: not enough memory (" STR_QUOTE(__LINE__) ")\n");
return;
}
@ -310,7 +354,8 @@ void send_tcp(char *msg) {
char *final_str = dawn_malloc(final_len);
if (!final_str){
dawn_free(enc);
fprintf(stderr, "Ustream error: not enought memory (" STR_QUOTE(__LINE__) ")\n");
enc = NULL;
dawnlog_error("Ustream error: not enough memory (" STR_QUOTE(__LINE__) ")\n");
return;
}
uint32_t *msg_header = (uint32_t *)final_str;
@ -320,14 +365,17 @@ void send_tcp(char *msg) {
{
if (con->connected) {
int len_ustream = ustream_write(&con->stream.stream, final_str, final_len, 0);
dawnlog_debug("Ustream send: %d\n", len_ustream);
if (len_ustream <= 0) {
fprintf(stderr,"Ustream error(" STR_QUOTE(__LINE__) ")!\n");
dawnlog_error("Ustream error(" STR_QUOTE(__LINE__) ")!\n");
//ERROR HANDLING!
if (con->stream.stream.write_error) {
ustream_free(&con->stream.stream);
dawn_unregmem(&con->stream.stream);
close(con->fd.fd);
list_del(&con->list);
dawn_free(con);
con = NULL;
}
}
}
@ -335,13 +383,15 @@ void send_tcp(char *msg) {
}
dawn_free(final_str);
final_str = NULL;
dawn_free(enc);
enc = NULL;
} else {
size_t msglen = strlen(msg) + 1;
uint32_t final_len = msglen + sizeof(final_len);
char *final_str = dawn_malloc(final_len);
if (!final_str){
fprintf(stderr, "Ustream error: not enought memory (" STR_QUOTE(__LINE__) ")\n");
dawnlog_error("Ustream error: not enough memory (" STR_QUOTE(__LINE__) ")\n");
return;
}
uint32_t *msg_header = (uint32_t *)final_str;
@ -352,25 +402,31 @@ void send_tcp(char *msg) {
{
if (con->connected) {
int len_ustream = ustream_write(&con->stream.stream, final_str, final_len, 0);
dawnlog_debug("Ustream send: %d\n", len_ustream);
if (len_ustream <= 0) {
//ERROR HANDLING!
fprintf(stderr,"Ustream error(" STR_QUOTE(__LINE__) ")!\n");
dawnlog_error("Ustream error(" STR_QUOTE(__LINE__) ")!\n");
if (con->stream.stream.write_error) {
ustream_free(&con->stream.stream);
dawn_unregmem(&con->stream.stream);
close(con->fd.fd);
list_del(&con->list);
dawn_free(con);
con = NULL;
}
}
}
}
dawn_free(final_str);
final_str = NULL;
}
}
struct network_con_s* tcp_list_contains_address(struct sockaddr_in entry) {
struct network_con_s *con;
dawnlog_debug_func("Entering...");
list_for_each_entry(con, &tcp_sock_list, list)
{
if(entry.sin_addr.s_addr == con->sock_addr.sin_addr.s_addr)
@ -382,14 +438,11 @@ struct network_con_s* tcp_list_contains_address(struct sockaddr_in entry) {
}
void print_tcp_array() {
#ifndef DAWN_NO_OUTPUT
struct network_con_s *con;
printf("--------Connections------\n");
dawnlog_debug("--------Connections------\n");
list_for_each_entry(con, &tcp_sock_list, list)
{
printf("Connecting to Port: %d, Connected: %s\n", ntohs(con->sock_addr.sin_port), con->connected ? "True" : "False");
dawnlog_debug("Connecting to Port: %d, Connected: %s\n", ntohs(con->sock_addr.sin_port), con->connected ? "True" : "False");
}
printf("------------------\n");
#endif
dawnlog_debug("------------------\n");
}

File diff suppressed because it is too large Load diff

View file

@ -438,7 +438,8 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
{
args_required = 1;
strcpy((char *)0x01, "oooops");
char *badpointer = 0;
*badpointer = 0;
}
else if (strcmp(*argv, "memaudit") == 0)
{
@ -502,7 +503,8 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
{
args_required = 1;
print_probe_array();
if (dawnlog_showing(DAWNLOG_INFO))
print_probe_array();
}
else if (strcmp(*argv, "client_show") == 0)
{
@ -514,11 +516,11 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
{
args_required = 1;
printf("--------APs------\n");
dawnlog_info("--------APs------\n");
for (auth_entry *i = denied_req_set; i != NULL; i = i->next_auth) {
print_auth_entry(i);
print_auth_entry(DAWNLOG_INFO, i);
}
printf("------------------\n");
dawnlog_info("------------------\n");
}
else if (strcmp(*argv, "ap_add_auto") == 0)
{
@ -902,11 +904,9 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
else if (!strncmp(fn, "vht_cap=", 8)) load_u8(&pr0->vht_capabilities, fn + 8);
else if (!strncmp(fn, "time=", 5)) load_time(&pr0->time, fn + 5);
else if (!strncmp(fn, "counter=", 8)) load_int(&pr0->counter, fn + 8);
#ifndef DAWN_NO_OUTPUT
else if (!strncmp(fn, "deny=", 5)) load_int(&pr0->deny_counter, fn + 5);
else if (!strncmp(fn, "max_rate=", 9)) load_u8(&pr0->max_supp_datarate, fn + 9);
else if (!strncmp(fn, "min_rate=", 9)) load_u8(&pr0->min_supp_datarate, fn + 9);
#endif
else if (!strncmp(fn, "rcpi=", 5)) load_u32(&pr0->rcpi, fn + 5);
else if (!strncmp(fn, "rsni=", 5)) load_u32(&pr0->rsni, fn + 5);
else {
@ -945,11 +945,9 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
pr0->vht_capabilities = 0;
pr0->time = faketime;
pr0->counter = 0;
#ifndef DAWN_NO_OUTPUT
pr0->deny_counter = 0;
pr0->max_supp_datarate = 0;
pr0->min_supp_datarate = 0;
#endif
pr0->rcpi = 0;
pr0->rsni = 0;
@ -1081,6 +1079,9 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
ap* ap_entry = ap_array_get_ap(pr0->bssid_addr, NULL);
int this_metric = eval_probe_metric(pr0, ap_entry);
dawnlog_info("Score: %d of:\n", this_metric);
print_probe_entry(DAWNLOG_DEBUG, pr0);
printf("eval_probe_metric: Returned %d\n", this_metric);
}
@ -1193,6 +1194,8 @@ int main(int argc, char* argv[])
int ret = 0;
int harness_verbosity = 1;
dawnlog_dest(DAWNLOG_DEST_STDIO); // Send messages to stderr / stdout
printf("DAWN datastorage.c test harness...\n\n");
if ((argc == 1) || !strcmp(*(argv + 1), "help") || !strcmp(*(argv + 1), "--help") || !strcmp(*(argv + 1), "-h"))

View file

@ -24,16 +24,11 @@ int get_bandwidth(const char *ifname, struct dawn_mac client_addr, float *rx_rat
int compare_essid_iwinfo(struct dawn_mac bssid_addr, struct dawn_mac bssid_addr_to_compare) {
const struct iwinfo_ops *iw;
char mac_buf[20];
char mac_buf_to_compare[20];
sprintf(mac_buf, MACSTR, MAC2STR(bssid_addr.u8));
sprintf(mac_buf_to_compare, MACSTR, MAC2STR(bssid_addr_to_compare.u8));
DIR *dirp;
struct dirent *entry;
dirp = opendir(hostapd_dir_glob); // error handling?
if (!dirp) {
fprintf(stderr, "[COMPARE ESSID] Failed to open %s\n", hostapd_dir_glob);
dawnlog_error("[COMPARE ESSID] Failed to open %s\n", hostapd_dir_glob);
return 0;
}
@ -50,11 +45,15 @@ int compare_essid_iwinfo(struct dawn_mac bssid_addr, struct dawn_mac bssid_addr_
iw = iwinfo_backend(entry->d_name);
// FIXME: Try to reduce string conversion and comparison here by using byte array compares
// TODO: Magic number
static char buf_bssid[18] = {0};
if (iw->bssid(entry->d_name, buf_bssid))
snprintf(buf_bssid, sizeof(buf_bssid), "00:00:00:00:00:00");
char mac_buf[20];
sprintf(mac_buf, MACSTR, MAC2STR(bssid_addr.u8));
if (strcmp(mac_buf, buf_bssid) == 0) {
if (iw->ssid(entry->d_name, buf_essid))
@ -62,6 +61,9 @@ int compare_essid_iwinfo(struct dawn_mac bssid_addr, struct dawn_mac bssid_addr_
essid = buf_essid;
}
char mac_buf_to_compare[20];
sprintf(mac_buf_to_compare, MACSTR, MAC2STR(bssid_addr_to_compare.u8));
if (strcmp(mac_buf_to_compare, buf_bssid) == 0) {
if (iw->ssid(entry->d_name, buf_essid_to_compare))
memset(buf_essid_to_compare, 0, sizeof(buf_essid_to_compare));
@ -72,6 +74,8 @@ int compare_essid_iwinfo(struct dawn_mac bssid_addr, struct dawn_mac bssid_addr_
}
closedir(dirp);
dawnlog_debug("Comparing: %s with %s\n", essid, essid_to_compare);
if (essid == NULL || essid_to_compare == NULL) {
return -1;
}
@ -89,18 +93,20 @@ int get_bandwidth_iwinfo(struct dawn_mac client_addr, float *rx_rate, float *tx_
struct dirent *entry;
dirp = opendir(hostapd_dir_glob); // error handling?
if (!dirp) {
fprintf(stderr, "[BANDWIDTH INFO] Failed to open %s\n", hostapd_dir_glob);
dawnlog_error("[BANDWIDTH INFO] Failed to open %s\n", hostapd_dir_glob);
return 0;
}
else
{
dawnlog_debug("[BANDWIDTH INFO] Opened %s\n", hostapd_dir_glob);
}
int sucess = 0;
while ((entry = readdir(dirp)) != NULL) {
while (!sucess && ((entry = readdir(dirp)) != NULL)) {
if (entry->d_type == DT_SOCK) {
if (get_bandwidth(entry->d_name, client_addr, rx_rate, tx_rate)) {
sucess = 1;
break;
}
dawnlog_debug("[BANDWIDTH INFO] Trying %s\n", entry->d_name);
sucess = get_bandwidth(entry->d_name, client_addr, rx_rate, tx_rate);
}
}
closedir(dirp);
@ -108,35 +114,34 @@ int get_bandwidth_iwinfo(struct dawn_mac client_addr, float *rx_rate, float *tx_
}
int get_bandwidth(const char *ifname, struct dawn_mac client_addr, float *rx_rate, float *tx_rate) {
int ret = 0;
int i, len;
char buf[IWINFO_BUFSIZE];
struct iwinfo_assoclist_entry *e;
const struct iwinfo_ops *iw;
if (strcmp(ifname, "global") == 0)
return 0;
iw = iwinfo_backend(ifname);
if (strcmp(ifname, "global") != 0)
{
const struct iwinfo_ops* iw = iwinfo_backend(ifname);
if (iw->assoclist(ifname, buf, &len)) {
iwinfo_finish();
return 0;
} else if (len <= 0) {
iwinfo_finish();
return 0;
}
char buf[IWINFO_BUFSIZE];
int len;
if (iw->assoclist(ifname, buf, &len) == 0 && len > 0)
{
struct iwinfo_assoclist_entry* e = (struct iwinfo_assoclist_entry*)buf;
for (int i = 0; ret == 0 && i < len; i += sizeof(struct iwinfo_assoclist_entry)) {
for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) {
e = (struct iwinfo_assoclist_entry *) &buf[i];
if (mac_is_equal(client_addr.u8, e->mac)) {
*rx_rate = e->rx_rate.rate / 1000.0;
*tx_rate = e->tx_rate.rate / 1000.0;
if (mac_is_equal(client_addr.u8, e->mac)) {
*rx_rate = e->rx_rate.rate / 1000;
*tx_rate = e->tx_rate.rate / 1000;
iwinfo_finish();
return 1;
ret = 1;
}
e++;
}
}
iwinfo_finish();
}
iwinfo_finish();
return 0;
return ret;
}
int get_rssi_iwinfo(struct dawn_mac client_addr) {
@ -145,7 +150,7 @@ int get_rssi_iwinfo(struct dawn_mac client_addr) {
struct dirent *entry;
dirp = opendir(hostapd_dir_glob); // error handling?
if (!dirp) {
fprintf(stderr, "[RSSI INFO] No hostapd sockets!\n");
dawnlog_error("[RSSI INFO] No hostapd sockets!\n");
return INT_MIN;
}
@ -173,15 +178,11 @@ int get_rssi(const char *ifname, struct dawn_mac client_addr) {
iw = iwinfo_backend(ifname);
if (iw->assoclist(ifname, buf, &len)) {
#ifndef DAWN_NO_OUTPUT
fprintf(stdout, "No information available\n");
#endif
dawnlog_warning("No information available\n");
iwinfo_finish();
return INT_MIN;
} else if (len <= 0) {
#ifndef DAWN_NO_OUTPUT
fprintf(stdout, "No station connected\n");
#endif
dawnlog_warning("No station connected\n");
iwinfo_finish();
return INT_MIN;
}
@ -205,7 +206,7 @@ int get_expected_throughput_iwinfo(struct dawn_mac client_addr) {
struct dirent *entry;
dirp = opendir(hostapd_dir_glob); // error handling?
if (!dirp) {
fprintf(stderr, "[RSSI INFO] Failed to open dir:%s\n", hostapd_dir_glob);
dawnlog_error("[RSSI INFO] Failed to open dir:%s\n", hostapd_dir_glob);
return INT_MIN;
}
@ -233,15 +234,11 @@ int get_expected_throughput(const char *ifname, struct dawn_mac client_addr) {
iw = iwinfo_backend(ifname);
if (iw->assoclist(ifname, buf, &len)) {
#ifndef DAWN_NO_OUTPUT
fprintf(stdout, "No information available\n");
#endif
dawnlog_warning("No information available\n");
iwinfo_finish();
return INT_MIN;
} else if (len <= 0) {
#ifndef DAWN_NO_OUTPUT
fprintf(stdout, "No station connected\n");
#endif
dawnlog_warning("No station connected\n");
iwinfo_finish();
return INT_MIN;
}
@ -310,13 +307,13 @@ int get_channel_utilization(const char *ifname, uint64_t *last_channel_time, uin
if (iw->survey(ifname, buf, &len))
{
fprintf(stderr, "Survey not possible!\n\n");
dawnlog_warning("Survey not possible!\n");
iwinfo_finish();
return 0;
}
else if (len <= 0)
{
fprintf(stderr, "No survey results\n\n");
dawnlog_warning("No survey results\n");
iwinfo_finish();
return 0;
}
@ -352,6 +349,7 @@ int support_ht(const char *ifname) {
if (iw->htmodelist(ifname, &htmodes))
{
dawnlog_debug("No HT mode information available\n");
iwinfo_finish();
return 0;
}
@ -371,6 +369,7 @@ int support_vht(const char *ifname) {
if (iw->htmodelist(ifname, &htmodes))
{
dawnlog_error("No VHT mode information available\n");
iwinfo_finish();
return 0;
}

View file

@ -25,6 +25,8 @@ static void set_if_present_int(int *ret, struct uci_section *s, const char* opti
void uci_get_hostname(char* hostname)
{
dawnlog_debug_func("Entering...");
char path[]= "system.@system[0].hostname";
struct uci_ptr ptr;
struct uci_context *c = uci_alloc_context();
@ -80,6 +82,8 @@ struct time_config_s uci_get_time_config() {
.update_beacon_reports = 20,
};
dawnlog_debug_func("Entering...");
struct uci_element *e;
uci_foreach_element(&uci_pkg->sections, e)
{
@ -102,6 +106,43 @@ struct time_config_s uci_get_time_config() {
return ret;
}
struct local_config_s uci_get_local_config() {
struct local_config_s ret = {
.loglevel = 0,
};
dawnlog_debug_func("Entering...");
struct uci_element* e;
uci_foreach_element(&uci_pkg->sections, e)
{
struct uci_section* s = uci_to_section(e);
if (strcmp(s->type, "local") == 0) {
DAWN_SET_CONFIG_INT(ret, s, loglevel);
}
}
switch (ret.loglevel)
{
case 3:
dawnlog_minlevel(DAWNLOG_DEBUG);
break;
case 2:
dawnlog_minlevel(DAWNLOG_TRACE);
break;
case 1:
dawnlog_minlevel(DAWNLOG_INFO);
break;
case 0:
default:
dawnlog_minlevel(DAWNLOG_ALWAYS);
break;
}
return ret;
}
static int get_rrm_mode_val(char mode) {
switch (tolower(mode)) {
@ -123,6 +164,8 @@ static int parse_rrm_mode(int *rrm_mode_order, const char *mode_string) {
int len, mode_val;
int mask = 0, order = 0, pos = 0;
dawnlog_debug_func("Entering...");
if (!mode_string)
mode_string = DEFAULT_RRM_MODE_ORDER;
len = strlen(mode_string);
@ -141,16 +184,19 @@ static int parse_rrm_mode(int *rrm_mode_order, const char *mode_string) {
static struct mac_entry_s *insert_neighbor_mac(struct mac_entry_s *head, const char* mac) {
struct mac_entry_s *new;
dawnlog_debug_func("Entering...");
if (!(new = dawn_malloc(sizeof (struct mac_entry_s)))) {
fprintf(stderr, "Warning: Failed to create neighbor entry for '%s'\n", mac);
struct mac_entry_s *new = dawn_malloc(sizeof(struct mac_entry_s));
if (new == NULL) {
dawnlog_error("Failed to allocate neighbor entry for '%s'\n", mac);
return head;
}
memset(new, 0, sizeof (struct mac_entry_s));
if (hwaddr_aton(mac, new->mac.u8) != 0) {
fprintf(stderr, "Warning: Failed to parse MAC from '%s'\n", mac);
dawnlog_error("Failed to parse MAC from '%s'\n", mac);
dawn_free(new);
new = NULL;
return head;
}
new->next_mac = head;
@ -159,17 +205,22 @@ static struct mac_entry_s *insert_neighbor_mac(struct mac_entry_s *head, const c
static void free_neighbor_mac_list(struct mac_entry_s *list) {
struct mac_entry_s *ptr = list;
dawnlog_debug_func("Entering...");
while (list) {
ptr = list;
list = list->next_mac;
dawn_free(ptr);
ptr = NULL;
}
}
static struct mac_entry_s* uci_lookup_mac_list(struct uci_option *o) {
struct uci_element *e;
struct uci_element *e = NULL;
struct mac_entry_s *head = NULL;
char *str;
char* str = NULL;
dawnlog_debug_func("Entering...");
if (o == NULL)
return NULL;
@ -196,6 +247,8 @@ static struct uci_section *uci_find_metric_section(const char *name) {
struct uci_section *s;
struct uci_element *e;
dawnlog_debug_func("Entering...");
uci_foreach_element(&uci_pkg->sections, e) {
s = uci_to_section(e);
if (strcmp(s->type, "metric") == 0 &&
@ -255,15 +308,18 @@ struct probe_metric_s uci_get_dawn_metric() {
struct uci_section *global_s, *band_s[__DAWN_BAND_MAX];
struct uci_option *global_neighbors = NULL, *neighbors;
if (!(global_s = uci_find_metric_section("global"))) {
if (!(global_s = uci_find_metric_section(NULL))) {
fprintf(stderr, "Warning: config metric global section not found! Using defaults.\n");
} else {
fprintf(stderr, "Warning: config metric global section not found. "
"Using first unnamed config metric.\n"
"Consider naming a 'global' metric section to avoid ambiguity.\n");
}
}
dawnlog_debug_func("Entering...");
global_s = uci_find_metric_section("global");
if (!global_s && (global_s = uci_find_metric_section(NULL)))
dawnlog_warning("config metric global section not found. "
"Using first unnamed config metric.\n"
"Consider naming a 'global' metric section to avoid ambiguity.\n");
if (!global_s)
dawnlog_warning("config metric global section not found! Using defaults.\n");
if (global_s) {
// True global configuration
DAWN_SET_CONFIG_INT(ret, global_s, kicking);
@ -286,6 +342,7 @@ struct probe_metric_s uci_get_dawn_metric() {
uci_lookup_option_string(uci_ctx, global_s, "rrm_mode"));
global_neighbors = uci_lookup_option(uci_ctx, global_s, "neighbors");
}
for (int band = 0; band < __DAWN_BAND_MAX; band++) {
band_s[band] = uci_find_metric_section(band_config_name[band]);
neighbors = band_s[band] ? uci_lookup_option(uci_ctx, band_s[band], "neighbors") : NULL;
@ -325,6 +382,8 @@ struct network_config_s uci_get_dawn_network() {
.bandwidth = -1,
};
dawnlog_debug_func("Entering...");
struct uci_element *e;
uci_foreach_element(&uci_pkg->sections, e)
{
@ -362,6 +421,8 @@ struct network_config_s uci_get_dawn_network() {
}
bool uci_get_dawn_hostapd_dir() {
dawnlog_debug_func("Entering...");
struct uci_element *e;
uci_foreach_element(&uci_pkg->sections, e)
{
@ -377,6 +438,8 @@ bool uci_get_dawn_hostapd_dir() {
}
bool uci_get_dawn_sort_order() {
dawnlog_debug_func("Entering...");
struct uci_element *e;
uci_foreach_element(&uci_pkg->sections, e)
{
@ -393,6 +456,8 @@ bool uci_get_dawn_sort_order() {
int uci_reset()
{
dawnlog_debug_func("Entering...");
struct uci_context *ctx = uci_ctx;
if (!ctx) {
@ -410,6 +475,8 @@ int uci_reset()
}
int uci_init() {
dawnlog_debug_func("Entering...");
struct uci_context *ctx = uci_ctx;
if (!ctx) {
@ -439,6 +506,8 @@ int uci_init() {
}
int uci_clear() {
dawnlog_debug_func("Entering...");
for (int band = 0; band < __DAWN_BAND_MAX; band++)
free_neighbor_mac_list(dawn_metric.neighbors[band]);
@ -456,6 +525,8 @@ int uci_clear() {
int uci_set_network(char* uci_cmd)
{
dawnlog_debug_func("Entering...");
struct uci_ptr ptr;
int ret = UCI_OK;
struct uci_context *ctx = uci_ctx;
@ -480,7 +551,7 @@ int uci_set_network(char* uci_cmd)
}
if (uci_commit(ctx, &ptr.p, 0) != UCI_OK) {
fprintf(stderr, "Failed to commit UCI cmd: %s\n", uci_cmd);
dawnlog_error("Failed to commit UCI cmd: %s\n", uci_cmd);
}
return ret;

View file

@ -48,17 +48,10 @@ int hwaddr_aton(const char* txt, uint8_t* addr) {
void write_mac_to_file(char* path, struct dawn_mac addr) {
FILE* f = fopen(path, "a");
if (f == NULL) {
fprintf(stderr, "Error opening mac file!\n");
// TODO: Should this be an exit()?
exit(1);
}
char mac_buf[20];
sprintf(mac_buf, MACSTR, MAC2STR(addr.u8));
fprintf(f, "%s\n", mac_buf);
if (f == NULL)
dawnlog_error("Error opening mac file!\n");
else
fprintf(f, MACSTR "\n", MAC2STR(addr.u8));
fclose(f);
}

View file

@ -4,6 +4,7 @@
#include <string.h>
#include <inttypes.h>
#include "utils.h"
#include "memory_utils.h"
#define DAWN_MEM_FILENAME_LEN 20
@ -54,10 +55,6 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
struct mem_list* this_log = NULL;
char type_c = '?';
// Ignore over enthusiastic effort to register a failed allocation
if (ptr == NULL)
return ret;
switch (type)
{
case DAWN_MALLOC:
@ -73,10 +70,19 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
type_c = 'X';
break;
default:
printf("mem-audit: Unexpected memory op tag!\n");
dawnlog_warning("mem-audit: Unexpected memory op tag!\n");
break;
}
// Note effort to register a failed allocation (other code probably wrong as well)
if (ptr == NULL)
{
char* xfile = strrchr(file, '/');
dawnlog_warning("mem-audit: attempting to register failed allocation (%c@%s:%d)...\n", type_c, xfile ? xfile + 1 : file, line);
return ret;
}
// Insert to linked list with ascending memory reference
struct mem_list** ipos = &mem_base;
while (*ipos != NULL && (*ipos)->ptr < ptr)
@ -84,7 +90,9 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
if (*ipos != NULL && (*ipos)->ptr == ptr)
{
printf("mem-audit: attempting to register memory already registered (%c@%s:%d)...\n", type_c, file, line);
char* xfile = strrchr(file, '/');
dawnlog_warning("mem-audit: attempted to register memory already registered (%c@%s:%d)...\n", type_c, xfile ? xfile + 1 : file, line);
}
else
{
@ -92,18 +100,19 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
if (this_log == NULL)
{
printf("mem-audit: Oh the irony! malloc() failed in dawn_memory_register()!\n");
dawnlog_error("mem-audit: Oh the irony! malloc() failed in dawn_memory_register()!\n");
}
else
{
// Just use filename - no path
char *xfile = strrchr(file, '/');
dawnlog_debug("mem-audit: registering memory (%c@%s:%d)...\n", type_c, xfile ? xfile + 1 : file, line);
this_log->next_mem = *ipos;
*ipos = this_log;
// Just use filename - no path
file = strrchr(file, '/');
if (file != NULL)
strncpy(this_log->file, file + 1, DAWN_MEM_FILENAME_LEN);
if (xfile != NULL)
strncpy(this_log->file, xfile + 1, DAWN_MEM_FILENAME_LEN);
else
strncpy(this_log->file, "?? UNKNOWN ??", DAWN_MEM_FILENAME_LEN);
@ -121,38 +130,26 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
void dawn_memory_unregister(enum dawn_memop type, char* file, int line, void* ptr)
{
struct mem_list** mem = &mem_base;
char type_c = '?';
while (*mem != NULL && (*mem)->ptr < ptr)
{
mem = &((*mem)->next_mem);
}
switch (type)
{
case DAWN_FREE:
type_c = 'F';
break;
case DAWN_MEMUNREG:
type_c = 'U';
break;
case DAWN_REALLOC:
type_c = 'R';
break;
default:
printf("mem-audit: Unexpected memory op tag!\n");
break;
}
char* xfile = strrchr(file, '/');
if (*mem != NULL && (*mem)->ptr == ptr)
{
// Just use filename - no path
dawnlog_debug("mem-audit: unregistering memory (%s:%d -> %c@%s:%d)...\n", xfile ? xfile + 1 : file, line, (*mem)->type, (*mem)->file, (*mem)->line);
struct mem_list* tmp = *mem;
*mem = tmp->next_mem;
free(tmp);
}
else
{
printf("mem-audit: Releasing (%c) memory we hadn't registered (%s:%d)...\n", type_c, file, line);
dawnlog_warning("mem-audit: Releasing memory we hadn't registered (%s:%d)...\n", xfile ? xfile + 1 : file, line);
}
return;
@ -171,10 +168,10 @@ void dawn_memory_audit()
{
size_t total = 0;
printf("mem-audit: Currently recorded allocations...\n");
dawnlog_always("mem-audit: Currently recorded allocations...\n");
for (struct mem_list* mem = mem_base; mem != NULL; mem = mem->next_mem)
{
printf("mem-audit: %8" PRIu64 "=%c - %s@%d: %zu\n", mem->ref, mem->type, mem->file, mem->line, mem->size);
dawnlog_always("mem-audit: %8" PRIu64 "=%c - %s@%d: %zu\n", mem->ref, mem->type, mem->file, mem->line, mem->size);
total += mem->size;
}
@ -185,5 +182,5 @@ size_t total = 0;
suffix = "kbytes";
}
printf("mem-audit: [End of list: %zu %s]\n", total, suffix);
dawnlog_always("mem-audit: [End of list: %zu %s]\n", total, suffix);
}

View file

@ -133,6 +133,8 @@ static int handle_uci_config(struct blob_attr* msg);
int parse_to_hostapd_notify(struct blob_attr* msg, hostapd_notify_entry* notify_req) {
struct blob_attr* tb[__HOSTAPD_NOTIFY_MAX];
dawnlog_debug_func("Entering...");
blobmsg_parse(hostapd_notify_policy, __HOSTAPD_NOTIFY_MAX, tb, blob_data(msg), blob_len(msg));
if (hwaddr_aton(blobmsg_data(tb[HOSTAPD_NOTIFY_BSSID_ADDR]), notify_req->bssid_addr.u8))
@ -147,10 +149,12 @@ int parse_to_hostapd_notify(struct blob_attr* msg, hostapd_notify_entry* notify_
probe_entry *parse_to_probe_req(struct blob_attr* msg) {
struct blob_attr* tb[__PROB_MAX];
dawnlog_debug_func("Entering...");
probe_entry* prob_req = dawn_malloc(sizeof(probe_entry));
if (prob_req == NULL)
{
fprintf(stderr, "dawn_malloc of probe_entry failed!\n");
dawnlog_error("dawn_malloc of probe_entry failed!\n");
return NULL;
}
@ -159,18 +163,21 @@ probe_entry *parse_to_probe_req(struct blob_attr* msg) {
if (hwaddr_aton(blobmsg_data(tb[PROB_BSSID_ADDR]), prob_req->bssid_addr.u8))
{
dawn_free(prob_req);
prob_req = NULL;
return NULL;
}
if (hwaddr_aton(blobmsg_data(tb[PROB_CLIENT_ADDR]), prob_req->client_addr.u8))
{
dawn_free(prob_req);
prob_req = NULL;
return NULL;
}
if (hwaddr_aton(blobmsg_data(tb[PROB_TARGET_ADDR]), prob_req->target_addr.u8))
{
dawn_free(prob_req);
prob_req = NULL;
return NULL;
}
@ -220,6 +227,8 @@ int handle_deauth_req(struct blob_attr* msg) {
hostapd_notify_entry notify_req;
parse_to_hostapd_notify(msg, &notify_req);
dawnlog_debug_func("Entering...");
pthread_mutex_lock(&client_array_mutex);
client* client_entry = client_array_get_client(notify_req.client_addr);
@ -228,11 +237,15 @@ int handle_deauth_req(struct blob_attr* msg) {
pthread_mutex_unlock(&client_array_mutex);
dawnlog_debug("[WC] Deauth: %s\n", "deauth");
return 0;
}
static int handle_set_probe(struct blob_attr* msg) {
dawnlog_debug_func("Entering...");
hostapd_notify_entry notify_req;
parse_to_hostapd_notify(msg, &notify_req);
@ -246,7 +259,10 @@ int handle_network_msg(char* msg) {
char* method;
char* data;
dawnlog_debug_func("Entering...");
blob_buf_init(&network_buf, 0);
// dawn_regmem(&network_buf);
blobmsg_add_json_from_string(&network_buf, msg);
blobmsg_parse(network_policy, __NETWORK_MAX, tb, blob_data(network_buf.head), blob_len(network_buf.head));
@ -258,18 +274,19 @@ int handle_network_msg(char* msg) {
method = blobmsg_data(tb[NETWORK_METHOD]);
data = blobmsg_data(tb[NETWORK_DATA]);
#ifndef DAWN_NO_OUTPUT
printf("Network Method new: %s : %s\n", method, msg);
#endif
dawnlog_debug("Network Method new: %s : %s\n", method, msg);
blob_buf_init(&data_buf, 0);
// dawn_regmem(&data_buf);
blobmsg_add_json_from_string(&data_buf, data);
if (!data_buf.head) {
dawnlog_warning("Data header not formed!");
return -1;
}
if (blob_len(data_buf.head) <= 0) {
dawnlog_warning("Data header invalid length!");
return -1;
}
@ -283,26 +300,24 @@ int handle_network_msg(char* msg) {
if (strncmp(method, "probe", 5) == 0) {
probe_entry *entry = parse_to_probe_req(data_buf.head);
if (entry != NULL) {
// we get the same entry back if it is added to the list
// or the one actually used if it is an update to existing
// use 802.11k values
if (entry != insert_to_array(entry, false, false, false, time(0)))
//FIXME: 802.11k parameter and comment seem to be at odds here. Historic cut / paste quirk?
if (entry != insert_to_array(entry, false, false, false, time(0))) // use 802.11k values
{
// insert found an existing entry, rather than linking in our new one
dawn_free(entry);
entry = NULL;
}
}
}
else if (strncmp(method, "clients", 5) == 0) {
parse_to_clients(data_buf.head, 0, 0);
}
else if (strncmp(method, "deauth", 5) == 0) {
#ifndef DAWN_NO_OUTPUT
printf("METHOD DEAUTH\n");
#endif
dawnlog_debug("METHOD DEAUTH\n");
handle_deauth_req(data_buf.head);
}
else if (strncmp(method, "setprobe", 5) == 0) {
#ifndef DAWN_NO_OUTPUT
printf("HANDLING SET PROBE!\n");
#endif
dawnlog_debug("HANDLING SET PROBE!\n");
handle_set_probe(data_buf.head);
}
else if (strncmp(method, "addmac", 5) == 0) {
@ -312,35 +327,39 @@ int handle_network_msg(char* msg) {
parse_add_mac_to_file(data_buf.head);
}
else if (strncmp(method, "uci", 2) == 0) {
#ifndef DAWN_NO_OUTPUT
printf("HANDLING UCI!\n");
#endif
dawnlog_debug("HANDLING UCI!\n");
handle_uci_config(data_buf.head);
}
else if (strncmp(method, "beacon-report", 12) == 0) {
// TODO: Check beacon report stuff
//printf("HANDLING BEACON REPORT NETWORK!\n");
//printf("The Method for beacon-report is: %s\n", method);
dawnlog_debug("HANDLING BEACON REPORT NETWORK!\n");
dawnlog_debug("The Method for beacon-report is: %s\n", method);
// ignore beacon reports send via network!, use probe functions for it
//probe_entry entry; // for now just stay at probe entry stuff...
//parse_to_beacon_rep(data_buf.head, &entry, true);
}
else
{
#ifndef DAWN_NO_OUTPUT
printf("No method fonud for: %s\n", method);
#endif
dawnlog_warning("No method found for: %s\n", method);
}
blob_buf_free(&data_buf);
// dawn_unregmem(&data_buf);
blob_buf_free(&network_buf);
// dawn_unregmem(&network_buf);
return 0;
}
static uint8_t
dump_rrm_data(struct blob_attr* head)
{
dawnlog_debug_func("Entering...");
if (blob_id(head) != BLOBMSG_TYPE_INT32) {
fprintf(stderr, "wrong type of rrm array.\n");
dawnlog_error("wrong type of rrm array.\n");
return 0;
}
return (uint8_t)blobmsg_get_u32(head);
@ -350,6 +369,8 @@ dump_rrm_data(struct blob_attr* head)
static void
dump_client(struct blob_attr** tb, struct dawn_mac client_addr, const char* bssid_addr, uint32_t freq, uint8_t ht_supported,
uint8_t vht_supported) {
dawnlog_debug_func("Entering...");
client *client_entry = dawn_malloc(sizeof(struct client_s));
if (client_entry == NULL)
{
@ -419,7 +440,11 @@ dump_client(struct blob_attr** tb, struct dawn_mac client_addr, const char* bssi
pthread_mutex_lock(&client_array_mutex);
// If entry was akraedy in list it won't be added, so free memorY
if (client_entry != insert_client_to_array(client_entry, time(0)))
{
dawn_free(client_entry);
client_entry = NULL;
}
pthread_mutex_unlock(&client_array_mutex);
}
@ -430,6 +455,8 @@ dump_client_table(struct blob_attr* head, int len, const char* bssid_addr, uint3
struct blobmsg_hdr* hdr;
int station_count = 0;
dawnlog_debug_func("Entering...");
__blob_for_each_attr(attr, head, len)
{
hdr = blob_data(attr);
@ -453,6 +480,8 @@ dump_client_table(struct blob_attr* head, int len, const char* bssid_addr, uint3
int parse_to_clients(struct blob_attr* msg, int do_kick, uint32_t id) {
struct blob_attr* tb[__CLIENT_TABLE_MAX];
dawnlog_debug_func("Entering...");
if (!msg) {
return -1;
}
@ -682,12 +711,14 @@ static const struct blobmsg_policy uci_times_policy[__UCI_TIMES_MAX] = {
static int handle_uci_config(struct blob_attr* msg) {
dawnlog_debug_func("Entering...");
struct blob_attr* tb[__UCI_TABLE_MAX];
blobmsg_parse(uci_table_policy, __UCI_TABLE_MAX, tb, blob_data(msg), blob_len(msg));
const char *version_string = blobmsg_get_string(tb[UCI_CONFIG_VERSION]);
if (version_string == NULL || strcmp(version_string, DAWN_CONFIG_VERSION)) {
fprintf(stderr, "Ignoring network config message with incompatible version string '%s'.\n",
dawnlog_warning("Ignoring network config message with incompatible version string '%s'.\n",
version_string ? : "");
return -1;
}
@ -768,7 +799,7 @@ static int handle_uci_config(struct blob_attr* msg) {
break;
}
if (band == __DAWN_BAND_MAX) {
fprintf(stderr, "handle_uci_config: Warning: unknown band '%s'.\n", band_name);
dawnlog_warning("handle_uci_config: unknown band '%s'.\n", band_name);
continue; // Should we write the metrics of an unknown band to the config file?
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,10 @@
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <syslog.h>
#include <stdio.h>
#include "utils.h"
@ -20,3 +25,106 @@ int string_is_greater(char *str, char *str_2) {
}
return length_1 > length_2;
}
// Size implied by https://man7.org/linux/man-pages/man3/strerror.3.html
char dawnlog_pbuf[1024] = "NOT SET";
static int _logdest = DAWNLOG_DEST_SYSLOG; // Assume daemon, logging to syslog
static int _logmin = DAWNLOG_ALWAYS; // Anything of lower priority is suppressed
void dawnlog_dest(int logdest)
{
_logdest = logdest;
}
void dawnlog_minlevel(int level)
{
// Don't allow certain prioriites to be suppressed
if (level < DAWNLOG_ALWAYS)
{
_logmin = level;
}
}
int dawnlog_showing(int level)
{
return(level >= _logmin);
}
void dawnlog(int level, const char* fmt, ...)
{
if ((level & DAWNLOG_PRIMASK) >= _logmin)
{
// Attempt to replicate what perror() does...
// dawnlog_buf is already referenced by macro expanded format string, so set it to a value
if ((level & DAWNLOG_PERROR) == DAWNLOG_PERROR)
{
strerror_r(errno, dawnlog_pbuf, 1024);
}
va_list ap;
va_start(ap, fmt);
int sl = LOG_NOTICE; // Should always be mapped to a different value
char *iotag = "default: ";
switch (level)
{
case DAWNLOG_ERROR:
sl = LOG_ERR;
iotag = "error: ";
break;
case DAWNLOG_WARNING:
sl = LOG_WARNING;
iotag = "warning: ";
break;
case DAWNLOG_ALWAYS:
sl = LOG_INFO;
iotag = "info: ";
break;
case DAWNLOG_INFO:
sl = LOG_INFO;
iotag = "info: ";
break;
case DAWNLOG_TRACE:
sl = LOG_DEBUG;
iotag = "trace: ";
break;
case DAWNLOG_DEBUG:
sl = LOG_DEBUG;
iotag = "debug: ";
break;
}
if (_logdest == DAWNLOG_DEST_SYSLOG)
{
vsyslog(sl, fmt, ap);
}
else
{
int l = strlen(fmt);
if (l)
{
FILE* f = (level == DAWNLOG_ERROR || level == DAWNLOG_WARNING) ? stderr : stdout;
fprintf(f, "%s", iotag);
vfprintf(f, fmt, ap);
// Messages created for syslog() may not have a closing newline, so add one if using stdio
if (fmt[l - 1] != '\n')
fprintf(f, "\n");
}
}
va_end(ap);
}
}
/* Return pointer to filename part of full path */
const char* dawnlog_basename(const char* file)
{
char* xfile = strrchr(file, '/');
return(xfile ? xfile + 1 : file);
}