comparison rvinterf/libprint/gpf_tst.c @ 939:4d2e6a2dd1a1

libprint: implement libg23 replacement
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 24 May 2023 06:29:13 +0000
parents
children
comparison
equal deleted inserted replaced
938:74930218c270 939:4d2e6a2dd1a1
1 /*
2 * This libprint module (one public function plus many internal subfunctions)
3 * implements printing/formatting of GPF TST interface packets, which can be
4 * traces, sysprims, protocol stack primitives or unrecognized packet format.
5 */
6
7 #include <sys/types.h>
8 #include <ctype.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <strings.h>
13
14 static int
15 basic_checks(rxpkt, rxpkt_len)
16 u_char *rxpkt;
17 unsigned rxpkt_len;
18 {
19 int i, c;
20
21 if (rxpkt_len < 17)
22 return(0);
23 /* check version bits in the header byte */
24 if ((rxpkt[1] & 0xC0) != 0x80)
25 return(0);
26 /* check the length */
27 c = rxpkt[2] | rxpkt[3] << 8;
28 if (c + 4 != rxpkt_len)
29 return(0);
30 /* ensure that the "from" and "to" are printable ASCII */
31 for (i = 8; i < 16; i++) {
32 c = rxpkt[i];
33 if (c < ' ' || c > '~')
34 return(0);
35 }
36 /* basic checks pass */
37 return(1);
38 }
39
40 static int
41 psprim_extra_checks(rxpkt, rxpkt_len)
42 u_char *rxpkt;
43 unsigned rxpkt_len;
44 {
45 int i, c;
46
47 if (rxpkt_len < 24)
48 return(0);
49 /* "original rcvr" field needs to be printable ASCII */
50 for (i = 16; i < 20; i++) {
51 c = rxpkt[i];
52 if (c < ' ' || c > '~')
53 return(0);
54 }
55 /* checks pass */
56 return(1);
57 }
58
59 static void
60 print_malformed(rxpkt, rxpkt_len, extra_prefix, outfunc_head, outfunc_cont)
61 u_char *rxpkt;
62 unsigned rxpkt_len;
63 char *extra_prefix;
64 void (*outfunc_head)(), (*outfunc_cont)();
65 {
66 char headline[80];
67
68 sprintf(headline, "%sGPF unrecognized packet format", extra_prefix);
69 outfunc_head(headline);
70 packet_hex_dump(rxpkt, rxpkt_len, outfunc_cont);
71 }
72
73 static void
74 print_malloc_fail(rxpkt, rxpkt_len, extra_prefix, outfunc_head, outfunc_cont)
75 u_char *rxpkt;
76 unsigned rxpkt_len;
77 char *extra_prefix;
78 void (*outfunc_head)(), (*outfunc_cont)();
79 {
80 char headline[80];
81
82 sprintf(headline, "%sGPF packet, failed malloc in formatting",
83 extra_prefix);
84 outfunc_head(headline);
85 packet_hex_dump(rxpkt, rxpkt_len, outfunc_cont);
86 }
87
88 static int
89 entity_name_well_formed(p)
90 char *p;
91 {
92 int i, len;
93
94 if (!isupper(p[0]))
95 return(0);
96 for (i = 0; i < 4; i++)
97 if (!isalnum(p[i]))
98 break;
99 len = i;
100 for (; i < 4; i++)
101 if (p[i] != ' ')
102 return(0);
103 return(len);
104 }
105
106 static void
107 print_entity_name(raw, outp)
108 char *raw, **outp;
109 {
110 int len;
111
112 len = entity_name_well_formed(raw);
113 if (len) {
114 sprintf(*outp, "%.*s", len, raw);
115 *outp += len;
116 } else {
117 sprintf(*outp, "\"%.4s\"", raw);
118 *outp += 6;
119 }
120 }
121
122 static void
123 print_common_hdr(rxpkt, outp, typestr, extra_prefix)
124 u_char *rxpkt;
125 char **outp, *typestr, *extra_prefix;
126 {
127 sprintf(*outp, "%sGPF %s id=%02X ts=%02X%02X%02X%02X ", extra_prefix,
128 typestr, rxpkt[1], rxpkt[7], rxpkt[6], rxpkt[5], rxpkt[4]);
129 *outp = index(*outp, '\0');
130 print_entity_name(rxpkt + 8, outp);
131 *(*outp)++ = '-';
132 *(*outp)++ = '>';
133 print_entity_name(rxpkt + 12, outp);
134 *(*outp)++ = ' ';
135 }
136
137 static void
138 format_text(rxpkt, rxpkt_len, start_off, outp)
139 u_char *rxpkt;
140 unsigned rxpkt_len, start_off;
141 char *outp;
142 {
143 *outp++ = '\"';
144 safe_print_trace(rxpkt + start_off, rxpkt_len - start_off, outp);
145 outp = index(outp, '\0');
146 *outp++ = '\"';
147 *outp = '\0';
148 }
149
150 static void
151 format_compressed_trace(rxpkt, rxpkt_len, start_off, outp)
152 u_char *rxpkt;
153 unsigned rxpkt_len, start_off;
154 char *outp;
155 {
156 int i;
157
158 i = start_off + 1;
159 sprintf(outp, "%d", rxpkt[i+1] << 8 | rxpkt[i]);
160 outp = index(outp, '\0');
161 i += 4;
162 for (; i < rxpkt_len; i++) {
163 sprintf(outp, " %02X", rxpkt[i]);
164 outp += 3;
165 }
166 *outp = '\0';
167 }
168
169 static void
170 format_trace(rxpkt, rxpkt_len, extra_prefix, outfunc_head, outfunc_cont)
171 u_char *rxpkt;
172 unsigned rxpkt_len;
173 char *extra_prefix;
174 void (*outfunc_head)(), (*outfunc_cont)();
175 {
176 char *outbuf, *outp;
177 int i;
178
179 outbuf = malloc(rxpkt_len * 4 + strlen(extra_prefix) + 1);
180 if (!outbuf) {
181 print_malloc_fail(rxpkt, rxpkt_len, extra_prefix, outfunc_head,
182 outfunc_cont);
183 return;
184 }
185 outp = outbuf;
186 print_common_hdr(rxpkt, &outp, "trace", extra_prefix);
187 i = 16;
188 if (rxpkt[i] < 0x20) {
189 sprintf(outp, "tc=%02X ", rxpkt[i]);
190 outp += 6;
191 i++;
192 }
193 if (rxpkt_len - i >= 5 && rxpkt[i] == '%' &&
194 !rxpkt[i+3] && !rxpkt[i+4])
195 format_compressed_trace(rxpkt, rxpkt_len, i, outp);
196 else
197 format_text(rxpkt, rxpkt_len, i, outp);
198 outfunc_head(outbuf);
199 free(outbuf);
200 }
201
202 static void
203 format_sysprim(rxpkt, rxpkt_len, extra_prefix, outfunc_head, outfunc_cont)
204 u_char *rxpkt;
205 unsigned rxpkt_len;
206 char *extra_prefix;
207 void (*outfunc_head)(), (*outfunc_cont)();
208 {
209 char *outbuf, *outp;
210
211 outbuf = malloc(rxpkt_len * 4 + strlen(extra_prefix) + 1);
212 if (!outbuf) {
213 print_malloc_fail(rxpkt, rxpkt_len, extra_prefix, outfunc_head,
214 outfunc_cont);
215 return;
216 }
217 outp = outbuf;
218 print_common_hdr(rxpkt, &outp, "sysprim", extra_prefix);
219 format_text(rxpkt, rxpkt_len, 16, outp);
220 outfunc_head(outbuf);
221 free(outbuf);
222 }
223
224 static void
225 format_psprim(rxpkt, rxpkt_len, extra_prefix, outfunc_head, outfunc_cont)
226 u_char *rxpkt;
227 unsigned rxpkt_len;
228 char *extra_prefix;
229 void (*outfunc_head)(), (*outfunc_cont)();
230 {
231 char headline[80];
232 char *outp = headline;
233
234 print_common_hdr(rxpkt, &outp, "PSprim", extra_prefix);
235 /* original destination */
236 *outp++ = '(';
237 print_entity_name(rxpkt + 16, &outp);
238 *outp++ = ')';
239 /* opcode and data length */
240 sprintf(outp, " %02X%02X%02X%02X len=%u",
241 rxpkt[23], rxpkt[22], rxpkt[21], rxpkt[20], rxpkt_len - 24);
242 outfunc_head(headline);
243 packet_hex_dump(rxpkt + 24, rxpkt_len - 24, outfunc_cont);
244 }
245
246 void
247 format_gpf_packet(rxpkt, rxpkt_len, extra_prefix, outfunc_head, outfunc_cont)
248 u_char *rxpkt;
249 unsigned rxpkt_len;
250 char *extra_prefix;
251 void (*outfunc_head)(), (*outfunc_cont)();
252 {
253 if (!basic_checks(rxpkt, rxpkt_len)) {
254 print_malformed(rxpkt, rxpkt_len, extra_prefix, outfunc_head,
255 outfunc_cont);
256 return;
257 }
258 /* dispatch by type */
259 switch (rxpkt[1] & 0x30) {
260 case 0x10:
261 /* PS primitive */
262 if (psprim_extra_checks(rxpkt, rxpkt_len))
263 format_psprim(rxpkt, rxpkt_len, extra_prefix,
264 outfunc_head, outfunc_cont);
265 else
266 print_malformed(rxpkt, rxpkt_len, extra_prefix,
267 outfunc_head, outfunc_cont);
268 return;
269 case 0x20:
270 /* trace */
271 format_trace(rxpkt, rxpkt_len, extra_prefix, outfunc_head,
272 outfunc_cont);
273 return;
274 case 0x30:
275 /* system primitive */
276 format_sysprim(rxpkt, rxpkt_len, extra_prefix, outfunc_head,
277 outfunc_cont);
278 return;
279 default:
280 print_malformed(rxpkt, rxpkt_len, extra_prefix, outfunc_head,
281 outfunc_cont);
282 }
283 }