From 437bf2b8b72f9d89422447c85b93f1c62af4bab1 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Thu, 27 Jun 2013 08:28:49 +0300 Subject: [PATCH] IS2: additional deframing code --- src/aprsis2.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- src/aprsis2.h | 1 + src/uplink.c | 11 +++++++---- src/worker.c | 2 -- 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/aprsis2.c b/src/aprsis2.c index 3a29c66..8b45390 100644 --- a/src/aprsis2.c +++ b/src/aprsis2.c @@ -4,6 +4,7 @@ #include "aprsis2.h" #include "aprsis2.pb-c.h" #include "version.h" +#include "hlog.h" #define IS2_HEAD_LEN 4 #define IS2_TAIL_LEN 1 @@ -40,7 +41,54 @@ int is2_out_server_signature(struct worker_t *self, struct client_t *c) return 0; } -int is2_data_in(struct worker_t *self, struct client_t *c) +static int is2_unpack_server_signature(struct worker_t *self, struct client_t *c, void *buf, int len) { return 0; } + +#define IS2_MINIMUM_FRAME_LEN 4 + 1 + 1 +#define IS2_MINIMUM_FRAME_CONTENT_LEN 4 + +static int is2_deframe(struct worker_t *self, struct client_t *c, char *s, int len) +{ + if (len < IS2_MINIMUM_FRAME_LEN) { + hlog_packet(LOG_WARNING, s, len, "%s/%s: IS2: Too short frame wrapper (%d): ", + c->addr_rem, c->username, len); + return -1; + } + + uint32_t *ip = (uint32_t *)s; + int clen = ntohl(*ip); + + if (clen < IS2_MINIMUM_FRAME_CONTENT_LEN) { + hlog_packet(LOG_WARNING, s, len, "%s/%s: IS2: Too short frame content (%d): ", + c->addr_rem, c->username, clen); + return -1; + } + + if (IS2_HEAD_LEN + clen + IS2_TAIL_LEN > len) { + hlog_packet(LOG_WARNING, s, len, "%s/%s: IS2: Frame length points behind buffer end (%d): ", + c->addr_rem, c->username, clen); + return -1; + } + + if (s[IS2_HEAD_LEN + clen] != '\n') { + hlog_packet(LOG_WARNING, s, len, "%s/%s: IS2: Frame missing terminating LF: ", + c->addr_rem, c->username); + return -1; + } + + hlog_packet(LOG_DEBUG, s, len, "%s/%s: IS2: framing ok: ", c->addr_rem, c->username); + + is2_unpack_server_signature(self, c, s, len); + + return 0; +} + +int is2_in_server_signature(struct worker_t *self, struct client_t *c, char *s, int len) +{ + /* this one comes through the CRLF deframing */ + is2_deframe(self, c, s, len+1); + + return 0; +} diff --git a/src/aprsis2.h b/src/aprsis2.h index 136530e..59c58da 100644 --- a/src/aprsis2.h +++ b/src/aprsis2.h @@ -5,6 +5,7 @@ #include "worker.h" extern int is2_out_server_signature(struct worker_t *self, struct client_t *c); +extern int is2_in_server_signature(struct worker_t *self, struct client_t *c, char *s, int len); #endif diff --git a/src/uplink.c b/src/uplink.c index 50ba217..90522a1 100644 --- a/src/uplink.c +++ b/src/uplink.c @@ -44,6 +44,8 @@ #include "outgoing.h" #include "filter.h" #include "tls.h" +#include "aprsis2.h" + int uplink_reconfiguring; int uplink_shutting_down; @@ -297,10 +299,6 @@ int uplink_login_handler(struct worker_t *self, struct client_t *c, int l4proto, int argc; char *argv[256]; - //if (is2_in_server_signature(self, c, l4proto, s, len) - - hlog_packet(LOG_INFO, s, len, "%s: Uplink server software: ", c->addr_rem); - #ifdef USE_SSL if (c->ssl_con && c->ssl_con->validate) { hlog(LOG_DEBUG, "%s/%s: Uplink: Validating TLS server cert against CA", c->addr_rem, c->username); @@ -314,6 +312,11 @@ int uplink_login_handler(struct worker_t *self, struct client_t *c, int l4proto, } #endif + if (is2_in_server_signature(self, c, s, len)) + return 0; + + hlog_packet(LOG_INFO, s, len, "%s: Uplink server software: ", c->addr_rem); + /* parse to arguments */ /* make it null-terminated for our string processing */ char *e = s + len; diff --git a/src/worker.c b/src/worker.c index be2a5b9..c76a3fb 100644 --- a/src/worker.c +++ b/src/worker.c @@ -1285,8 +1285,6 @@ int client_postread(struct worker_t *self, struct client_t *c, int r) return 0; } - - /* * handle an event on an fd */