]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/smux/utils.cpp
\n added
[stg.git] / projects / stargazer / plugins / other / smux / utils.cpp
1 #include <unistd.h> // write
2
3 #include <cstring> // memset
4 #include <cerrno>
5
6 #include "stg/common.h"
7
8 #include "stg/OpenPDU.h"
9 #include "stg/ClosePDU.h"
10 #include "stg/RReqPDU.h"
11 #include "stg/ber_decoder.h"
12 #include "stg/der_encoder.h"
13
14 #include "pen.h"
15 #include "utils.h"
16
17 bool String2OI(const std::string & str, OBJECT_IDENTIFIER_t * oi)
18 {
19 size_t left = 0, pos = 0, arcPos = 0;
20 int arcs[1024];
21 pos = str.find_first_of('.', left);
22 if (pos == 0)
23     {
24     left = 1;
25     pos = str.find_first_of('.', left);
26     }
27 while (pos != std::string::npos)
28     {
29     int arc = 0;
30     if (str2x(str.substr(left, left - pos), arc))
31         {
32         return false;
33         }
34     arcs[arcPos++] = arc;
35     left = pos + 1;
36     pos = str.find_first_of('.', left);
37     }
38 if (left < str.length())
39     {
40     int arc = 0;
41     if (str2x(str.substr(left, left - pos), arc))
42         {
43         return false;
44         }
45     arcs[arcPos++] = arc;
46     }
47 OBJECT_IDENTIFIER_set_arcs(oi, arcs, sizeof(arcs[0]), arcPos);
48 return true;
49 }
50
51 std::string OI2String(OBJECT_IDENTIFIER_t * oi)
52 {
53 std::string res;
54
55 int arcs[1024];
56 int count = OBJECT_IDENTIFIER_get_arcs(oi, arcs, sizeof(arcs[0]), 1024);
57
58 if (count > 1024)
59     return "";
60
61 for (int i = 0; i < count; ++i)
62     {
63     res += ".";
64     std::string arc;
65     strprintf(&arc, "%d", arcs[i]);
66     res += arc;
67     }
68
69 return res;
70 }
71
72 bool SendOpenPDU(int fd)
73 {
74 const char * description = "Stg SMUX Plugin";
75 asn_enc_rval_t error;
76 OpenPDU_t msg;
77
78 memset(&msg, 0, sizeof(msg));
79
80 msg.present = OpenPDU_PR_simple;
81 asn_long2INTEGER(&msg.choice.simple.version, SimpleOpen__version_version_1);
82 if (!String2OI(PEN_PREFIX, &msg.choice.simple.identity))
83     {
84     printfd(__FILE__,
85             "SendOpenPDU() - failed to convert string to OBJECT_IDENTIFIER\n");
86     return false;
87     }
88 OCTET_STRING_fromString(&msg.choice.simple.description, description);
89 OCTET_STRING_fromString(&msg.choice.simple.password, "");
90
91 char buffer[1024];
92 error = der_encode_to_buffer(&asn_DEF_OpenPDU, &msg, buffer, sizeof(buffer));
93
94 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OpenPDU, &msg);
95
96 if (error.encoded == -1)
97     {
98     printfd(__FILE__, "Could not encode OpenPDU (at %s)\n",
99             error.failed_type ? error.failed_type->name : "unknown");
100     return false;
101     }
102 else
103     {
104     write(fd, buffer, error.encoded);
105     }
106 return true;
107 }
108
109 int SendClosePDU(int fd)
110 {
111 ClosePDU_t msg;
112
113 memset(&msg, 0, sizeof(msg));
114
115 asn_long2INTEGER(&msg, ClosePDU_goingDown);
116
117 char buffer[1024];
118 asn_enc_rval_t error;
119 error = der_encode_to_buffer(&asn_DEF_ClosePDU, &msg, buffer, sizeof(buffer));
120
121 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_ClosePDU, &msg);
122
123 if (error.encoded == -1)
124     {
125     printfd(__FILE__, "Could not encode ClosePDU (at %s)\n",
126             error.failed_type ? error.failed_type->name : "unknown");
127     return -1;
128     }
129 else
130     {
131     write(fd, buffer, error.encoded);
132     }
133 return 0;
134 }
135
136 int SendRReqPDU(int fd)
137 {
138 int oid[] = {1, 3, 6, 1, 4, 1, 38313, 1};
139 asn_enc_rval_t error;
140 RReqPDU_t msg;
141
142 memset(&msg, 0, sizeof(msg));
143
144 msg.priority = 0;
145 asn_long2INTEGER(&msg.operation, RReqPDU__operation_readOnly);
146 OBJECT_IDENTIFIER_set_arcs(&msg.subtree,
147                            oid,
148                            sizeof(oid[0]),
149                            8);
150
151 char buffer[1024];
152 error = der_encode_to_buffer(&asn_DEF_RReqPDU, &msg, buffer, sizeof(buffer));
153
154 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RReqPDU, &msg);
155
156 if (error.encoded == -1)
157     {
158     printfd(__FILE__, "Could not encode RReqPDU (at %s)\n",
159             error.failed_type ? error.failed_type->name : "unknown");
160     return -1;
161     }
162 else
163     {
164     write(fd, buffer, error.encoded);
165     }
166 return 0;
167 }
168
169 SMUX_PDUs_t * RecvSMUXPDUs(int fd)
170 {
171 char buffer[1024];
172 SMUX_PDUs_t * pdus = NULL;
173
174 memset(buffer, 0, sizeof(buffer));
175
176 size_t length = read(fd, buffer, sizeof(buffer));
177 if (length < 1)
178     return NULL;
179 asn_dec_rval_t error;
180 error = ber_decode(0, &asn_DEF_SMUX_PDUs, (void **)&pdus, buffer, length);
181
182 if(error.code != RC_OK)
183     {
184     printfd(__FILE__, "Failed to decode PDUs at byte %ld\n",
185             (long)error.consumed);
186     return NULL;
187     }
188 return pdus;
189 }
190
191 int SendGetResponsePDU(int fd, GetResponse_PDU_t * getResponse)
192 {
193 asn_enc_rval_t error;
194
195 char buffer[1024];
196 error = der_encode_to_buffer(&asn_DEF_GetResponse_PDU, getResponse, buffer,
197                              sizeof(buffer));
198
199 if (error.encoded == -1)
200     {
201     printfd(__FILE__, "Could not encode GetResponsePDU (at %s)\n",
202             error.failed_type ? error.failed_type->name : "unknown");
203     return -1;
204     }
205 else
206     {
207     write(fd, buffer, error.encoded);
208     }
209 return 0;
210 }
211
212 int SendGetResponseErrorPDU(int fd,
213                             const PDU_t * getRequest,
214                             int errorStatus,
215                             int errorIndex)
216 {
217 asn_enc_rval_t error;
218 GetResponse_PDU_t msg;
219
220 memset(&msg, 0, sizeof(msg));
221
222 long id = 0;
223 asn_INTEGER2long(&getRequest->request_id, &id);
224 asn_long2INTEGER(&msg.request_id, id);
225 asn_long2INTEGER(&msg.error_status, errorStatus);
226 asn_long2INTEGER(&msg.error_index, errorIndex);
227
228 char buffer[1024];
229 error = der_encode_to_buffer(&asn_DEF_GetResponse_PDU, &msg, buffer,
230                              sizeof(buffer));
231
232 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_GetResponse_PDU, &msg);
233
234 if (error.encoded == -1)
235     {
236     printfd(__FILE__, "Could not encode GetResponsePDU for error (at %s)\n",
237             error.failed_type ? error.failed_type->name : "unknown");
238     return -1;
239     }
240 else
241     {
242     write(fd, buffer, error.encoded);
243     }
244 return 0;
245 }