PUD: fix snprintf length confusion
[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                 *nodeIdStr = (char *) nodeId;
125                 break;
126
127         case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
128         case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
129         case PUD_NODEIDTYPE_MMSI: /* an AIS MMSI number */
130         case PUD_NODEIDTYPE_URN: /* a URN number */
131         case PUD_NODEIDTYPE_192:
132         case PUD_NODEIDTYPE_193:
133         case PUD_NODEIDTYPE_194:
134                 *nodeIdStr = getNodeIdNumberFromOlsr(nodeId, nodeIdSize,
135                                 nodeIdStrBuffer, nodeIdStrBufferSize);
136                 break;
137
138         case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
139         case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
140         default: /* unsupported */
141         {
142                 void * addr = getOlsrMessageOriginator(ipVersion, olsrMessage);
143                 *nodeIdStr = inet_ntop(ipVersion, addr, nodeIdStrBuffer,
144                                 nodeIdStrBufferSize);
145         }
146                 break;
147         }
148
149         return;
150 }
151
152 /**
153  Convert a given MAC address to the binary/wireformat representation of it.
154
155  @param nodeIdBinary
156  a pointer to the buffer in which to store the binary/wireformat representation
157  @param mac
158  a pointer to a buffer in which the MAC address is stored (in network byte-order)
159  @return
160  - true when ok
161  - false on failure
162  */
163 bool setupNodeIdBinaryMAC(nodeIdBinaryType * nodeIdBinary, unsigned char * mac) {
164         memcpy(&nodeIdBinary->buffer.mac, mac, PUD_NODEIDTYPE_MAC_BYTES);
165         nodeIdBinary->length = PUD_NODEIDTYPE_MAC_BYTES;
166         nodeIdBinary->set = true;
167         return true;
168 }
169
170 /**
171  Convert a given unsigned long long 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 value
176  the value to convert (in machine byte-order)
177  @param bytes
178  the number of bytes used by the value
179
180  @return
181  - true when ok
182  - false on failure
183  */
184 bool setupNodeIdBinaryLongLong(nodeIdBinaryType * nodeIdBinary,
185                 unsigned long long value, size_t bytes) {
186         unsigned long long longValue = value;
187         int i = bytes - 1;
188
189         while (i >= 0) {
190                 ((unsigned char *) &nodeIdBinary->buffer.longValue)[i] = longValue & 0xff;
191                 longValue >>= 8;
192                 i--;
193         }
194
195         assert(longValue == 0);
196
197         nodeIdBinary->length = bytes;
198         nodeIdBinary->set = true;
199         return true;
200 }
201
202 /**
203  Convert a given string to the binary/wireformat representation of it.
204
205  @param nodeIdBinary
206  a pointer to the buffer in which to store the binary/wireformat representation
207  @param nodeId
208  a pointer to the nodeId string
209  @param nodeIdLength
210  the length of the nodeId string
211  @return
212  - true when ok
213  - false on failure
214  */
215 bool setupNodeIdBinaryString(nodeIdBinaryType * nodeIdBinary, char * nodeId,
216                 size_t nodeIdLength) {
217         /* including trailing \0 */
218         memcpy(&nodeIdBinary->buffer.stringValue[0], &nodeId[0], nodeIdLength + 1);
219         nodeIdBinary->length = nodeIdLength + 1;
220         nodeIdBinary->set = true;
221         return true;
222 }
223
224 /**
225  Convert a given IP address to the binary/wireformat representation of it.
226
227  @param nodeIdBinary
228  a pointer to the buffer in which to store the binary/wireformat representation
229  @param ip
230  a pointer to a buffer in which the IP address is stored (in network byte-order)
231  @param ipLength
232  the number of bytes used by the IP address
233  @return
234  - true when ok
235  - false on failure
236  */
237 bool setupNodeIdBinaryIp(nodeIdBinaryType * nodeIdBinary, void * ip,
238                 size_t ipLength) {
239         memcpy(&nodeIdBinary->buffer.ip, ip, ipLength);
240         nodeIdBinary->length = ipLength;
241         nodeIdBinary->set = true;
242         return true;
243 }