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
"Welcome to our mercurial repository"