Coverage Report

Created: 2026-07-12 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/to_str.c
Line
Count
Source
1
/* to_str.c
2
 * Routines for utilities to convert various other types to strings.
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 *
8
 * SPDX-License-Identifier: GPL-2.0-or-later
9
 */
10
11
#include "config.h"
12
13
#include <stdio.h>
14
#include <string.h>
15
#include <time.h>
16
#include <glib.h>
17
18
#include <epan/wmem_scopes.h>
19
#include "proto.h"
20
#include "to_str.h"
21
#include "strutil.h"
22
#include <wsutil/pint.h>
23
#include <wsutil/utf8_entities.h>
24
25
/*
26
 * If a user _does_ pass in a too-small buffer, this is probably
27
 * going to be too long to fit.  However, even a partial string
28
 * starting with "[Buf" should provide enough of a clue to be
29
 * useful.
30
 */
31
0
#define BUF_TOO_SMALL_ERR "[Buffer too small]"
32
33
static const char mon_names[12][4] = {
34
    "Jan",
35
    "Feb",
36
    "Mar",
37
    "Apr",
38
    "May",
39
    "Jun",
40
    "Jul",
41
    "Aug",
42
    "Sep",
43
    "Oct",
44
    "Nov",
45
    "Dec"
46
};
47
48
static const char *
49
get_zonename(struct tm *tmp)
50
3.19k
{
51
#if defined(_WIN32)
52
    /*
53
     * The strings in _tzname[] are encoded using the code page
54
     * for the current C-language locale.
55
     *
56
     * On Windows, all Wireshark programs set that code page
57
     * to the UTF-8 code page by calling
58
     *
59
     *    setlocale(LC_ALL, ".UTF-8");
60
     *
61
     * so the strings in _tzname[] are UTF-8 strings, and we can
62
     * just return them.
63
     *
64
     * (Note: the above does *not* mean we've set any code pages
65
     * *other* than the one used by the Visual Studio C runtime
66
     * to UTF-8, so don't assume, for example, that the "ANSI"
67
     * versions of Windows APIs will take UTF-8 strings, or that
68
     * non-UTF-16 output to the console will be treated as UTF-8.
69
     * Setting those other code pages can cause problems, especially
70
     * on pre-Windows 10 or older Windows 10 releases.)
71
     */
72
    return _tzname[tmp->tm_isdst];
73
#else
74
    /*
75
     * UN*X.
76
     *
77
     * If we have tm_zone in struct tm, use that.
78
     * Otherwise, if we have tzname[], use it, otherwise just
79
     * say "we don't know.
80
     */
81
3.19k
# if defined(HAVE_STRUCT_TM_TM_ZONE)
82
3.19k
    return tmp->tm_zone;
83
# else /* HAVE_STRUCT_TM_TM_ZONE */
84
    if ((tmp->tm_isdst != 0) && (tmp->tm_isdst != 1)) {
85
        return "???";
86
    }
87
#  if defined(HAVE_TZNAME)
88
    return tzname[tmp->tm_isdst];
89
#  else
90
    return tmp->tm_isdst ? "?DT" : "?ST";
91
#  endif /* HAVE_TZNAME */
92
# endif /* HAVE_STRUCT_TM_TM_ZONE */
93
3.19k
#endif /* _WIN32 */
94
3.19k
}
95
96
static struct tm *
97
get_fmt_broken_down_time(field_display_e fmt, const time_t *secs)
98
3.79k
{
99
3.79k
    switch (fmt) {
100
578
        case ABSOLUTE_TIME_UTC:
101
578
        case ABSOLUTE_TIME_DOY_UTC:
102
602
        case ABSOLUTE_TIME_NTP_UTC:
103
602
            return gmtime(secs);
104
3.19k
        case ABSOLUTE_TIME_LOCAL:
105
3.19k
            return localtime(secs);
106
0
        default:
107
0
            break;
108
3.79k
    }
109
0
    ws_assert_not_reached();
110
0
}
111
112
static char *
113
snprint_abs_time_secs(wmem_allocator_t *scope,
114
                        field_display_e fmt, struct tm *tmp,
115
                        const char *nsecs_str, const char *tzone_sep,
116
                        const char *tzone_str, bool add_quotes)
117
3.79k
{
118
3.79k
    char *buf;
119
120
3.79k
    switch (fmt) {
121
0
        case ABSOLUTE_TIME_DOY_UTC:
122
0
            buf = wmem_strdup_printf(scope,
123
0
                    "%s%04d/%03d:%02d:%02d:%02d%s%s%s%s",
124
0
                    add_quotes ? "\"" : "",
125
0
                    tmp->tm_year + 1900,
126
0
                    tmp->tm_yday + 1,
127
0
                    tmp->tm_hour,
128
0
                    tmp->tm_min,
129
0
                    tmp->tm_sec,
130
0
                    nsecs_str,
131
0
                    tzone_sep,
132
0
                    tzone_str,
133
0
                    add_quotes ? "\"" : "");
134
0
            break;
135
24
        case ABSOLUTE_TIME_NTP_UTC: /* FALLTHROUGH */
136
602
        case ABSOLUTE_TIME_UTC:   /* FALLTHROUGH */
137
3.79k
        case ABSOLUTE_TIME_LOCAL:
138
3.79k
            buf = wmem_strdup_printf(scope,
139
3.79k
                    "%s%s %2d, %d %02d:%02d:%02d%s%s%s%s",
140
3.79k
                    add_quotes ? "\"" : "",
141
3.79k
                    mon_names[tmp->tm_mon],
142
3.79k
                    tmp->tm_mday,
143
3.79k
                    tmp->tm_year + 1900,
144
3.79k
                    tmp->tm_hour,
145
3.79k
                    tmp->tm_min,
146
3.79k
                    tmp->tm_sec,
147
3.79k
                    nsecs_str,
148
3.79k
                    tzone_sep,
149
3.79k
                    tzone_str,
150
3.79k
                    add_quotes ? "\"" : "");
151
3.79k
            break;
152
0
        default:
153
0
            ws_assert_not_reached();
154
3.79k
    }
155
3.79k
    return buf;
156
3.79k
}
157
158
static char *
159
snprint_abs_time_iso8601(wmem_allocator_t *scope,
160
                        field_display_e fmt, struct tm *tmp,
161
                        const char *nsecs_str, int flags)
162
0
{
163
0
    char *buf;
164
0
    bool add_quotes = flags & ABS_TIME_TO_STR_ADD_DQUOTES;
165
0
    bool add_zone = flags & ABS_TIME_TO_STR_SHOW_ZONE;
166
0
    if (fmt != ABSOLUTE_TIME_LOCAL && flags & ABS_TIME_TO_STR_SHOW_UTC_ONLY) {
167
0
        add_zone = true;
168
0
    }
169
170
0
    switch (fmt) {
171
0
        case ABSOLUTE_TIME_DOY_UTC:
172
            /* ISO 8601 4.1.3 Ordinal date */
173
0
            buf = wmem_strdup_printf(scope,
174
0
                    "%s%04d-%03dT%02d:%02d:%02d%s%s%s",
175
0
                    add_quotes ? "\"" : "",
176
0
                    tmp->tm_year + 1900,
177
0
                    tmp->tm_yday + 1,
178
0
                    tmp->tm_hour,
179
0
                    tmp->tm_min,
180
0
                    tmp->tm_sec,
181
0
                    nsecs_str,
182
0
                    add_zone ? "Z" : "",
183
0
                    add_quotes ? "\"" : "");
184
0
            break;
185
0
        case ABSOLUTE_TIME_NTP_UTC: /* FALLTHROUGH */
186
0
        case ABSOLUTE_TIME_UTC:   /* FALLTHROUGH */
187
0
            buf = wmem_strdup_printf(scope,
188
0
                    "%s%d-%02d-%02dT%02d:%02d:%02d%s%s%s",
189
0
                    add_quotes ? "\"" : "",
190
0
                    tmp->tm_year + 1900,
191
0
                    tmp->tm_mon + 1,
192
0
                    tmp->tm_mday,
193
0
                    tmp->tm_hour,
194
0
                    tmp->tm_min,
195
0
                    tmp->tm_sec,
196
0
                    nsecs_str,
197
0
                    add_zone ? "Z" : "",
198
0
                    add_quotes ? "\"" : "");
199
0
            break;
200
0
        case ABSOLUTE_TIME_LOCAL:
201
0
        {
202
0
            char zone_buf[8] = "";
203
0
            if (add_zone) {
204
                /*
205
                 * C11 requires that strftime supports %z; unfortunately
206
                 * it doesn't put the ':' in the timezone as strict ISO 8601
207
                 * would require (no mixing "basic" and "extended" formats.)
208
                 * XXX - Should we add in the ":"?
209
                 *
210
                 * We could also use _get_timezone on Windows, or on Linux and
211
                 * *BSD tm_gmtoff (if HAVE_STRUCT_TM_TM_GMTOFF).
212
                 */
213
0
                strftime(zone_buf, 8, "%z", tmp);
214
0
            }
215
0
            buf = wmem_strdup_printf(scope,
216
0
                    "%s%d-%02d-%02dT%02d:%02d:%02d%s%s%s",
217
0
                    add_quotes ? "\"" : "",
218
0
                    tmp->tm_year + 1900,
219
0
                    tmp->tm_mon + 1,
220
0
                    tmp->tm_mday,
221
0
                    tmp->tm_hour,
222
0
                    tmp->tm_min,
223
0
                    tmp->tm_sec,
224
0
                    nsecs_str,
225
0
                    zone_buf,
226
0
                    add_quotes ? "\"" : "");
227
0
            break;
228
0
        }
229
0
        default:
230
0
            ws_assert_not_reached();
231
0
    }
232
0
    return buf;
233
0
}
234
235
char *
236
abs_time_to_str_ex(wmem_allocator_t *scope, const nstime_t *abs_time, field_display_e fmt,
237
                    int flags)
238
3.79k
{
239
3.79k
    struct tm *tmp;
240
3.79k
    char buf_nsecs[32];
241
3.79k
    const char *tzone_sep, *tzone_str;
242
243
3.79k
    if (fmt == BASE_NONE)
244
0
        fmt = ABSOLUTE_TIME_LOCAL;
245
246
3.79k
    ws_assert(FIELD_DISPLAY_IS_ABSOLUTE_TIME(fmt));
247
248
3.79k
    if (fmt == ABSOLUTE_TIME_UNIX) {
249
0
        return abs_time_to_unix_str(scope, abs_time);
250
0
    }
251
252
3.79k
    if (fmt == ABSOLUTE_TIME_NTP_UTC && abs_time->secs == 0 &&
253
2
                (abs_time->nsecs == 0 || abs_time->nsecs == INT_MAX)) {
254
2
        return wmem_strdup(scope, "NULL");
255
2
    }
256
257
3.79k
    tmp = get_fmt_broken_down_time(fmt, &abs_time->secs);
258
3.79k
    if (tmp == NULL) {
259
0
        return wmem_strdup(scope, "Not representable");
260
0
    }
261
262
3.79k
    *buf_nsecs = '\0';
263
3.79k
    if (abs_time->nsecs != INT_MAX) {
264
698
        snprintf(buf_nsecs, sizeof(buf_nsecs), ".%09d", abs_time->nsecs);
265
698
    }
266
267
3.79k
    if (flags & ABS_TIME_TO_STR_ISO8601) {
268
0
        return snprint_abs_time_iso8601(scope, fmt, tmp, buf_nsecs, flags);
269
0
    }
270
271
3.79k
    tzone_sep = "";
272
3.79k
    tzone_str = "";
273
3.79k
    if (flags & ABS_TIME_TO_STR_SHOW_ZONE || flags & ABS_TIME_TO_STR_SHOW_UTC_ONLY) {
274
3.79k
        switch (fmt) {
275
276
578
        case ABSOLUTE_TIME_UTC:
277
578
        case ABSOLUTE_TIME_DOY_UTC:
278
602
        case ABSOLUTE_TIME_NTP_UTC:
279
602
            tzone_sep = " ";
280
602
            tzone_str = "UTC";
281
602
            break;
282
283
3.19k
        case ABSOLUTE_TIME_LOCAL:
284
3.19k
            if (flags & ABS_TIME_TO_STR_SHOW_ZONE) {
285
3.19k
                tzone_sep = " ";
286
3.19k
                tzone_str = get_zonename(tmp);
287
3.19k
            }
288
3.19k
            break;
289
0
        default:
290
0
            ws_assert_not_reached();
291
3.79k
        }
292
3.79k
    }
293
294
3.79k
    return snprint_abs_time_secs(scope, fmt, tmp, buf_nsecs, tzone_sep, tzone_str, flags & ABS_TIME_TO_STR_ADD_DQUOTES);
295
3.79k
}
296
297
char *
298
abs_time_secs_to_str_ex(wmem_allocator_t *scope, const time_t abs_time_secs, field_display_e fmt,
299
                        int flags)
300
3.09k
{
301
3.09k
    nstime_t abs_time;
302
303
3.09k
    nstime_set_unset(&abs_time);
304
3.09k
    abs_time.secs = abs_time_secs;
305
3.09k
    return abs_time_to_str_ex(scope, &abs_time, fmt, flags);
306
3.09k
}
307
308
101k
#define PLURALIZE(n)  (((n) > 1) ? "s" : "")
309
78.5k
#define COMMA(do_it)  ((do_it) ? ", " : "")
310
311
/*
312
 * Maximum length of a string showing days/hours/minutes/seconds.
313
 * (Does not include the terminating '\0'.)
314
 * Includes space for a '-' sign for any negative components.
315
 * -123456789012345 days, 12 hours, 12 minutes, 12.123 seconds
316
 */
317
29.1k
#define TIME_SECS_LEN (16+1+4+2+2+5+2+2+7+2+2+7+4)
318
319
/*
320
 * Convert an unsigned value in seconds and fractions of a second to a string,
321
 * giving time in days, hours, minutes, and seconds, and put the result
322
 * into a buffer.
323
 * "is_nsecs" says that "frac" is nanoseconds if true and milliseconds
324
 * if false.
325
 */
326
static void
327
unsigned_time_secs_to_str_buf(uint64_t time_val, const uint32_t frac,
328
                                const bool is_nsecs, wmem_strbuf_t *buf)
329
29.1k
{
330
29.1k
    uint64_t hours, mins, secs;
331
29.1k
    bool do_comma = false;
332
333
29.1k
    secs = time_val % 60;
334
29.1k
    time_val /= 60;
335
29.1k
    mins = time_val % 60;
336
29.1k
    time_val /= 60;
337
29.1k
    hours = time_val % 24;
338
29.1k
    time_val /= 24;
339
340
29.1k
    if (time_val != 0) {
341
23.3k
        wmem_strbuf_append_printf(buf, "%" PRIu64 " day%s", time_val, PLURALIZE(time_val));
342
23.3k
        do_comma = true;
343
23.3k
    }
344
29.1k
    if (hours != 0) {
345
24.0k
        wmem_strbuf_append_printf(buf, "%s%" PRIu64 " hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
346
24.0k
        do_comma = true;
347
24.0k
    }
348
29.1k
    if (mins != 0) {
349
27.3k
        wmem_strbuf_append_printf(buf, "%s%" PRIu64 " minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
350
27.3k
        do_comma = true;
351
27.3k
    }
352
29.1k
    if (secs != 0) {
353
27.0k
        if (frac != 0) {
354
432
            if (is_nsecs)
355
8
                wmem_strbuf_append_printf(buf, "%s%" PRIu64 ".%09u seconds", COMMA(do_comma), secs, frac);
356
424
            else
357
424
                wmem_strbuf_append_printf(buf, "%s%" PRIu64 ".%03u seconds", COMMA(do_comma), secs, frac);
358
432
        } else
359
26.6k
            wmem_strbuf_append_printf(buf, "%s%" PRIu64 " second%s", COMMA(do_comma), secs, PLURALIZE(secs));
360
27.0k
    } else if (frac != 0) {
361
42
        if (is_nsecs) {
362
0
            if (frac < 1000) {
363
0
                wmem_strbuf_append_printf(buf, "%s%u nanosecond%s", COMMA(do_comma), frac, PLURALIZE(frac));
364
0
            } else if (frac < 1000000) {
365
0
                wmem_strbuf_append_printf(buf, "%s%u.%03u microseconds", COMMA(do_comma), frac / 1000, frac % 1000);
366
0
            } else {
367
0
                wmem_strbuf_append_printf(buf, "%s%u.%06u milliseconds", COMMA(do_comma), frac / 1000000, frac % 1000000);
368
0
            }
369
42
        } else {
370
42
            wmem_strbuf_append_printf(buf, "%s%u millisecond%s", COMMA(do_comma), frac, PLURALIZE(frac));
371
42
        }
372
42
    }
373
29.1k
}
374
375
char *
376
unsigned_time_secs_to_str(wmem_allocator_t *scope, const uint32_t time_val)
377
27.3k
{
378
27.3k
    wmem_strbuf_t *buf;
379
380
27.3k
    if (time_val == 0) {
381
1.91k
        return wmem_strdup(scope, "0 seconds");
382
1.91k
    }
383
384
25.4k
    buf = wmem_strbuf_new_sized(scope, TIME_SECS_LEN+1);
385
386
25.4k
    unsigned_time_secs_to_str_buf(time_val, 0, false, buf);
387
388
25.4k
    return wmem_strbuf_finalize(buf);
389
27.3k
}
390
391
/*
392
 * Convert a signed value in seconds and fractions of a second to a string,
393
 * giving time in days, hours, minutes, and seconds, and put the result
394
 * into a buffer.
395
 * "is_nsecs" says that "frac" is nanoseconds if true and milliseconds
396
 * if false.
397
 */
398
static void
399
signed_time_secs_to_str_buf(int64_t time_val, const uint32_t frac,
400
    const bool is_nsecs, wmem_strbuf_t *buf)
401
3.69k
{
402
3.69k
    if(time_val < 0){
403
170
        wmem_strbuf_append_printf(buf, "-");
404
170
        if(time_val == INT64_MIN) {
405
            /*
406
             * You can't fit time_val's absolute value into
407
             * a 64-bit signed integer.  Just directly
408
             * pass UINT64_MAX, which is its absolute
409
             * value, directly to unsigned_time_secs_to_str_buf().
410
             *
411
             * (XXX - does ISO C guarantee that -(-2^n),
412
             * when calculated and cast to an n-bit unsigned
413
             * integer type, will have the value 2^n?)
414
             */
415
0
            unsigned_time_secs_to_str_buf(UINT64_MAX, frac,
416
0
                is_nsecs, buf);
417
170
        } else {
418
            /*
419
             * We now know -secs will fit into a uint32_t;
420
             * negate it and pass that to
421
             * unsigned_time_secs_to_str_buf().
422
             */
423
170
            unsigned_time_secs_to_str_buf(-time_val, frac, is_nsecs, buf);
424
170
        }
425
170
    } else
426
3.52k
        unsigned_time_secs_to_str_buf(time_val, frac, is_nsecs, buf);
427
3.69k
}
428
429
char *
430
signed_time_secs_to_str(wmem_allocator_t *scope, const int32_t time_val)
431
5.61k
{
432
5.61k
    wmem_strbuf_t *buf;
433
434
5.61k
    if (time_val == 0) {
435
2.38k
        return wmem_strdup(scope, "0 seconds");
436
2.38k
    }
437
438
3.22k
    buf = wmem_strbuf_new_sized(scope, TIME_SECS_LEN+1);
439
440
3.22k
    signed_time_secs_to_str_buf(time_val, 0, false, buf);
441
442
3.22k
    return wmem_strbuf_finalize(buf);
443
5.61k
}
444
445
/*
446
 * Convert a signed value in milliseconds to a string, giving time in days,
447
 * hours, minutes, and seconds, and put the result into a buffer.
448
 */
449
char *
450
signed_time_msecs_to_str(wmem_allocator_t *scope, int32_t time_val)
451
493
{
452
493
    wmem_strbuf_t *buf;
453
493
    int msecs;
454
455
493
    if (time_val == 0) {
456
26
        return wmem_strdup(scope, "0 seconds");
457
26
    }
458
459
467
    buf = wmem_strbuf_new_sized(scope, TIME_SECS_LEN+1+3+1);
460
461
467
    if (time_val<0) {
462
        /* oops we got passed a negative time */
463
        /* C99 and C++11 guarantee integer division rounds to zero */
464
5
        msecs = -(time_val % 1000);
465
5
        time_val /= 1000;
466
5
        if (time_val == 0) {
467
1
            wmem_strbuf_append_c(buf, '-');
468
1
        }
469
462
    } else {
470
462
        msecs = time_val % 1000;
471
462
        time_val /= 1000;
472
462
    }
473
474
467
    signed_time_secs_to_str_buf(time_val, msecs, false, buf);
475
476
467
    return wmem_strbuf_finalize(buf);
477
493
}
478
479
/*
480
 * Display a relative time as days/hours/minutes/seconds.
481
 */
482
char *
483
rel_time_to_str(wmem_allocator_t *scope, const nstime_t *rel_time)
484
8
{
485
8
    wmem_strbuf_t *buf;
486
8
    int64_t time_val;
487
8
    int32_t nsec;
488
489
    /* If the nanoseconds part of the time stamp is negative,
490
       print its absolute value and, if the seconds part isn't
491
       (the seconds part should be zero in that case), stick
492
       a "-" in front of the entire time stamp. */
493
8
    time_val = (int64_t) rel_time->secs;
494
8
    nsec = rel_time->nsecs;
495
8
    if (time_val == 0 && nsec == 0) {
496
0
        return wmem_strdup(scope, "0.000000000 seconds");
497
0
    }
498
499
8
    buf = wmem_strbuf_new_sized(scope, 1+TIME_SECS_LEN+1+6+1);
500
501
8
    if (nsec < 0) {
502
0
        nsec = -nsec;
503
0
        wmem_strbuf_append_c(buf, '-');
504
505
        /*
506
         * We assume here that "rel_time->secs" is negative
507
         * or zero; if it's not, the time stamp is bogus,
508
         * with a positive seconds and negative microseconds.
509
         */
510
0
        time_val = (int64_t) -rel_time->secs;
511
0
    }
512
513
8
    signed_time_secs_to_str_buf(time_val, nsec, true, buf);
514
515
8
    return wmem_strbuf_finalize(buf);
516
8
}
517
518
/*
519
 * Number of characters required by a 64-bit signed number.
520
 */
521
28
#define CHARS_64_BIT_SIGNED 20  /* sign plus 19 digits */
522
523
/*
524
 * Number of characters required by a fractional part, in nanoseconds */
525
28
#define CHARS_NANOSECONDS 10  /* .000000001 */
526
527
/* Includes terminating '\0' */
528
28
#define NSTIME_SECS_LEN (CHARS_64_BIT_SIGNED+CHARS_NANOSECONDS+1)
529
530
/*
531
 * Display a relative time as seconds.
532
 */
533
char *
534
rel_time_to_secs_str(wmem_allocator_t *scope, const nstime_t *rel_time)
535
14
{
536
14
    char *buf;
537
538
14
    buf = (char *)wmem_alloc(scope, NSTIME_SECS_LEN);
539
540
14
    display_signed_time(buf, NSTIME_SECS_LEN, rel_time, WS_TSPREC_NSEC);
541
14
    return buf;
542
14
}
543
544
char *
545
abs_time_to_unix_str(wmem_allocator_t *scope, const nstime_t *rel_time)
546
0
{
547
0
    char *buf;
548
549
0
    buf = (char *)wmem_alloc(scope, NSTIME_SECS_LEN);
550
551
0
    display_epoch_time(buf, NSTIME_SECS_LEN, rel_time, WS_TSPREC_NSEC);
552
0
    return buf;
553
0
}
554
555
/*
556
 * Generates a string representing the bits in a bitfield at "bit_offset" from an 8 bit boundary
557
 * with the length in bits of no_of_bits based on value.
558
 * Ex: ..xx x...
559
 */
560
561
char *
562
decode_bits_in_field(wmem_allocator_t *scope, const unsigned bit_offset, const int no_of_bits, const uint64_t value, const unsigned encoding)
563
2.22M
{
564
2.22M
    uint64_t mask;
565
2.22M
    char *str;
566
2.22M
    int bit, str_p = 0;
567
2.22M
    int i;
568
2.22M
    int max_bits = MIN(64, no_of_bits);
569
2.22M
    int no_leading_dots;
570
571
2.22M
    mask = UINT64_C(1) << (max_bits-1);
572
573
2.22M
    if (encoding & ENC_LITTLE_ENDIAN) {
574
        /* Bits within octet are numbered from LSB (0) to MSB (7).
575
         * The value in string is from most significant bit to lowest.
576
         * Calculate how many dots have to be printed at the beginning of string.
577
         */
578
1.18k
        no_leading_dots = (8 - ((bit_offset + no_of_bits) % 8)) % 8;
579
2.22M
    } else {
580
2.22M
        no_leading_dots = bit_offset % 8;
581
2.22M
    }
582
583
    /* Prepare the string, 256 pos for the bits and zero termination, + 64 for the spaces */
584
2.22M
    str = (char *)wmem_alloc0(scope, 256+64);
585
7.86M
    for (bit = 0; bit < no_leading_dots; bit++) {
586
5.64M
        if (bit && !(bit % 4)) {
587
552k
            str[str_p] = ' ';
588
552k
            str_p++;
589
552k
        }
590
5.64M
        str[str_p] = '.';
591
5.64M
        str_p++;
592
5.64M
    }
593
594
    /* read the bits for the int */
595
10.9M
    for (i = 0; i < max_bits; i++) {
596
8.74M
        if (bit && !(bit % 4)) {
597
1.47M
            str[str_p] = ' ';
598
1.47M
            str_p++;
599
1.47M
        }
600
8.74M
        if (bit && !(bit % 8)) {
601
509k
            str[str_p] = ' ';
602
509k
            str_p++;
603
509k
        }
604
8.74M
        bit++;
605
8.74M
        if ((value & mask) != 0) {
606
3.47M
            str[str_p] = '1';
607
3.47M
            str_p++;
608
5.26M
        } else {
609
5.26M
            str[str_p] = '0';
610
5.26M
            str_p++;
611
5.26M
        }
612
8.74M
        mask = mask>>1;
613
8.74M
    }
614
615
9.71M
    for (; bit % 8; bit++) {
616
7.49M
        if (bit && !(bit % 4)) {
617
1.21M
            str[str_p] = ' ';
618
1.21M
            str_p++;
619
1.21M
        }
620
7.49M
        str[str_p] = '.';
621
7.49M
        str_p++;
622
7.49M
    }
623
2.22M
    return str;
624
2.22M
}
625
626
char *
627
guid_to_str(wmem_allocator_t *scope, const e_guid_t *guid)
628
1.77k
{
629
1.77k
    char *buf;
630
631
1.77k
    buf = (char *)wmem_alloc(scope, GUID_STR_LEN);
632
1.77k
    return guid_to_str_buf(guid, buf, GUID_STR_LEN);
633
1.77k
}
634
635
char *
636
guid_to_str_buf(const e_guid_t *guid, char *buf, int buf_len)
637
1.77k
{
638
1.77k
    char *tempptr = buf;
639
640
1.77k
    if (buf_len < GUID_STR_LEN) {
641
0
        (void) g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
642
0
        return buf;
643
0
    }
644
645
    /* 37 bytes */
646
1.77k
    tempptr    = dword_to_hex(tempptr, guid->data1);        /*  8 bytes */
647
1.77k
    *tempptr++ = '-';                                       /*  1 byte */
648
1.77k
    tempptr    = word_to_hex(tempptr, guid->data2);         /*  4 bytes */
649
1.77k
    *tempptr++ = '-';                                       /*  1 byte */
650
1.77k
    tempptr    = word_to_hex(tempptr, guid->data3);         /*  4 bytes */
651
1.77k
    *tempptr++ = '-';                                       /*  1 byte */
652
1.77k
    tempptr    = bytes_to_hexstr(tempptr, &guid->data4[0], 2);  /*  4 bytes */
653
1.77k
    *tempptr++ = '-';                                       /*  1 byte */
654
1.77k
    tempptr    = bytes_to_hexstr(tempptr, &guid->data4[2], 6);  /* 12 bytes */
655
656
1.77k
    *tempptr   = '\0';
657
1.77k
    return buf;
658
1.77k
}
659
660
const char *
661
port_type_to_str (port_type type)
662
0
{
663
0
    switch (type) {
664
0
        case PT_NONE:       return "NONE";
665
0
        case PT_SCTP:       return "SCTP";
666
0
        case PT_TCP:        return "TCP";
667
0
        case PT_UDP:        return "UDP";
668
0
        case PT_DCCP:       return "DCCP";
669
0
        case PT_IPX:        return "IPX";
670
0
        case PT_DDP:        return "DDP";
671
0
        case PT_IDP:        return "IDP";
672
0
        case PT_USB:        return "USB";
673
0
        case PT_I2C:        return "I2C";
674
0
        case PT_IBQP:       return "IBQP";
675
0
        case PT_BLUETOOTH:  return "BLUETOOTH";
676
0
        case PT_IWARP_MPA:  return "IWARP_MPA";
677
0
        default:            return "[Unknown]";
678
0
    }
679
0
}
680
681
/*
682
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
683
 *
684
 * Local variables:
685
 * c-basic-offset: 4
686
 * tab-width: 8
687
 * indent-tabs-mode: nil
688
 * End:
689
 *
690
 * vi: set shiftwidth=4 tabstop=8 expandtab:
691
 * :indentSize=4:tabSize=8:noTabs=true:
692
 */