FreeCalypso > hg > freecalypso-tools
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 } |