PUD: add wireformat libraries
[olsrd.git] / lib / pud / wireformat / src / nodeIdConversion.c
1 #include <OlsrdPudWireFormat/nodeIdConversion.h>
2 #include <OlsrdPudWireFormat/compiler.h>
3
4 #include <assert.h>
5 #include <arpa/inet.h>
6 #include <net/if.h>
7
8 /* ************************************************************************
9  * Node Information
10  * ************************************************************************ */
11
12 /**
13  Convert the nodeIdType of an OLSR message into a string.
14
15  @param ipVersion
16  The ip version (AF_INET or AF_INET6)
17  @param olsrGpsMessage
18  A pointer to the position update message.
19  @param nodeIdTypeBuffer
20  A pointer to the buffer in which the nodeIdType string representation is
21  written (the buffer needs to be at least PUD_TX_NODEIDTYPE_DIGITS + 1 bytes).
22  When NULL then the nodeIdType string is not written.
23  @param nodeIdTypeBufferSize
24  The size of the nodeIdTypeBuffer. When zero then the nodeIdType string is not
25  written.
26  */
27 void getNodeTypeStringFromOlsr(int ipVersion,
28                 PudOlsrPositionUpdate * olsrGpsMessage, char * nodeIdTypeBuffer,
29                 int nodeIdTypeBufferSize) {
30         int chars;
31
32         if (unlikely(!nodeIdTypeBuffer || (nodeIdTypeBufferSize == 0))) {
33                 return;
34         }
35
36         assert(nodeIdTypeBufferSize >= (PUD_TX_NODEIDTYPE_DIGITS + 1));
37
38         /* message has NO nodeId information */
39         chars = snprintf(&nodeIdTypeBuffer[0], nodeIdTypeBufferSize, "%u",
40                         getPositionUpdateNodeIdType(ipVersion, olsrGpsMessage));
41         if (likely(chars < nodeIdTypeBufferSize)) {
42                 nodeIdTypeBuffer[chars] = '\0';
43         } else {
44                 nodeIdTypeBuffer[nodeIdTypeBufferSize] = '\0';
45         }
46
47         return;
48 }
49
50 /**
51  Get a nodeId number (in string representation), using a certain number of
52  bytes, from the message of an OLSR message.
53
54  @param buffer
55  A pointer to the buffer that holds the nodeId
56  @param bufferSize
57  The number of bytes used by the number in the buffer
58  @param nodeIdBuffer
59  The buffer in which to place the nodeId number in string representation
60  @param nodeIdBufferSize
61  The size of the nodeIdbuffer
62
63  @return
64  A pointer to the nodeId string representation (&nodeIdBuffer[0])
65  */
66 static char *getNodeIdNumberFromOlsr(unsigned char * buffer,
67                 unsigned int bufferSize, char *nodeIdBuffer, socklen_t nodeIdBufferSize) {
68         unsigned long long val = 0;
69         unsigned int i = 0;
70         int chars;
71
72         while (i < bufferSize) {
73                 val <<= 8;
74                 val += buffer[i];
75                 i++;
76         }
77
78         chars = snprintf(nodeIdBuffer, nodeIdBufferSize, "%llu", val);
79         if (likely(chars < (int) nodeIdBufferSize)) {
80                 nodeIdBuffer[chars] = '\0';
81         } else {
82                 nodeIdBuffer[nodeIdBufferSize] = '\0';
83         }
84         return &nodeIdBuffer[0];
85 }
86
87 /**
88  Convert the nodeId of an OLSR message into a string.
89
90  @param ipVersion
91  The ip version (AF_INET or AF_INET6)
92  @param olsrMessage
93  A pointer to the OLSR message. Used to be able to retrieve the IP address of
94  the sender.
95  @param nodeIdStr
96  A pointer to a variable in which to store the pointer to the buffer in which
97  the nodeId string representation is written (the buffer needs to be at least
98  PUD_TX_NODEIDTYPE_DIGITS + 1 bytes). Not written to when nodeIdStrBuffer or
99  nodeIdStr is NULL or when nodeIdStrBufferSize is zero. Can point to
100  nodeIdStrBuffer or straight into the olsrMessage
101  @param nodeIdStrBuffer
102  A pointer to the buffer in which the nodeId string representation can be
103  written. Not written to when nodeIdStrBuffer or nodeIdStr is NULL or when
104  nodeIdStrBufferSize is zero.
105  @param nodeIdStrBufferSize
106  The size of the nodeIdStrBuffer. When zero then nodeIdStrBuffer and nodeIdStr
107  are not written to.
108  */
109 void getNodeIdStringFromOlsr(int ipVersion, union olsr_message *olsrMessage,
110                 const char **nodeIdStr, char *nodeIdStrBuffer,
111                 unsigned int nodeIdStrBufferSize) {
112         PudOlsrPositionUpdate * olsrGpsMessage;
113         unsigned char * nodeId;
114         unsigned int nodeIdSize;
115
116         if (unlikely(!nodeIdStrBuffer || (nodeIdStrBufferSize == 0) || !nodeIdStr)) {
117                 return;
118         }
119
120         assert(nodeIdStrBufferSize >= (PUD_TX_NODEID_BUFFERSIZE + 1));
121
122         olsrGpsMessage = getOlsrMessagePayload(ipVersion, olsrMessage);
123
124         getPositionUpdateNodeId(ipVersion, olsrMessage, &nodeId, &nodeIdSize);
125
126         switch (getPositionUpdateNodeIdType(ipVersion, olsrGpsMessage)) {
127         case PUD_NODEIDTYPE_MAC: /* hardware address */
128         {
129                 int chars;
130
131                 assert(nodeIdSize == 6);
132
133                 chars = snprintf(nodeIdStrBuffer, nodeIdStrBufferSize,
134                                 "%02x:%02x:%02x:%02x:%02x:%02x", nodeId[0], nodeId[1],
135                                 nodeId[2], nodeId[3], nodeId[4], nodeId[5]);
136                 if (likely(chars < (int) nodeIdStrBufferSize)) {
137                         nodeIdStrBuffer[chars] = '\0';
138                 } else {
139                         nodeIdStrBuffer[nodeIdStrBufferSize - 1] = '\0';
140                 }
141                 *nodeIdStr = &nodeIdStrBuffer[0];
142         }
143                 break;
144
145         case PUD_NODEIDTYPE_DNS: /* DNS name */
146                 *nodeIdStr = (char *) nodeId;
147                 break;
148
149         case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
150         case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
151         case PUD_NODEIDTYPE_192:
152         case PUD_NODEIDTYPE_193:
153         case PUD_NODEIDTYPE_194:
154                 *nodeIdStr = getNodeIdNumberFromOlsr(nodeId, nodeIdSize,
155                                 nodeIdStrBuffer, nodeIdStrBufferSize);
156                 break;
157
158         case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
159         case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
160         default: /* unsupported */
161         {
162                 void * addr = getOlsrMessageOriginator(ipVersion, olsrMessage);
163                 *nodeIdStr = inet_ntop(ipVersion, addr, nodeIdStrBuffer,
164                                 nodeIdStrBufferSize);
165         }
166                 break;
167         }
168
169         return;
170 }