nftables-napi 0.4.3 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -31,7 +31,11 @@ export interface NftManagerOptions {
31
31
 
32
32
  /** Options for adding a single address. */
33
33
  export interface AddAddressOptions {
34
- /** IPv4/IPv6 address or CIDR (e.g., "1.2.3.4", "10.0.0.0/8", "2001:db8::/32"). */
34
+ /**
35
+ * IPv4/IPv6 address or CIDR (e.g., "1.2.3.4", "10.0.0.0/8", "2001:db8::/32").
36
+ * Misaligned CIDR (host bits set) is auto-normalized to the network address,
37
+ * e.g. "10.0.0.5/24" becomes "10.0.0.0/24".
38
+ */
35
39
  ip: string;
36
40
  /** Target set name (must match one from constructor's ingressAddrSets or egressAddrSets). */
37
41
  set: string;
@@ -41,7 +45,11 @@ export interface AddAddressOptions {
41
45
 
42
46
  /** Options for removing a single address. */
43
47
  export interface RemoveAddressOptions {
44
- /** IPv4/IPv6 address or CIDR to remove (must match exactly as added). */
48
+ /**
49
+ * IPv4/IPv6 address or CIDR to remove (must match exactly as added).
50
+ * Misaligned CIDR (host bits set) is auto-normalized to the network address,
51
+ * e.g. "10.0.0.5/24" becomes "10.0.0.0/24".
52
+ */
45
53
  ip: string;
46
54
  /** Target set name (must match one from constructor's ingressAddrSets or egressAddrSets). */
47
55
  set: string;
@@ -49,7 +57,7 @@ export interface RemoveAddressOptions {
49
57
 
50
58
  /** Options for bulk adding addresses. */
51
59
  export interface AddAddressesOptions {
52
- /** Array of IPv4/IPv6 addresses or CIDRs. */
60
+ /** Array of IPv4/IPv6 addresses or CIDRs. Misaligned CIDR is auto-normalized. */
53
61
  ips: string[];
54
62
  /** Target set name (must match one from constructor's ingressAddrSets or egressAddrSets). */
55
63
  set: string;
@@ -59,7 +67,7 @@ export interface AddAddressesOptions {
59
67
 
60
68
  /** Options for bulk removing addresses. */
61
69
  export interface RemoveAddressesOptions {
62
- /** Array of IPv4/IPv6 addresses or CIDRs to remove. */
70
+ /** Array of IPv4/IPv6 addresses or CIDRs to remove. Misaligned CIDR is auto-normalized. */
63
71
  ips: string[];
64
72
  /** Target set name (must match one from constructor's ingressAddrSets or egressAddrSets). */
65
73
  set: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nftables-napi",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Native Node.js binding for nftables via libnftnl+libmnl — nftables firewall management",
5
5
  "author": {
6
6
  "name": "kastov",
@@ -155,24 +155,19 @@ CidrAddr parse_ip_or_cidr(const std::string& input) {
155
155
 
156
156
  auto prefix_len = static_cast<uint8_t>(prefix);
157
157
 
158
- // Verify host bits are zero
158
+ // Mask off host bits silently — input like "10.0.0.5/24" becomes
159
+ // "10.0.0.0/24", matching `ip route` and Python ipaddress(strict=False).
159
160
  uint32_t full_bytes = prefix_len / 8;
160
161
  uint32_t remainder_bits = prefix_len % 8;
161
162
 
162
- // Check boundary byte: host bits must be zero
163
163
  if (remainder_bits > 0 && full_bytes < ip.len) {
164
- uint8_t mask = static_cast<uint8_t>(0xFF >> remainder_bits);
165
- if ((ip.bytes[full_bytes] & mask) != 0) {
166
- return result; // host bits set in boundary byte
167
- }
164
+ uint8_t mask = static_cast<uint8_t>(0xFF << (8 - remainder_bits));
165
+ ip.bytes[full_bytes] &= mask;
168
166
  }
169
167
 
170
- // Check all bytes after the prefix boundary must be zero
171
- uint32_t start_check = full_bytes + (remainder_bits > 0 ? 1 : 0);
172
- for (uint32_t i = start_check; i < ip.len; ++i) {
173
- if (ip.bytes[i] != 0) {
174
- return result; // host bits set
175
- }
168
+ uint32_t start_zero = full_bytes + (remainder_bits > 0 ? 1 : 0);
169
+ for (uint32_t i = start_zero; i < ip.len; ++i) {
170
+ ip.bytes[i] = 0;
176
171
  }
177
172
 
178
173
  result.network = ip;
package/src/validation.h CHANGED
@@ -22,11 +22,17 @@ struct CidrAddr {
22
22
  };
23
23
 
24
24
  // Parse IP string or CIDR notation. Accepts:
25
- // "1.2.3.4" -> CidrAddr{network=1.2.3.4, end=1.2.3.5}
26
- // "10.0.0.0/8" -> CidrAddr{network=10.0.0.0, end=11.0.0.0}
27
- // "2001:db8::/32" -> CidrAddr{network=2001:db8::, end=2001:db9::}
25
+ // "1.2.3.4" -> CidrAddr{network=1.2.3.4, end=1.2.3.5}
26
+ // "10.0.0.0/8" -> CidrAddr{network=10.0.0.0, end=11.0.0.0}
27
+ // "2001:db8::/32" -> CidrAddr{network=2001:db8::, end=2001:db9::}
28
+ // "198.19.0.0/15" -> CidrAddr{network=198.18.0.0, end=198.20.0.0}
29
+ // (host bits silently masked off — see below)
30
+ //
31
+ // Misaligned CIDR (host bits set) is auto-normalized: host bits are
32
+ // masked off to obtain the network address. Matches `ip route` and
33
+ // Python ipaddress.ip_network(strict=False). Rejects only:
34
+ // /0 (too dangerous), prefix > family bits, malformed input.
28
35
  // Returns CidrAddr with network.family=Invalid on failure.
29
- // Rejects: host bits set (192.168.1.1/24), prefix > 32/128, /0 (too dangerous).
30
36
  [[nodiscard]] CidrAddr parse_ip_or_cidr(const std::string& input);
31
37
 
32
38
  struct PortVal {