Mercurial > hg > freeDiameter
comparison libfdproto/dictionary_functions.c @ 1085:7d7266115a34
Cleaning of the traces in progress
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Fri, 03 May 2013 19:20:56 +0800 |
parents | b3d623f04b6d |
children | 44f3e48dfe27 |
comparison
equal
deleted
inserted
replaced
1084:6b7966ea27fb | 1085:7d7266115a34 |
---|---|
150 | 150 |
151 return 0; | 151 return 0; |
152 } | 152 } |
153 | 153 |
154 /* Dump the content of an Address AVP */ | 154 /* Dump the content of an Address AVP */ |
155 char * fd_dictfct_Address_dump(union avp_value * avp_value) | 155 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Address_dump, union avp_value * avp_value) |
156 { | 156 { |
157 char * ret; | |
158 #define STR_LEN 1024 | |
159 union { | 157 union { |
160 sSA sa; | 158 sSA sa; |
161 sSS ss; | 159 sSS ss; |
162 sSA4 sin; | 160 sSA4 sin; |
163 sSA6 sin6; | 161 sSA6 sin6; |
164 } s; | 162 } s; |
165 uint16_t fam; | 163 uint16_t fam; |
164 size_t o = 0; | |
165 | |
166 if (!offset) | |
167 offset = &o; | |
166 | 168 |
167 memset(&s, 0, sizeof(s)); | 169 memset(&s, 0, sizeof(s)); |
168 | |
169 CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL ); | |
170 | 170 |
171 /* The first two octets represent the address family, http://www.iana.org/assignments/address-family-numbers/ */ | 171 /* The first two octets represent the address family, http://www.iana.org/assignments/address-family-numbers/ */ |
172 if (avp_value->os.len < 2) { | 172 if (avp_value->os.len < 2) { |
173 snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len); | 173 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid length: %zd]", avp_value->os.len), return NULL); |
174 return ret; | 174 return *buf; |
175 } | 175 } |
176 | 176 |
177 /* Following octets are the address in network byte order already */ | 177 /* Following octets are the address in network byte order already */ |
178 fam = avp_value->os.data[0] << 8 | avp_value->os.data[1]; | 178 fam = avp_value->os.data[0] << 8 | avp_value->os.data[1]; |
179 switch (fam) { | 179 switch (fam) { |
180 case 1: | 180 case 1: |
181 /* IP */ | 181 /* IP */ |
182 s.sa.sa_family = AF_INET; | 182 s.sa.sa_family = AF_INET; |
183 if (avp_value->os.len != 6) { | 183 if (avp_value->os.len != 6) { |
184 snprintf(ret, STR_LEN, "[invalid IP length: %zd]", avp_value->os.len); | 184 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP length: %zd]", avp_value->os.len), return NULL); |
185 return ret; | 185 return *buf; |
186 } | 186 } |
187 memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4); | 187 memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4); |
188 break; | 188 break; |
189 case 2: | 189 case 2: |
190 /* IP6 */ | 190 /* IP6 */ |
191 s.sa.sa_family = AF_INET6; | 191 s.sa.sa_family = AF_INET6; |
192 if (avp_value->os.len != 18) { | 192 if (avp_value->os.len != 18) { |
193 snprintf(ret, STR_LEN, "[invalid IP6 length: %zd]", avp_value->os.len); | 193 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP6 length: %zd]", avp_value->os.len), return NULL); |
194 return ret; | 194 return *buf; |
195 } | 195 } |
196 memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16); | 196 memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16); |
197 break; | 197 break; |
198 default: | 198 default: |
199 snprintf(ret, STR_LEN, "[unsupported family: 0x%hx]", fam); | 199 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[unsupported family: 0x%hx]", fam), return NULL); |
200 return ret; | 200 return *buf; |
201 } | 201 } |
202 | 202 |
203 { | 203 return fd_sa_dump_node(FD_DUMP_STD_PARAMS, &s.sa, NI_NUMERICHOST); |
204 int rc = getnameinfo(&s.sa, sSAlen(&s.sa), ret, STR_LEN, NULL, 0, NI_NUMERICHOST); | |
205 if (rc) | |
206 snprintf(ret, STR_LEN, "%s", (char *)gai_strerror(rc)); | |
207 } | |
208 | |
209 return ret; | |
210 } | 204 } |
211 | 205 |
212 | 206 |
213 | 207 |
214 /*******************************/ | 208 /*******************************/ |
215 /* UTF8String AVP type */ | 209 /* UTF8String AVP type */ |
216 /*******************************/ | 210 /*******************************/ |
217 | 211 |
218 /* Dump the AVP in a natural human-readable format */ | 212 /* Dump the AVP in a natural human-readable format. This dumps the complete length of the AVP, it is up to the caller to truncate if needed */ |
219 char * fd_dictfct_UTF8String_dump(union avp_value * avp_value) | 213 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_UTF8String_dump, union avp_value * avp_value) |
220 { | 214 { |
221 #define TRUNC_LEN 1024 /* avoid very long strings */ | 215 size_t o = 0, l; |
222 char * ret; | 216 if (!offset) |
223 CHECK_MALLOC_DO( ret = malloc(TRUNC_LEN+2+3+1), return NULL ); | 217 offset = &o; |
224 *ret = '"'; | 218 |
225 strncpy(ret+1, (char *)avp_value->os.data, TRUNC_LEN); | 219 l = avp_value->os.len; |
226 /* be sure to have a nul-terminated string */ | 220 /* Just in case the string ends in invalid UTF-8 chars, we shorten it */ |
227 ret[TRUNC_LEN+1] = '\0'; | 221 while ((l > 0) && (avp_value->os.data[l - 1] & 0x80)) { |
228 if (ret[1] != '\0') { | 222 /* this byte is start or cont. of multibyte sequence, as we do not know the next byte we need to delete it. */ |
229 /* We sanitize the returned string to avoid UTF8 boundary problem. | 223 l--; |
230 We do this whether the string is trucated at TRUNC_LEN or not, to avoid potential problem | 224 if (avp_value->os.data[l] & 0x40) |
231 with malformed AVP */ | 225 break; /* This was a start byte, we can stop the loop */ |
232 | 226 } |
233 char * end = strchr(ret, '\0'); | 227 |
234 while (end > ret) { | 228 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "\"%.*s\"", (int)l, (char *)avp_value->os.data), return NULL); |
235 end--; | 229 |
236 char b = *end; | 230 return *buf; |
237 /* after the position pointed by end, we have only \0s */ | |
238 if ((b & 0x80) == 0) { | |
239 break; /* this is a single byte char, no problem */ | |
240 } else { | |
241 /* this byte is start or cont. of multibyte sequence, as we do not know the next byte we need to delete it. */ | |
242 *end = '\0'; | |
243 if (b & 0x40) | |
244 break; /* This was a start byte, we can stop the loop */ | |
245 } | |
246 } | |
247 if (strlen((char *)avp_value->os.data) > strlen(ret+1)) | |
248 strcat(end, "..."); | |
249 strcat(end, "\""); | |
250 } else { | |
251 *ret = '\0'; | |
252 } | |
253 return ret; | |
254 } | 231 } |
255 | 232 |
256 | 233 |
257 /*******************************/ | 234 /*******************************/ |
258 /* Time AVP type */ | 235 /* Time AVP type */ |
323 CHECK_PARAMS( avp_value && interpreted ); | 300 CHECK_PARAMS( avp_value && interpreted ); |
324 | 301 |
325 return diameter_string_to_time_t((const char *)avp_value->os.data, avp_value->os.len, interpreted); | 302 return diameter_string_to_time_t((const char *)avp_value->os.data, avp_value->os.len, interpreted); |
326 } | 303 } |
327 | 304 |
328 char * fd_dictfct_Time_dump(union avp_value * avp_value) | 305 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Time_dump, union avp_value * avp_value) |
329 { | 306 { |
330 char * ret; | 307 size_t o = 0; |
331 time_t val; | 308 time_t val; |
332 struct tm conv; | 309 struct tm conv; |
333 CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL ); | 310 |
311 if (!offset) | |
312 offset = &o; | |
313 | |
334 if (avp_value->os.len != 4) { | 314 if (avp_value->os.len != 4) { |
335 snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len); | 315 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid length: %zd]", avp_value->os.len), return NULL); |
336 return ret; | 316 return *buf; |
337 } | 317 } |
318 | |
338 if (diameter_string_to_time_t((char *)avp_value->os.data, avp_value->os.len, &val) != 0) { | 319 if (diameter_string_to_time_t((char *)avp_value->os.data, avp_value->os.len, &val) != 0) { |
339 snprintf(ret, STR_LEN, "[time conversion error]"); | 320 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[time conversion error]"), return NULL); |
340 return ret; | 321 return *buf; |
341 } | 322 } |
342 gmtime_r(&val, &conv); | 323 |
343 snprintf(ret, STR_LEN, "%d%02d%02dT%02d%02d%02d+00", conv.tm_year+1900, conv.tm_mon+1, conv.tm_mday, conv.tm_hour, conv.tm_min, conv.tm_sec); | 324 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "%d%02d%02dT%02d%02d%02d+00", conv.tm_year+1900, conv.tm_mon+1, conv.tm_mday, conv.tm_hour, conv.tm_min, conv.tm_sec), return NULL); |
344 return ret; | 325 return *buf; |
345 } | 326 } |
346 | 327 |