comparison rvinterf/libg23/fmtdispatch.c @ 0:e7502631a0f9

initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 11 Jun 2016 00:13:35 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e7502631a0f9
1 /*
2 * This libg23 module exports the format_g23_packet() function, which
3 * validates the packet, then dispatches it to format_g23_trace(),
4 * format_g23_sysprim() or format_g23_psprim() as appropriate, or
5 * prints it in raw hex if malformed.
6 */
7
8 #include <sys/types.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <strings.h>
12
13 static int
14 basic_checks(rxpkt, rxpkt_len)
15 u_char *rxpkt;
16 {
17 int i, c;
18
19 if (rxpkt_len < 17)
20 return(0);
21 /* check version bits in the header byte */
22 if ((rxpkt[1] & 0xC0) != 0x80)
23 return(0);
24 /* check the length */
25 c = rxpkt[2] | rxpkt[3] << 8;
26 if (c + 4 != rxpkt_len)
27 return(0);
28 /* ensure that the "from" and "to" are printable ASCII */
29 for (i = 8; i < 16; i++) {
30 c = rxpkt[i];
31 if (c < ' ' || c > '~')
32 return(0);
33 }
34 /* basic checks pass */
35 return(1);
36 }
37
38 static int
39 psprim_extra_checks(rxpkt, rxpkt_len)
40 u_char *rxpkt;
41 {
42 int i, c;
43
44 if (rxpkt_len < 24)
45 return(0);
46 /* "original rcvr" field needs to be printable ASCII */
47 for (i = 16; i < 20; i++) {
48 c = rxpkt[i];
49 if (c < ' ' || c > '~')
50 return(0);
51 }
52 /* checks pass */
53 return(1);
54 }
55
56 static void
57 print_unknown_bin(rxpkt, rxpkt_len, outbuf)
58 u_char *rxpkt;
59 char *outbuf;
60 {
61 int i;
62 char *dp;
63
64 dp = outbuf;
65 strcpy(dp, "GPF UNK:");
66 dp += 8;
67 for (i = 1; i < rxpkt_len; i++) {
68 sprintf(dp, " %02X", rxpkt[i]);
69 dp += 3;
70 }
71 *dp = '\0';
72 }
73
74 static void
75 print_old_ascii(rxpkt, rxpkt_len, outbuf)
76 u_char *rxpkt;
77 char *outbuf;
78 {
79 char *dp;
80 int txtlen = rxpkt_len - 1;
81
82 dp = outbuf;
83 strcpy(dp, "GPF ASC: ");
84 dp += 9;
85 bcopy(rxpkt + 1, dp, txtlen);
86 dp += txtlen;
87 *dp = '\0';
88 }
89
90 static int
91 is_old_ascii(rxpkt, rxpkt_len)
92 u_char *rxpkt;
93 {
94 int i, c;
95
96 for (i = 1; i < rxpkt_len; i++) {
97 c = rxpkt[i];
98 if (c < ' ' || c > '~')
99 return(0);
100 }
101 return(1);
102 }
103
104 static void
105 print_malformed(rxpkt, rxpkt_len, outbuf)
106 u_char *rxpkt;
107 char *outbuf;
108 {
109 if (is_old_ascii(rxpkt, rxpkt_len))
110 print_old_ascii(rxpkt, rxpkt_len, outbuf);
111 else
112 print_unknown_bin(rxpkt, rxpkt_len, outbuf);
113 }
114
115 void
116 format_g23_packet(rxpkt, rxpkt_len, outbuf)
117 u_char *rxpkt;
118 char *outbuf;
119 {
120 if (!basic_checks(rxpkt, rxpkt_len)) {
121 print_malformed(rxpkt, rxpkt_len, outbuf);
122 return;
123 }
124 /* dispatch by type */
125 switch (rxpkt[1] & 0x30) {
126 case 0x10:
127 /* PS primitive */
128 if (psprim_extra_checks(rxpkt, rxpkt_len))
129 format_g23_psprim(rxpkt, rxpkt_len, outbuf);
130 else
131 print_malformed(rxpkt, rxpkt_len, outbuf);
132 return;
133 case 0x20:
134 /* trace */
135 format_g23_trace(rxpkt, rxpkt_len, outbuf);
136 return;
137 case 0x30:
138 /* system primitive */
139 format_g23_sysprim(rxpkt, rxpkt_len, outbuf);
140 return;
141 default:
142 print_malformed(rxpkt, rxpkt_len, outbuf);
143 }
144 }