pud: add UUID nodeId type
[olsrd.git] / lib / pud / wireformat / src / nodeIdConversion.c
1 #include <OlsrdPudWireFormat/nodeIdConversion.h>
2
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <arpa/inet.h>
6
7 /* ************************************************************************
8  * Node Information
9  * ************************************************************************ */
10
11 /**
12  Convert the nodeIdType of an OLSR message into a string.
13
14  @param ipVersion
15  The ip version (AF_INET or AF_INET6)
16  @param olsrGpsMessage
17  A pointer to the position update message.
18  @param nodeIdTypeBuffer
19  A pointer to the buffer in which the nodeIdType string representation is
20  written (the buffer needs to be at least PUD_TX_NODEIDTYPE_DIGITS bytes).
21  When NULL then the nodeIdType string is not written.
22  @param nodeIdTypeBufferSize
23  The size of the nodeIdTypeBuffer. When zero then the nodeIdType string is not
24  written.
25  */
26 void getNodeTypeStringFromOlsr(int ipVersion,
27                 PudOlsrPositionUpdate * olsrGpsMessage, char * nodeIdTypeBuffer,
28                 int nodeIdTypeBufferSize) {
29         if (unlikely(!nodeIdTypeBuffer || (nodeIdTypeBufferSize == 0))) {
30                 return;
31         }
32
33         assert(nodeIdTypeBufferSize >= PUD_TX_NODEIDTYPE_DIGITS);
34
35         /* message has NO nodeId information */
36         snprintf(&nodeIdTypeBuffer[0], nodeIdTypeBufferSize, "%u",
37                         getPositionUpdateNodeIdType(ipVersion, olsrGpsMessage));
38         return;
39 }
40
41 /**
42  Get a nodeId number (in string representation), using a certain number of
43  bytes, from the message of an OLSR message.
44
45  @param buffer
46  A pointer to the buffer that holds the nodeId
47  @param bufferSize
48  The number of bytes used by the number in the buffer
49  @param nodeIdBuffer
50  The buffer in which to place the nodeId number in string representation
51  @param nodeIdBufferSize
52  The size of the nodeIdbuffer
53
54  @return
55  A pointer to the nodeId string representation (&nodeIdBuffer[0])
56  */
57 static char *getNodeIdNumberFromOlsr(unsigned char * buffer,
58                 unsigned int bufferSize, char *nodeIdBuffer, socklen_t nodeIdBufferSize) {
59         unsigned long long val = 0;
60         unsigned int i = 0;
61
62         while (i < bufferSize) {
63                 val <<= 8;
64                 val += buffer[i];
65                 i++;
66         }
67
68         snprintf(nodeIdBuffer, nodeIdBufferSize, "%llu", val);
69         return &nodeIdBuffer[0];
70 }
71
72 /**
73  Get a nodeId hexadecimal number (in string representation), using a certain
74  number of bytes, from the message of an OLSR message.
75
76  @param buffer
77  A pointer to the buffer that holds the nodeId
78  @param bufferSize
79  The number of bytes used by the number in the buffer
80  @param nodeIdBuffer
81  The buffer in which to place the nodeId number in string representation
82  @param nodeIdBufferSize
83  The size of the nodeIdbuffer
84
85  @return
86  A pointer to the nodeId string representation (&nodeIdBuffer[0])
87  */
88 static char *getNodeIdHexNumberFromOlsr(unsigned char * buffer,
89                 unsigned int bufferSize, char *nodeIdBuffer, socklen_t nodeIdBufferSize) {
90         unsigned long long val = 0;
91         unsigned int i = 0;
92
93         while (i < bufferSize) {
94                 val <<= 8;
95                 val += buffer[i];
96                 i++;
97         }
98
99         snprintf(nodeIdBuffer, nodeIdBufferSize, "%llx", val);
100         return &nodeIdBuffer[0];
101 }
102
103 /**
104  Convert the nodeId of an OLSR message into a string.
105
106  @param ipVersion
107  The ip version (AF_INET or AF_INET6)
108  @param olsrMessage
109  A pointer to the OLSR message. Used to be able to retrieve the IP address of
110  the sender.
111  @param nodeIdStr
112  A pointer to a variable in which to store the pointer to the buffer in which
113  the nodeId string representation is written (the buffer needs to be at least
114  PUD_TX_NODEID_BUFFERSIZE bytes). Not written to when nodeIdStrBuffer or
115  nodeIdStr is NULL or when nodeIdStrBufferSize is zero. Can point to
116  nodeIdStrBuffer or straight into the olsrMessage
117  @param nodeIdStrBuffer
118  A pointer to the buffer in which the nodeId string representation can be
119  written. Not written to when nodeIdStrBuffer or nodeIdStr is NULL or when
120  nodeIdStrBufferSize is zero.
121  @param nodeIdStrBufferSize
122  The size of the nodeIdStrBuffer. When zero then nodeIdStrBuffer and nodeIdStr
123  are not written to.
124  */
125 void getNodeIdStringFromOlsr(int ipVersion, union olsr_message *olsrMessage,
126                 const char **nodeIdStr, char *nodeIdStrBuffer,
127                 unsigned int nodeIdStrBufferSize) {
128         PudOlsrPositionUpdate * olsrGpsMessage;
129         unsigned char * nodeId;
130         unsigned int nodeIdSize;
131
132         if (unlikely(!nodeIdStrBuffer || (nodeIdStrBufferSize == 0) || !nodeIdStr)) {
133                 return;
134         }
135
136         assert(nodeIdStrBufferSize >= PUD_TX_NODEID_BUFFERSIZE);
137
138         olsrGpsMessage = getOlsrMessagePayload(ipVersion, olsrMessage);
139
140         getPositionUpdateNodeId(ipVersion, olsrMessage, &nodeId, &nodeIdSize);
141
142         switch (getPositionUpdateNodeIdType(ipVersion, olsrGpsMessage)) {
143         case PUD_NODEIDTYPE_MAC: /* hardware address */
144         {
145                 assert(nodeIdSize == 6);
146
147                 snprintf(nodeIdStrBuffer, nodeIdStrBufferSize,
148                                 "%02x:%02x:%02x:%02x:%02x:%02x", nodeId[0], nodeId[1],
149                                 nodeId[2], nodeId[3], nodeId[4], nodeId[5]);
150                 *nodeIdStr = &nodeIdStrBuffer[0];
151         }
152                 break;
153
154         case PUD_NODEIDTYPE_DNS: /* DNS name */
155                 if (nodeIdSize >= nodeIdStrBufferSize) {
156                   nodeIdSize = nodeIdStrBufferSize - 1;
157                 }
158                 memcpy(nodeIdStrBuffer, nodeId, nodeIdSize);
159                 nodeIdStrBuffer[nodeIdSize] = '\0';
160                 *nodeIdStr = &nodeIdStrBuffer[0];
161                 break;
162
163         case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
164         case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
165         case PUD_NODEIDTYPE_MMSI: /* an AIS MMSI number */
166         case PUD_NODEIDTYPE_URN: /* a URN number */
167         case PUD_NODEIDTYPE_192:
168         case PUD_NODEIDTYPE_193:
169         case PUD_NODEIDTYPE_194:
170                 *nodeIdStr = getNodeIdNumberFromOlsr(nodeId, nodeIdSize,
171                                 nodeIdStrBuffer, nodeIdStrBufferSize);
172                 break;
173
174         case PUD_NODEIDTYPE_UUID: /* a UUID number */
175           *nodeIdStr = getNodeIdHexNumberFromOlsr(
176               &nodeId[0],
177               PUD_NODEIDTYPE_UUID_BYTES1,
178               &nodeIdStrBuffer[0],
179               PUD_NODEIDTYPE_UUID_CHARS1 + 1);
180           getNodeIdHexNumberFromOlsr(
181               &nodeId[PUD_NODEIDTYPE_UUID_BYTES1],
182               nodeIdSize - PUD_NODEIDTYPE_UUID_BYTES1,
183               &nodeIdStrBuffer[PUD_NODEIDTYPE_UUID_CHARS1],
184               nodeIdStrBufferSize - PUD_NODEIDTYPE_UUID_CHARS1);
185                 break;
186
187         case PUD_NODEIDTYPE_MIP: /* a MIP OID number */
188           *nodeIdStr = getNodeIdNumberFromOlsr(
189               &nodeId[0],
190               PUD_NODEIDTYPE_MIP_BYTES1,
191               &nodeIdStrBuffer[0],
192               PUD_NODEIDTYPE_MIP_CHARS1 + 1);
193           getNodeIdNumberFromOlsr(
194               &nodeId[PUD_NODEIDTYPE_MIP_BYTES1],
195               nodeIdSize - PUD_NODEIDTYPE_MIP_BYTES1,
196               &nodeIdStrBuffer[PUD_NODEIDTYPE_MIP_CHARS1],
197               nodeIdStrBufferSize - PUD_NODEIDTYPE_MIP_CHARS1);
198           break;
199
200         case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
201         case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
202         default: /* unsupported */
203         {
204                 void * addr = getOlsrMessageOriginator(ipVersion, olsrMessage);
205                 *nodeIdStr = inet_ntop(ipVersion, addr, nodeIdStrBuffer,
206                                 nodeIdStrBufferSize);
207         }
208                 break;
209         }
210
211         return;
212 }
213
214 /**
215  Convert a given MAC address to the binary/wireformat representation of it.
216
217  @param nodeIdBinary
218  a pointer to the buffer in which to store the binary/wireformat representation
219  @param mac
220  a pointer to a buffer in which the MAC address is stored (in network byte-order)
221  @return
222  - true when ok
223  - false on failure
224  */
225 bool setupNodeIdBinaryMAC(nodeIdBinaryType * nodeIdBinary, unsigned char * mac) {
226         memcpy(&nodeIdBinary->buffer.mac, mac, PUD_NODEIDTYPE_MAC_BYTES);
227         nodeIdBinary->length = PUD_NODEIDTYPE_MAC_BYTES;
228         nodeIdBinary->set = true;
229         return true;
230 }
231
232 /**
233  Convert a given unsigned long long to the binary/wireformat representation of it.
234
235  @param nodeIdBinary
236  a pointer to the buffer in which to store the binary/wireformat representation
237  @param value
238  the value to convert (in machine byte-order)
239  @param bytes
240  the number of bytes used by the value
241
242  @return
243  - true when ok
244  - false on failure
245  */
246 bool setupNodeIdBinaryLongLong(nodeIdBinaryType * nodeIdBinary,
247                 unsigned long long value, size_t bytes) {
248         unsigned long long longValue = value;
249         int i = bytes - 1;
250
251         while (i >= 0) {
252                 ((unsigned char *) &nodeIdBinary->buffer.longValue)[i] = longValue & 0xff;
253                 longValue >>= 8;
254                 i--;
255         }
256
257         assert(longValue == 0);
258
259         nodeIdBinary->length = bytes;
260         nodeIdBinary->set = true;
261         return true;
262 }
263
264 /**
265  Convert two given unsigned long longs to the binary/wireformat representation
266  of them.
267
268  @param nodeIdBinary
269  a pointer to the buffer in which to store the binary/wireformat representation
270  @param value1
271  the first value to convert (in machine byte-order)
272  @param dst1
273  A pointer where to store the conversion of value1
274  @param bytes1
275  the number of bytes used by value1
276  @param value2
277  the second value to convert (in machine byte-order)
278  @param dst2
279  A pointer where to store the conversion of value2
280  @param bytes2
281  the number of bytes used by value2
282
283  @return
284  - true when ok
285  - false on failure
286  */
287 bool setupNodeIdBinaryDoubleLongLong(nodeIdBinaryType * nodeIdBinary,
288     unsigned long long value1, unsigned char * dst1, size_t bytes1,
289     unsigned long long value2, unsigned char * dst2, size_t bytes2) {
290         unsigned long long longValue1 = value1;
291         unsigned long long longValue2 = value2;
292         int i1 = bytes1 - 1;
293         int i2 = bytes2 - 1;
294
295         while (i1 >= 0) {
296                 dst1[i1] = longValue1 & 0xff;
297                 longValue1 >>= 8;
298                 i1--;
299         }
300         assert(longValue1 == 0);
301
302         while (i2 >= 0) {
303                 dst2[i2] = longValue2 & 0xff;
304                 longValue2 >>= 8;
305                 i2--;
306         }
307         assert(longValue2 == 0);
308
309         nodeIdBinary->length = bytes1 + bytes2;
310         nodeIdBinary->set = true;
311         return true;
312 }
313
314 /**
315  Convert a given string to the binary/wireformat representation of it.
316
317  @param nodeIdBinary
318  a pointer to the buffer in which to store the binary/wireformat representation
319  @param nodeId
320  a pointer to the nodeId string
321  @param nodeIdLength
322  the length of the nodeId string
323  @return
324  - true when ok
325  - false on failure
326  */
327 bool setupNodeIdBinaryString(nodeIdBinaryType * nodeIdBinary, char * nodeId,
328                 size_t nodeIdLength) {
329         /* including trailing \0 */
330         memcpy(&nodeIdBinary->buffer.stringValue[0], &nodeId[0], nodeIdLength + 1);
331         nodeIdBinary->length = nodeIdLength + 1;
332         nodeIdBinary->set = true;
333         return true;
334 }
335
336 /**
337  Convert a given IP address to the binary/wireformat representation of it.
338
339  @param nodeIdBinary
340  a pointer to the buffer in which to store the binary/wireformat representation
341  @param ip
342  a pointer to a buffer in which the IP address is stored (in network byte-order)
343  @param ipLength
344  the number of bytes used by the IP address
345  @return
346  - true when ok
347  - false on failure
348  */
349 bool setupNodeIdBinaryIp(nodeIdBinaryType * nodeIdBinary, void * ip,
350                 size_t ipLength) {
351         memcpy(&nodeIdBinary->buffer.ip, ip, ipLength);
352         nodeIdBinary->length = ipLength;
353         nodeIdBinary->set = true;
354         return true;
355 }