6a17c924f64f5c5f240fa3d0db3937245278fb18
[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  Convert the nodeId of an OLSR message into a string.
74
75  @param ipVersion
76  The ip version (AF_INET or AF_INET6)
77  @param olsrMessage
78  A pointer to the OLSR message. Used to be able to retrieve the IP address of
79  the sender.
80  @param nodeIdStr
81  A pointer to a variable in which to store the pointer to the buffer in which
82  the nodeId string representation is written (the buffer needs to be at least
83  PUD_TX_NODEID_BUFFERSIZE bytes). Not written to when nodeIdStrBuffer or
84  nodeIdStr is NULL or when nodeIdStrBufferSize is zero. Can point to
85  nodeIdStrBuffer or straight into the olsrMessage
86  @param nodeIdStrBuffer
87  A pointer to the buffer in which the nodeId string representation can be
88  written. Not written to when nodeIdStrBuffer or nodeIdStr is NULL or when
89  nodeIdStrBufferSize is zero.
90  @param nodeIdStrBufferSize
91  The size of the nodeIdStrBuffer. When zero then nodeIdStrBuffer and nodeIdStr
92  are not written to.
93  */
94 void getNodeIdStringFromOlsr(int ipVersion, union olsr_message *olsrMessage,
95                 const char **nodeIdStr, char *nodeIdStrBuffer,
96                 unsigned int nodeIdStrBufferSize) {
97         PudOlsrPositionUpdate * olsrGpsMessage;
98         unsigned char * nodeId;
99         unsigned int nodeIdSize;
100
101         if (unlikely(!nodeIdStrBuffer || (nodeIdStrBufferSize == 0) || !nodeIdStr)) {
102                 return;
103         }
104
105         assert(nodeIdStrBufferSize >= PUD_TX_NODEID_BUFFERSIZE);
106
107         olsrGpsMessage = getOlsrMessagePayload(ipVersion, olsrMessage);
108
109         getPositionUpdateNodeId(ipVersion, olsrMessage, &nodeId, &nodeIdSize);
110
111         switch (getPositionUpdateNodeIdType(ipVersion, olsrGpsMessage)) {
112         case PUD_NODEIDTYPE_MAC: /* hardware address */
113         {
114                 assert(nodeIdSize == 6);
115
116                 snprintf(nodeIdStrBuffer, nodeIdStrBufferSize,
117                                 "%02x:%02x:%02x:%02x:%02x:%02x", nodeId[0], nodeId[1],
118                                 nodeId[2], nodeId[3], nodeId[4], nodeId[5]);
119                 *nodeIdStr = &nodeIdStrBuffer[0];
120         }
121                 break;
122
123         case PUD_NODEIDTYPE_DNS: /* DNS name */
124                 if (nodeIdSize >= nodeIdStrBufferSize) {
125                   nodeIdSize = nodeIdStrBufferSize - 1;
126                 }
127                 memcpy(nodeIdStrBuffer, nodeId, nodeIdSize);
128                 nodeIdStrBuffer[nodeIdSize] = '\0';
129                 *nodeIdStr = &nodeIdStrBuffer[0];
130                 break;
131
132         case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
133         case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
134         case PUD_NODEIDTYPE_MMSI: /* an AIS MMSI number */
135         case PUD_NODEIDTYPE_URN: /* a URN number */
136         case PUD_NODEIDTYPE_192:
137         case PUD_NODEIDTYPE_193:
138         case PUD_NODEIDTYPE_194:
139                 *nodeIdStr = getNodeIdNumberFromOlsr(nodeId, nodeIdSize,
140                                 nodeIdStrBuffer, nodeIdStrBufferSize);
141                 break;
142
143         case PUD_NODEIDTYPE_MIP: /* a MIP OID number */
144           *nodeIdStr = getNodeIdNumberFromOlsr(
145               &nodeId[0],
146               PUD_NODEIDTYPE_MIP_BYTES1,
147               &nodeIdStrBuffer[0],
148               PUD_NODEIDTYPE_MIP_CHARS1 + 1);
149           getNodeIdNumberFromOlsr(
150               &nodeId[PUD_NODEIDTYPE_MIP_BYTES1],
151               nodeIdSize - PUD_NODEIDTYPE_MIP_BYTES1,
152               &nodeIdStrBuffer[PUD_NODEIDTYPE_MIP_CHARS1],
153               nodeIdStrBufferSize - PUD_NODEIDTYPE_MIP_CHARS1);
154           break;
155
156         case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
157         case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
158         default: /* unsupported */
159         {
160                 void * addr = getOlsrMessageOriginator(ipVersion, olsrMessage);
161                 *nodeIdStr = inet_ntop(ipVersion, addr, nodeIdStrBuffer,
162                                 nodeIdStrBufferSize);
163         }
164                 break;
165         }
166
167         return;
168 }
169
170 /**
171  Convert a given MAC address to the binary/wireformat representation of it.
172
173  @param nodeIdBinary
174  a pointer to the buffer in which to store the binary/wireformat representation
175  @param mac
176  a pointer to a buffer in which the MAC address is stored (in network byte-order)
177  @return
178  - true when ok
179  - false on failure
180  */
181 bool setupNodeIdBinaryMAC(nodeIdBinaryType * nodeIdBinary, unsigned char * mac) {
182         memcpy(&nodeIdBinary->buffer.mac, mac, PUD_NODEIDTYPE_MAC_BYTES);
183         nodeIdBinary->length = PUD_NODEIDTYPE_MAC_BYTES;
184         nodeIdBinary->set = true;
185         return true;
186 }
187
188 /**
189  Convert a given unsigned long long to the binary/wireformat representation of it.
190
191  @param nodeIdBinary
192  a pointer to the buffer in which to store the binary/wireformat representation
193  @param value
194  the value to convert (in machine byte-order)
195  @param bytes
196  the number of bytes used by the value
197
198  @return
199  - true when ok
200  - false on failure
201  */
202 bool setupNodeIdBinaryLongLong(nodeIdBinaryType * nodeIdBinary,
203                 unsigned long long value, size_t bytes) {
204         unsigned long long longValue = value;
205         int i = bytes - 1;
206
207         while (i >= 0) {
208                 ((unsigned char *) &nodeIdBinary->buffer.longValue)[i] = longValue & 0xff;
209                 longValue >>= 8;
210                 i--;
211         }
212
213         assert(longValue == 0);
214
215         nodeIdBinary->length = bytes;
216         nodeIdBinary->set = true;
217         return true;
218 }
219
220 /**
221  Convert two given unsigned long longs to the binary/wireformat representation
222  of them.
223
224  @param nodeIdBinary
225  a pointer to the buffer in which to store the binary/wireformat representation
226  @param value1
227  the first value to convert (in machine byte-order)
228  @param dst1
229  A pointer where to store the conversion of value1
230  @param bytes1
231  the number of bytes used by value1
232  @param value2
233  the second value to convert (in machine byte-order)
234  @param dst2
235  A pointer where to store the conversion of value2
236  @param bytes2
237  the number of bytes used by value2
238
239  @return
240  - true when ok
241  - false on failure
242  */
243 bool setupNodeIdBinaryDoubleLongLong(nodeIdBinaryType * nodeIdBinary,
244     unsigned long long value1, unsigned char * dst1, size_t bytes1,
245     unsigned long long value2, unsigned char * dst2, size_t bytes2) {
246         unsigned long long longValue1 = value1;
247         unsigned long long longValue2 = value2;
248         int i1 = bytes1 - 1;
249         int i2 = bytes2 - 1;
250
251         while (i1 >= 0) {
252                 dst1[i1] = longValue1 & 0xff;
253                 longValue1 >>= 8;
254                 i1--;
255         }
256         assert(longValue1 == 0);
257
258         while (i2 >= 0) {
259                 dst2[i2] = longValue2 & 0xff;
260                 longValue2 >>= 8;
261                 i2--;
262         }
263         assert(longValue2 == 0);
264
265         nodeIdBinary->length = bytes1 + bytes2;
266         nodeIdBinary->set = true;
267         return true;
268 }
269
270 /**
271  Convert a given string to the binary/wireformat representation of it.
272
273  @param nodeIdBinary
274  a pointer to the buffer in which to store the binary/wireformat representation
275  @param nodeId
276  a pointer to the nodeId string
277  @param nodeIdLength
278  the length of the nodeId string
279  @return
280  - true when ok
281  - false on failure
282  */
283 bool setupNodeIdBinaryString(nodeIdBinaryType * nodeIdBinary, char * nodeId,
284                 size_t nodeIdLength) {
285         /* including trailing \0 */
286         memcpy(&nodeIdBinary->buffer.stringValue[0], &nodeId[0], nodeIdLength + 1);
287         nodeIdBinary->length = nodeIdLength + 1;
288         nodeIdBinary->set = true;
289         return true;
290 }
291
292 /**
293  Convert a given IP address to the binary/wireformat representation of it.
294
295  @param nodeIdBinary
296  a pointer to the buffer in which to store the binary/wireformat representation
297  @param ip
298  a pointer to a buffer in which the IP address is stored (in network byte-order)
299  @param ipLength
300  the number of bytes used by the IP address
301  @return
302  - true when ok
303  - false on failure
304  */
305 bool setupNodeIdBinaryIp(nodeIdBinaryType * nodeIdBinary, void * ip,
306                 size_t ipLength) {
307         memcpy(&nodeIdBinary->buffer.ip, ip, ipLength);
308         nodeIdBinary->length = ipLength;
309         nodeIdBinary->set = true;
310         return true;
311 }