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