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