PUD: cleanup includes
[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 + 1 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         int chars;
30
31         if (unlikely(!nodeIdTypeBuffer || (nodeIdTypeBufferSize == 0))) {
32                 return;
33         }
34
35         assert(nodeIdTypeBufferSize >= (PUD_TX_NODEIDTYPE_DIGITS + 1));
36
37         /* message has NO nodeId information */
38         chars = snprintf(&nodeIdTypeBuffer[0], nodeIdTypeBufferSize, "%u",
39                         getPositionUpdateNodeIdType(ipVersion, olsrGpsMessage));
40         if (likely(chars < nodeIdTypeBufferSize)) {
41                 nodeIdTypeBuffer[chars] = '\0';
42         } else {
43                 nodeIdTypeBuffer[nodeIdTypeBufferSize] = '\0';
44         }
45
46         return;
47 }
48
49 /**
50  Get a nodeId number (in string representation), using a certain number of
51  bytes, from the message of an OLSR message.
52
53  @param buffer
54  A pointer to the buffer that holds the nodeId
55  @param bufferSize
56  The number of bytes used by the number in the buffer
57  @param nodeIdBuffer
58  The buffer in which to place the nodeId number in string representation
59  @param nodeIdBufferSize
60  The size of the nodeIdbuffer
61
62  @return
63  A pointer to the nodeId string representation (&nodeIdBuffer[0])
64  */
65 static char *getNodeIdNumberFromOlsr(unsigned char * buffer,
66                 unsigned int bufferSize, char *nodeIdBuffer, socklen_t nodeIdBufferSize) {
67         unsigned long long val = 0;
68         unsigned int i = 0;
69         int chars;
70
71         while (i < bufferSize) {
72                 val <<= 8;
73                 val += buffer[i];
74                 i++;
75         }
76
77         chars = snprintf(nodeIdBuffer, nodeIdBufferSize, "%llu", val);
78         if (likely(chars < (int) nodeIdBufferSize)) {
79                 nodeIdBuffer[chars] = '\0';
80         } else {
81                 nodeIdBuffer[nodeIdBufferSize] = '\0';
82         }
83         return &nodeIdBuffer[0];
84 }
85
86 /**
87  Convert the nodeId of an OLSR message into a string.
88
89  @param ipVersion
90  The ip version (AF_INET or AF_INET6)
91  @param olsrMessage
92  A pointer to the OLSR message. Used to be able to retrieve the IP address of
93  the sender.
94  @param nodeIdStr
95  A pointer to a variable in which to store the pointer to the buffer in which
96  the nodeId string representation is written (the buffer needs to be at least
97  PUD_TX_NODEIDTYPE_DIGITS + 1 bytes). Not written to when nodeIdStrBuffer or
98  nodeIdStr is NULL or when nodeIdStrBufferSize is zero. Can point to
99  nodeIdStrBuffer or straight into the olsrMessage
100  @param nodeIdStrBuffer
101  A pointer to the buffer in which the nodeId string representation can be
102  written. Not written to when nodeIdStrBuffer or nodeIdStr is NULL or when
103  nodeIdStrBufferSize is zero.
104  @param nodeIdStrBufferSize
105  The size of the nodeIdStrBuffer. When zero then nodeIdStrBuffer and nodeIdStr
106  are not written to.
107  */
108 void getNodeIdStringFromOlsr(int ipVersion, union olsr_message *olsrMessage,
109                 const char **nodeIdStr, char *nodeIdStrBuffer,
110                 unsigned int nodeIdStrBufferSize) {
111         PudOlsrPositionUpdate * olsrGpsMessage;
112         unsigned char * nodeId;
113         unsigned int nodeIdSize;
114
115         if (unlikely(!nodeIdStrBuffer || (nodeIdStrBufferSize == 0) || !nodeIdStr)) {
116                 return;
117         }
118
119         assert(nodeIdStrBufferSize >= (PUD_TX_NODEID_BUFFERSIZE + 1));
120
121         olsrGpsMessage = getOlsrMessagePayload(ipVersion, olsrMessage);
122
123         getPositionUpdateNodeId(ipVersion, olsrMessage, &nodeId, &nodeIdSize);
124
125         switch (getPositionUpdateNodeIdType(ipVersion, olsrGpsMessage)) {
126         case PUD_NODEIDTYPE_MAC: /* hardware address */
127         {
128                 int chars;
129
130                 assert(nodeIdSize == 6);
131
132                 chars = snprintf(nodeIdStrBuffer, nodeIdStrBufferSize,
133                                 "%02x:%02x:%02x:%02x:%02x:%02x", nodeId[0], nodeId[1],
134                                 nodeId[2], nodeId[3], nodeId[4], nodeId[5]);
135                 if (likely(chars < (int) nodeIdStrBufferSize)) {
136                         nodeIdStrBuffer[chars] = '\0';
137                 } else {
138                         nodeIdStrBuffer[nodeIdStrBufferSize - 1] = '\0';
139                 }
140                 *nodeIdStr = &nodeIdStrBuffer[0];
141         }
142                 break;
143
144         case PUD_NODEIDTYPE_DNS: /* DNS name */
145                 *nodeIdStr = (char *) nodeId;
146                 break;
147
148         case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
149         case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
150         case PUD_NODEIDTYPE_MMSI: /* an AIS MMSI number */
151         case PUD_NODEIDTYPE_URN: /* a URN number */
152         case PUD_NODEIDTYPE_192:
153         case PUD_NODEIDTYPE_193:
154         case PUD_NODEIDTYPE_194:
155                 *nodeIdStr = getNodeIdNumberFromOlsr(nodeId, nodeIdSize,
156                                 nodeIdStrBuffer, nodeIdStrBufferSize);
157                 break;
158
159         case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
160         case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
161         default: /* unsupported */
162         {
163                 void * addr = getOlsrMessageOriginator(ipVersion, olsrMessage);
164                 *nodeIdStr = inet_ntop(ipVersion, addr, nodeIdStrBuffer,
165                                 nodeIdStrBufferSize);
166         }
167                 break;
168         }
169
170         return;
171 }
172
173 /**
174  Convert a given MAC address to the binary/wireformat representation of it.
175
176  @param nodeIdBinary
177  a pointer to the buffer in which to store the binary/wireformat representation
178  @param mac
179  a pointer to a buffer in which the MAC address is stored (in network byte-order)
180  @return
181  - true when ok
182  - false on failure
183  */
184 bool setupNodeIdBinaryMAC(nodeIdBinaryType * nodeIdBinary, unsigned char * mac) {
185         memcpy(&nodeIdBinary->buffer.mac, mac, PUD_NODEIDTYPE_MAC_BYTES);
186         nodeIdBinary->length = PUD_NODEIDTYPE_MAC_BYTES;
187         nodeIdBinary->set = true;
188         return true;
189 }
190
191 /**
192  Convert a given unsigned long long to the binary/wireformat representation of it.
193
194  @param nodeIdBinary
195  a pointer to the buffer in which to store the binary/wireformat representation
196  @param value
197  the value to convert (in machine byte-order)
198  @param bytes
199  the number of bytes used by the value
200
201  @return
202  - true when ok
203  - false on failure
204  */
205 bool setupNodeIdBinaryLongLong(nodeIdBinaryType * nodeIdBinary,
206                 unsigned long long value, size_t bytes) {
207         unsigned long long longValue = value;
208         int i = bytes - 1;
209
210         while (i >= 0) {
211                 ((unsigned char *) &nodeIdBinary->buffer.longValue)[i] = longValue & 0xff;
212                 longValue >>= 8;
213                 i--;
214         }
215
216         assert(longValue == 0);
217
218         nodeIdBinary->length = bytes;
219         nodeIdBinary->set = true;
220         return true;
221 }
222
223 /**
224  Convert a given string to the binary/wireformat representation of it.
225
226  @param nodeIdBinary
227  a pointer to the buffer in which to store the binary/wireformat representation
228  @param nodeId
229  a pointer to the nodeId string
230  @param nodeIdLength
231  the length of the nodeId string
232  @return
233  - true when ok
234  - false on failure
235  */
236 bool setupNodeIdBinaryString(nodeIdBinaryType * nodeIdBinary, char * nodeId,
237                 size_t nodeIdLength) {
238         /* including trailing \0 */
239         memcpy(&nodeIdBinary->buffer.stringValue[0], &nodeId[0], nodeIdLength + 1);
240         nodeIdBinary->length = nodeIdLength + 1;
241         nodeIdBinary->set = true;
242         return true;
243 }
244
245 /**
246  Convert a given IP address to the binary/wireformat representation of it.
247
248  @param nodeIdBinary
249  a pointer to the buffer in which to store the binary/wireformat representation
250  @param ip
251  a pointer to a buffer in which the IP address is stored (in network byte-order)
252  @param ipLength
253  the number of bytes used by the IP address
254  @return
255  - true when ok
256  - false on failure
257  */
258 bool setupNodeIdBinaryIp(nodeIdBinaryType * nodeIdBinary, void * ip,
259                 size_t ipLength) {
260         memcpy(&nodeIdBinary->buffer.ip, ip, ipLength);
261         nodeIdBinary->length = ipLength;
262         nodeIdBinary->set = true;
263         return true;
264 }