Changeset 1085:7d7266115a34 in freeDiameter for libfdproto/dictionary_functions.c
- Timestamp:
- May 3, 2013, 8:20:56 PM (11 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdproto/dictionary_functions.c
r1052 r1085 153 153 154 154 /* Dump the content of an Address AVP */ 155 char * fd_dictfct_Address_dump(union avp_value * avp_value) 156 { 157 char * ret; 158 #define STR_LEN 1024 155 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Address_dump, union avp_value * avp_value) 156 { 159 157 union { 160 158 sSA sa; … … 164 162 } s; 165 163 uint16_t fam; 164 size_t o = 0; 165 166 if (!offset) 167 offset = &o; 166 168 167 169 memset(&s, 0, sizeof(s)); 168 169 CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL );170 170 171 171 /* The first two octets represent the address family, http://www.iana.org/assignments/address-family-numbers/ */ 172 172 if (avp_value->os.len < 2) { 173 snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len);174 return ret;173 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid length: %zd]", avp_value->os.len), return NULL); 174 return *buf; 175 175 } 176 176 … … 182 182 s.sa.sa_family = AF_INET; 183 183 if (avp_value->os.len != 6) { 184 snprintf(ret, STR_LEN, "[invalid IP length: %zd]", avp_value->os.len);185 return ret;184 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP length: %zd]", avp_value->os.len), return NULL); 185 return *buf; 186 186 } 187 187 memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4); … … 191 191 s.sa.sa_family = AF_INET6; 192 192 if (avp_value->os.len != 18) { 193 snprintf(ret, STR_LEN, "[invalid IP6 length: %zd]", avp_value->os.len);194 return ret;193 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP6 length: %zd]", avp_value->os.len), return NULL); 194 return *buf; 195 195 } 196 196 memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16); 197 197 break; 198 198 default: 199 snprintf(ret, STR_LEN, "[unsupported family: 0x%hx]", fam); 200 return ret; 201 } 202 203 { 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; 199 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[unsupported family: 0x%hx]", fam), return NULL); 200 return *buf; 201 } 202 203 return fd_sa_dump_node(FD_DUMP_STD_PARAMS, &s.sa, NI_NUMERICHOST); 210 204 } 211 205 … … 216 210 /*******************************/ 217 211 218 /* Dump the AVP in a natural human-readable format */ 219 char * fd_dictfct_UTF8String_dump(union avp_value * avp_value) 220 { 221 #define TRUNC_LEN 1024 /* avoid very long strings */ 222 char * ret; 223 CHECK_MALLOC_DO( ret = malloc(TRUNC_LEN+2+3+1), return NULL ); 224 *ret = '"'; 225 strncpy(ret+1, (char *)avp_value->os.data, TRUNC_LEN); 226 /* be sure to have a nul-terminated string */ 227 ret[TRUNC_LEN+1] = '\0'; 228 if (ret[1] != '\0') { 229 /* We sanitize the returned string to avoid UTF8 boundary problem. 230 We do this whether the string is trucated at TRUNC_LEN or not, to avoid potential problem 231 with malformed AVP */ 232 233 char * end = strchr(ret, '\0'); 234 while (end > ret) { 235 end--; 236 char b = *end; 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; 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 */ 213 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_UTF8String_dump, union avp_value * avp_value) 214 { 215 size_t o = 0, l; 216 if (!offset) 217 offset = &o; 218 219 l = avp_value->os.len; 220 /* Just in case the string ends in invalid UTF-8 chars, we shorten it */ 221 while ((l > 0) && (avp_value->os.data[l - 1] & 0x80)) { 222 /* this byte is start or cont. of multibyte sequence, as we do not know the next byte we need to delete it. */ 223 l--; 224 if (avp_value->os.data[l] & 0x40) 225 break; /* This was a start byte, we can stop the loop */ 226 } 227 228 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "\"%.*s\"", (int)l, (char *)avp_value->os.data), return NULL); 229 230 return *buf; 254 231 } 255 232 … … 326 303 } 327 304 328 char * fd_dictfct_Time_dump(union avp_value * avp_value)329 { 330 char * ret;305 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Time_dump, union avp_value * avp_value) 306 { 307 size_t o = 0; 331 308 time_t val; 332 309 struct tm conv; 333 CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL ); 310 311 if (!offset) 312 offset = &o; 313 334 314 if (avp_value->os.len != 4) { 335 snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len); 336 return ret; 337 } 315 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid length: %zd]", avp_value->os.len), return NULL); 316 return *buf; 317 } 318 338 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]");340 return ret;341 } 342 gmtime_r(&val, &conv);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);344 return ret;345 } 346 320 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[time conversion error]"), return NULL); 321 return *buf; 322 } 323 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); 325 return *buf; 326 } 327
Note: See TracChangeset
for help on using the changeset viewer.