Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/wsutil/inet_cidr.c
Line
Count
Source (jump to first uncovered line)
1
/* ipv4.c
2
 *
3
 * Wireshark - Network traffic analyzer
4
 * By Gerald Combs <gerald@wireshark.org>
5
 * Copyright 1998 Gerald Combs
6
 *
7
 * SPDX-License-Identifier: GPL-2.0-or-later
8
 */
9
10
#include "inet_cidr.h"
11
12
13
uint32_t
14
ws_ipv4_get_subnet_mask(const uint32_t mask_length)
15
130k
{
16
130k
  static const uint32_t masks[33] = {
17
130k
    0x00000000,
18
130k
    0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
19
130k
    0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
20
130k
    0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
21
130k
    0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
22
130k
    0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
23
130k
    0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
24
130k
    0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
25
130k
    0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff,
26
130k
  };
27
28
130k
  ws_assert(mask_length <= 32);
29
30
130k
  return masks[mask_length];
31
130k
}
32
33
static int
34
compare_ipv4(const ipv4_addr_and_mask *a, const ipv4_addr_and_mask *b)
35
0
{
36
0
    uint32_t addr_a, addr_b, nmask;
37
38
0
    nmask = MIN(a->nmask, b->nmask);
39
0
    addr_a = a->addr & nmask;
40
0
    addr_b = b->addr & nmask;
41
0
    if (addr_a < addr_b)
42
0
        return -1;
43
0
    if (addr_a > addr_b)
44
0
        return 1;
45
0
    return 0;
46
0
}
47
48
void
49
ws_ipv4_addr_and_mask_init(ipv4_addr_and_mask *dst, ws_in4_addr src_addr, int src_bits)
50
129k
{
51
129k
    dst->addr = g_ntohl(src_addr);
52
129k
    dst->nmask = ws_ipv4_get_subnet_mask(src_bits);
53
129k
}
54
55
bool
56
ws_ipv4_addr_and_mask_contains(const ipv4_addr_and_mask *ipv4, const ws_in4_addr *in_addr)
57
0
{
58
0
    ipv4_addr_and_mask addr_and_mask;
59
60
0
    addr_and_mask.addr = g_ntohl(*in_addr);
61
0
    addr_and_mask.nmask = ws_ipv4_get_subnet_mask(32);
62
0
    return compare_ipv4(ipv4, &addr_and_mask) == 0;
63
0
}
64
65
static const uint8_t bitmasks[9] =
66
    { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
67
68
static int
69
compare_ipv6(const ipv6_addr_and_prefix *a, const ipv6_addr_and_prefix *b)
70
0
{
71
0
    uint32_t prefix;
72
0
    int pos = 0;
73
74
0
    prefix = MIN(a->prefix, b->prefix); /* MIN() like IPv4 */
75
0
    prefix = MIN(prefix, 128);    /* sanitize, max prefix is 128 */
76
77
0
    while (prefix >= 8) {
78
0
        int byte_a = (int) (a->addr.bytes[pos]);
79
0
        int byte_b = (int) (b->addr.bytes[pos]);
80
81
0
        if (byte_a != byte_b) {
82
0
            return byte_a - byte_b;
83
0
        }
84
85
0
        prefix -= 8;
86
0
        pos++;
87
0
    }
88
89
0
    if (prefix != 0) {
90
0
        int byte_a = (int) (a->addr.bytes[pos] & (bitmasks[prefix]));
91
0
        int byte_b = (int) (b->addr.bytes[pos] & (bitmasks[prefix]));
92
93
0
        if (byte_a != byte_b) {
94
0
            return byte_a - byte_b;
95
0
        }
96
0
    }
97
98
0
    return 0;
99
0
}
100
101
102
bool
103
ws_ipv6_addr_and_prefix_contains(const ipv6_addr_and_prefix *ipv6, const ws_in6_addr *in_addr)
104
0
{
105
0
    ipv6_addr_and_prefix addr_and_mask;
106
107
0
    addr_and_mask.addr = *in_addr;
108
0
    addr_and_mask.prefix = 128;
109
0
    return compare_ipv6(ipv6, &addr_and_mask) == 0;
110
0
}