FreeCalypso > hg > freecalypso-sw
diff rvinterf/libg23/fmtdispatch.c @ 332:28b4d3c9e85d
rvinterf/libg23: complete for now
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Tue, 22 Apr 2014 05:03:39 +0000 |
parents | |
children | 42c91c51ca7f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rvinterf/libg23/fmtdispatch.c Tue Apr 22 05:03:39 2014 +0000 @@ -0,0 +1,103 @@ +/* + * This libg23 module exports the format_g23_packet() function, which + * validates the packet, then dispatches it to format_g23_trace(), + * format_g23_sysprim() or format_g23_psprim() as appropriate, or + * prints it in raw hex if malformed. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> + +static int +basic_checks(rxpkt, rxpkt_len) + u_char *rxpkt; +{ + int i, c; + + if (rxpkt_len < 17) + return(0); + /* check version bits in the header byte */ + if ((rxpkt[1] & 0xC0) != 0x80) + return(0); + /* check the length */ + c = rxpkt[2] | rxpkt[3] << 8; + if (c + 4 != rxpkt_len) + return(0); + /* ensure that the "from" and "to" are printable ASCII */ + for (i = 8; i < 16; i++) { + c = rxpkt[i]; + if (c < ' ' || c > '~') + return(0); + } + /* basic checks pass */ + return(1); +} + +static int +psprim_extra_checks(rxpkt, rxpkt_len) + u_char *rxpkt; +{ + int i, c; + + if (rxpkt_len < 24) + return(0); + /* "original rcvr" field needs to be printable ASCII */ + for (i = 16; i < 20; i++) { + c = rxpkt[i]; + if (c < ' ' || c > '~') + return(0); + } + /* checks pass */ + return(1); +} + +static void +print_malformed(rxpkt, rxpkt_len, outbuf) + u_char *rxpkt; + char *outbuf; +{ + int i; + char *dp; + + dp = outbuf; + strcpy(dp, "G23 UNK:"); + dp += 8; + for (i = 1; i < rxpkt_len; i++) { + sprintf(dp, " %02X", rxpkt[i]); + dp += 3; + } + *dp = '\0'; +} + +void +format_g23_packet(rxpkt, rxpkt_len, outbuf) + u_char *rxpkt; + char *outbuf; +{ + if (!basic_checks(rxpkt, rxpkt_len)) { + print_malformed(rxpkt, rxpkt_len, outbuf); + return; + } + /* dispatch by type */ + switch (rxpkt[1] & 0x30) { + case 0x10: + /* PS primitive */ + if (psprim_extra_checks(rxpkt, rxpkt_len)) + format_g23_psprim(rxpkt, rxpkt_len, outbuf); + else + print_malformed(rxpkt, rxpkt_len, outbuf); + return; + case 0x20: + /* trace */ + format_g23_trace(rxpkt, rxpkt_len, outbuf); + return; + case 0x30: + /* system primitive */ + format_g23_sysprim(rxpkt, rxpkt_len, outbuf); + return; + default: + print_malformed(rxpkt, rxpkt_len, outbuf); + } +}