File: massip-addr.h

package info (click to toggle)
masscan 2%3A1.3.2%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid, trixie
  • size: 2,704 kB
  • sloc: ansic: 37,158; javascript: 256; makefile: 80
file content (158 lines) | stat: -rw-r--r-- 4,628 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
    Simple module for handling addresses (IPv6, IPv4, MAC).
    Also implements a 128-bit type for dealing with addresses.
 
    This is the module that almost all the other code depends
    upon, because everything else deals with the IP address
    types defined here.
    
*/
#ifndef MASSIP_ADDR_H
#define MASSIP_ADDR_H
#include <stdint.h>
#include <stddef.h>

#if defined(_MSC_VER) && !defined(inline)
#define inline __inline
#endif
#if defined(_MSC_VER)
#pragma warning(disable: 4201)
#endif

/**
 * An IPv6 address is represented as two 64-bit integers intead of a single
 * 128-bit integer. This is because curently (year 2020) most compilers
 * do not support the `uint128_t` type, but all relevant ones do support
 * the `uint64_t` type.
 */
struct ipv6address {uint64_t hi; uint64_t lo;};
typedef struct ipv6address ipv6address;
typedef struct ipv6address ipv6address_t;

/**
 * IPv4 addresses are represented simply with an integer.
 */
typedef unsigned ipv4address;
typedef ipv4address ipv4address_t;

/**
 * MAC address (layer 2).  Since we have canonical types for IPv4/IPv6
 * addresses, we may as well have a canonical type for MAC addresses,
 * too.
 */
struct macaddress_t {unsigned char addr[6];};
typedef struct macaddress_t macaddress_t;

/**
 * In many cases we need to do arithmetic on IPv6 addresses, treating
 * them as a large 128-bit integer. Thus, we declare our own 128-bit
 * integer type (and some accompanying math functions). But it's
 * still just the same as a 128-bit integer.
 */
typedef ipv6address massint128_t;


/**
 * Most of the code in this project is agnostic to the version of IP
 * addresses (IPv4 or IPv6). Therefore, we represnet them as a union
 * distinguished by a version number. The `version` is an integer
 * with a value of either 4 or 6.
 */
struct ipaddress {
    union {
        unsigned ipv4;
        ipv6address ipv6;
    };
    unsigned char version;
};
typedef struct ipaddress ipaddress;

static inline int ipv6address_is_zero(ipv6address_t a) {
    return a.hi == 0 && a.lo == 0;
}
#define massint128_is_zero ipv6address_is_zero

static inline int ipv6address_is_invalid(ipv6address_t a) {
    return a.hi == ~0ULL && a.lo == ~0ULL;
}
static inline int ipv6address_is_equal(ipv6address_t a, ipv6address_t b) {
    return a.hi == b.hi && a.lo == b.lo;
}
static inline int ipv6address_is_lessthan(ipv6address_t a, ipv6address_t b) {
    return (a.hi == b.hi)?(a.lo < b.lo):(a.hi < b.hi);
}

int ipv6address_is_equal_prefixed(ipv6address_t lhs, ipv6address_t rhs, unsigned prefix);


static inline ipv6address ipv6address_from_bytes(const unsigned char *buf) {
    ipv6address addr;
    addr.hi = (uint64_t)buf[ 0] << 56
            | (uint64_t)buf[ 1] << 48
            | (uint64_t)buf[ 2] << 40
            | (uint64_t)buf[ 3] << 32
            | (uint64_t)buf[ 4] << 24
            | (uint64_t)buf[ 5] << 16
            | (uint64_t)buf[ 6] <<  8
            | (uint64_t)buf[ 7] <<  0;
    addr.lo = (uint64_t)buf[ 8] << 56
            | (uint64_t)buf[ 9] << 48
            | (uint64_t)buf[10] << 40
            | (uint64_t)buf[11] << 32
            | (uint64_t)buf[12] << 24
            | (uint64_t)buf[13] << 16
            | (uint64_t)buf[14] <<  8
            | (uint64_t)buf[15] <<  0;
    return addr;
}
static inline macaddress_t macaddress_from_bytes(const void *vbuf)
{
    const unsigned char *buf = (const unsigned char *)vbuf;
    macaddress_t result;
    result.addr[0] = buf[0];
    result.addr[1] = buf[1];
    result.addr[2] = buf[2];
    result.addr[3] = buf[3];
    result.addr[4] = buf[4];
    result.addr[5] = buf[5];
    return result;
}
static inline int macaddress_is_zero(macaddress_t mac)
{
    return mac.addr[0] == 0
    && mac.addr[1] == 0
    && mac.addr[2] == 0
    && mac.addr[3] == 0
    && mac.addr[4] == 0
    && mac.addr[5] == 0;
}
static inline int macaddress_is_equal(macaddress_t lhs, macaddress_t rhs)
{
    return lhs.addr[0] == rhs.addr[0]
    && lhs.addr[1] == rhs.addr[1]
    && lhs.addr[2] == rhs.addr[2]
    && lhs.addr[3] == rhs.addr[3]
    && lhs.addr[4] == rhs.addr[4]
    && lhs.addr[5] == rhs.addr[5];
}

/**
 * Return a buffer with the formatted address
 */
typedef struct ipaddress_formatted {
    char string[48];
} ipaddress_formatted_t;

struct ipaddress_formatted ipv6address_fmt(ipv6address a);
struct ipaddress_formatted ipv4address_fmt(ipv4address a);
struct ipaddress_formatted ipaddress_fmt(ipaddress a);
struct ipaddress_formatted macaddress_fmt(macaddress_t a);

unsigned massint128_bitcount(massint128_t num);

/**
 * @return 0 on success, 1 on failure
 */
int ipv6address_selftest(void);

#endif