diff options
| -rw-r--r-- | .coderabbit.yaml | 29 | ||||
| l--------- | .github/copilot-instructions.md | 1 | ||||
| -rw-r--r-- | .github/mergify.yml | 22 | ||||
| -rw-r--r-- | .github/workflows/cla-check.yml | 18 | ||||
| -rw-r--r-- | .github/workflows/pr-mirror-repo-sync.yml | 30 | ||||
| -rw-r--r-- | .github/workflows/trigger-rebuild-repo-package.yml | 4 | ||||
| -rw-r--r-- | .gitignore | 79 | ||||
| -rw-r--r-- | AGENTS.md | 47 | ||||
| -rw-r--r-- | Jenkinsfile | 23 | ||||
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | debian/changelog | 15 | ||||
| -rw-r--r-- | debian/control | 4 | ||||
| -rw-r--r-- | src/Makefile.am | 6 | ||||
| -rw-r--r-- | src/ipaddrcheck_functions.c | 87 | ||||
| -rw-r--r-- | src/ipaddrcheck_functions.h | 7 | ||||
| -rw-r--r-- | src/ipaddrcheck_functions.o | bin | 55552 -> 0 bytes | |||
| -rw-r--r-- | tests/Makefile.am | 4 | ||||
| -rw-r--r-- | tests/check_ipaddrcheck.c | 21 | ||||
| -rwxr-xr-x | tests/integration_tests.sh | 54 |
19 files changed, 365 insertions, 88 deletions
diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 0000000..bb10f3a --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,29 @@ +# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json +# +# Per-repo CodeRabbit override for vyos/ipaddrcheck. +# +# Most behavior is inherited from the org-level central baseline at +# https://github.com/vyos/coderabbit/blob/production/.coderabbit.yaml +# (loaded automatically because the central repo is named `coderabbit` +# under the same GitHub org as this repo). +# +# When this repo has a VyOS-Networks mirror, this file is propagated by +# the gen-1 mirror pipeline. CodeRabbit's Atlassian/Jira OAuth grant is +# attached to the VyOS-Networks org only (one GitHub-org → Jira-tenant +# link per install), so `usage: auto` self-disables on the public source +# and activates on the private mirror — one file, both orgs. + +# Opt this repo into the inheritance chain. Without this, the file below +# would entirely REPLACE the central baseline rather than merge per-field +# on top of it — inheritance is disabled by default per CodeRabbit's +# schema (https://docs.coderabbit.ai/configuration/configuration-inheritance). +inheritance: true + +knowledge_base: + jira: + # `auto` is the cross-org-safe value: enabled on private/internal + # mirror repos where Jira OAuth is connected, disabled on the public + # source where it is not. + usage: auto + project_keys: + - VD diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 120000 index 0000000..be77ac8 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1 @@ +../AGENTS.md
\ No newline at end of file diff --git a/.github/mergify.yml b/.github/mergify.yml new file mode 100644 index 0000000..0617580 --- /dev/null +++ b/.github/mergify.yml @@ -0,0 +1,22 @@ +# yaml-language-server: $schema=https://docs.mergify.com/configuration/file-format/ +# Mergify configuration for vyos/ipaddrcheck. +# +# Inherits the central baseline from vyos/mergify:.mergify.yml. The central +# baseline provides: +# - `defaults.actions.backport.ignore_conflicts: false` +# - `pull_request_rules` → label conflicting PRs with `conflicts`; +# T-ID format checks on PR title and commit messages. +# - `commands_restrictions` → restrict @Mergifyio slash commands to the +# org Maintainers team + vyosbot. Resolves correctly on both sides of +# the cross-org mirror: vyos/mergify uses @vyos/maintainers, +# VyOS-Networks/mergify uses @VyOS-Networks/maintainers. +# +# Replaces the inline T8531 predecessor config. Rollout context: +# T8782 (Mergify central-config rollout), T8852 (fleet migration to +# `extends:`). See https://vyos.dev/T8782, https://vyos.dev/T8852, +# and the Confluence spec at +# https://vyos.atlassian.net/wiki/spaces/VYOS/pages/849477640. + +extends: mergify +merge_protections_settings: + reporting_method: check-runs diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml new file mode 100644 index 0000000..625ff78 --- /dev/null +++ b/.github/workflows/cla-check.yml @@ -0,0 +1,18 @@ +name: "CLA Check" + +permissions: + actions: write + contents: read + pull-requests: write + statuses: write + +on: + pull_request_target: + types: [opened, synchronize, closed] + issue_comment: + types: [created] + +jobs: + call-cla-assistant: + uses: vyos/vyos-cla-signatures/.github/workflows/cla-reusable.yml@current + secrets: inherit
\ No newline at end of file diff --git a/.github/workflows/pr-mirror-repo-sync.yml b/.github/workflows/pr-mirror-repo-sync.yml new file mode 100644 index 0000000..0f6c449 --- /dev/null +++ b/.github/workflows/pr-mirror-repo-sync.yml @@ -0,0 +1,30 @@ +# .github/workflows/pr-mirror-repo-sync.yml +# DO NOT EDIT — managed by mirror-pipeline rollout. +# To opt out: set vars.MIRROR_ENABLED=false in this repo's Actions variables. +name: PR Mirror and Repo Sync + +on: + pull_request_target: + types: [closed] + branches: [current] + workflow_dispatch: + inputs: + sync_branch: + required: true + type: string + +permissions: + contents: write + pull-requests: write + issues: write + +jobs: + call: + if: | + github.repository_owner == 'vyos' + && (github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch') + && vars.MIRROR_ENABLED != 'false' + uses: vyos/.github/.github/workflows/pr-mirror-repo-sync.yml@current + with: + sync_branch: ${{ inputs.sync_branch || github.event.pull_request.base.ref }} + secrets: inherit diff --git a/.github/workflows/trigger-rebuild-repo-package.yml b/.github/workflows/trigger-rebuild-repo-package.yml index 37ec832..e26669b 100644 --- a/.github/workflows/trigger-rebuild-repo-package.yml +++ b/.github/workflows/trigger-rebuild-repo-package.yml @@ -6,6 +6,8 @@ on: - closed branches: - current + - circinus + - sagitta workflow_dispatch: jobs: @@ -23,7 +25,7 @@ jobs: needs: get_repo_name uses: vyos/.github/.github/workflows/trigger-rebuild-repo-package.yml@current with: - branch: ${{ github.ref_name }} + branch: ${{ github.event.pull_request.base.ref }} package_name: ${{ needs.get_repo_name.outputs.PACKAGE_NAME }} secrets: REMOTE_OWNER: ${{ secrets.REMOTE_OWNER }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f267c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,79 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Autotools-generated files + +Makefile +Makefile.in +aclocal.m4 +autom4te.cache/ +compile +config.status +configure +depcomp +install-sh +man/Makefile +man/Makefile.in +missing +src/.deps/ +src/.dirstamp +src/Makefile +src/Makefile.in +src/config.h +src/config.h.in +src/stamp-h1 +test-driver +tests/.deps/ +tests/Makefile +tests/Makefile.in + +# Misc + +*.log +*.trs + +# Build artifacts + +src/ipaddrcheck +tests/check_ipaddrcheck diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..ba2e3e5 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,47 @@ +# AGENTS.md + +## Project purpose + +C utility for IPv4/IPv6 address and prefix validation in shell scripts. Used by VyOS as the canonical "is this string a valid IP / network / host / CIDR?" checker invoked from XML validators and conf-mode scripts. Fast and exit-status-driven (intended for `if ipaddrcheck --is-ipv4...; then...`). + +## Tech stack + +- C, autotools (`configure.ac`, `Makefile.am`, autoconf 2.x). +- Dependencies: `libcidr` (parsing), `libpcre2-8` (regex), `check >= 0.9.4` (test framework). +- Debian packaging under `debian/`. Upstream autotools version `1.1` (`configure.ac`); current Debian package version `1.4` (`debian/changelog`). + +## Build / test / run + +``` +autoreconf -fi # generate configure +./configure +make +make check # uses libcheck unit tests under tests/ +make install # installs into AC_PREFIX_DEFAULT (/usr) +# Debian package +dpkg-buildpackage -uc -us -tc -b +``` + +## Repository layout + +- `src/` — C sources (`ipaddrcheck.c`, headers, autotools `Makefile.am`). +- `tests/` — libcheck C unit tests (`check_ipaddrcheck.c`) and shell integration tests (`assert.sh`, `integration_tests.sh`). +- `man/` — manpages. +- `debian/` — Debian packaging. +- `configure.ac`, `Makefile.am`, `INSTALL`, `NEWS`, `ChangeLog`, `AUTHORS`, `COPYING` (GPL-2), `COPYING-LGPL` (LGPL-2.1). + +## Cross-repo context + +One of the canonical 14 VyOS-image build packages, listed in an internal repository. Built into VyOS images by `vyos-build` and invoked at runtime by `vyos-1x` validators and conf-mode scripts. Sits in the §3.5 native-libraries category alongside `hvinfo`, `udp-broadcast-relay`, etc. + +## Conventions + +- Commit / PR title format: `component: T12345: description` (Phorge task ID at https://vyos.dev mandatory). Enforced by `vyos/.github` reusable workflows where consumed. +- Branch model: `current` (rolling), `circinus` (1.5 LTS), `sagitta` (1.4 LTS), `equuleus` (1.3 LTS). +- Maintained by the VyOS team (`maintainers@vyos.net`); license is GPL-2 + LGPL-2.1 dual. + +## Notes for future contributors + +- Used as a CLI-level validator — exit status 0/1 is the contract. Don't break stdout/stderr conventions or add chatty output. +- `libcidr` is by Matthew Fuller (http://www.over-yonder.net/~fullermd/projects/libcidr) — Debian-packaged. +- Adding a new flag: extend `src/ipaddrcheck.c`'s argument table and add a libcheck test under `tests/`. diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 21a6829..0000000 --- a/Jenkinsfile +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2020-2021 VyOS maintainers and contributors -// -// This program is free software; you can redistribute it and/or modify -// in order to easy exprort images built to "external" world -// it under the terms of the GNU General Public License version 2 or later as -// published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -@NonCPS - -// Using a version specifier library, use 'current' branch. The underscore (_) -// is not a typo! You need this underscore if the line immediately after the -// @Library annotation is not an import statement! -@Library('vyos-build@current')_ - -// Start package build using library function from https://github.com/vyos/vyos-build -buildPackage(null, null, null, true) diff --git a/configure.ac b/configure.ac index 567bfd9..482523c 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,6 @@ AC_COPYRIGHT([Copyright (c) 2024 VyOS maintainers and contributors.]) #AC_PROG_CC AM_PROG_CC_C_O -AC_CHECK_HEADER([pcre.h], [], [AC_MSG_FAILURE([pcre.h is not found.])]) AC_CHECK_HEADER([libcidr.h], [], [AC_MSG_FAILURE([libcidr.h is not found.])]) AM_INIT_AUTOMAKE([gnu no-dist-gzip dist-bzip2 subdir-objects]) @@ -14,5 +13,6 @@ AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile man/Makefile]) AC_CONFIG_HEADERS([src/config.h]) PKG_CHECK_MODULES([CHECK], [check >= 0.9.4]) +PKG_CHECK_MODULES([PCRE2], [libpcre2-8]) AC_OUTPUT diff --git a/debian/changelog b/debian/changelog index 6405fd7..d51c754 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +ipaddrcheck (1.4) unstable; urgency=medium + + * Do not disallow all-zero host part IPv6 addresses for host and interface address checks (Daniil Baturin). + + -- Daniil Baturin <daniil@vyos.io> Fri, 05 Dec 2025 15:04:03 +0000 + +ipaddrcheck (1.3) unstable; urgency=medium + + * New option --range-prefix-length to require ranges to be within a subnet (Daniil Baturin). + * Options for checking IP ranges: --is-ipv4-range and --is-ipv6-range (Daniil Baturin). + * Fixed linker flags to build correctly on Debian Bullseye (John Eastabrook). + * Removed stale dependency on libcidr0-dev (Christian Breunig). + + -- Daniil Baturin <daniil@vyos.io> Tue, 25 Feb 2025 18:21:43 +0000 + ipaddrcheck (1.2) unstable; urgency=medium * Correct recognition of IPv4 /31 and IPv6 /127 as valid host addresses. diff --git a/debian/control b/debian/control index ac61240..bc6785a 100644 --- a/debian/control +++ b/debian/control @@ -2,11 +2,11 @@ Source: ipaddrcheck Section: contrib/net Priority: extra Maintainer: VyOS Package Maintainers <maintainers@vyos.net> -Build-Depends: autoconf, debhelper (>= 9), libpcre3-dev, libcidr-dev, check +Build-Depends: autoconf, debhelper (>= 9), libpcre2-dev, libcidr-dev, check Standards-Version: 3.9.6 Package: ipaddrcheck Architecture: any -Depends: libpcre3, libcidr0, ${shlibs:Depends}, ${misc:Depends} +Depends: libpcre2-8-0, libcidr0, ${shlibs:Depends}, ${misc:Depends} Description: IPv4 and IPv6 address validation utility A validation utility for IPv4 and IPv6 addresses. diff --git a/src/Makefile.am b/src/Makefile.am index 1c43bae..ce8ea59 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ -AM_CFLAGS = --pedantic -Wall -Werror -Wno-error=format-overflow= -std=c99 -O2 -AM_LDFLAGS = +AM_CFLAGS = --pedantic -Wall -Werror -std=c99 -O2 +AM_CPPFLAGS = $(PCRE2_CFLAGS) ipaddrcheck_SOURCES = ipaddrcheck.c ipaddrcheck_functions.c -ipaddrcheck_LDADD = -lcidr -lpcre +ipaddrcheck_LDADD = -lcidr $(PCRE2_LIBS) bin_PROGRAMS = ipaddrcheck diff --git a/src/ipaddrcheck_functions.c b/src/ipaddrcheck_functions.c index 2d2dff3..09830a1 100644 --- a/src/ipaddrcheck_functions.c +++ b/src/ipaddrcheck_functions.c @@ -2,7 +2,7 @@ * ipaddrcheck_functions.c: IPv4/IPv6 validation functions for ipaddrcheck * * Copyright (C) 2013 Daniil Baturin - * Copyright (C) 2018-2024 VyOS maintainers and contributors + * Copyright (C) 2018-2025 VyOS maintainers and contributors * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -41,25 +41,31 @@ int regex_matches(const char* regex, const char* str) { - int offsets[1]; - pcre *re; + pcre2_code *re; int rc; - const char *error; - int erroffset; + int out; + int error; + PCRE2_SIZE erroffset; - re = pcre_compile(regex, 0, &error, &erroffset, NULL); + re = pcre2_compile((PCRE2_SPTR)regex, PCRE2_ZERO_TERMINATED, 0, &error, &erroffset, NULL); assert(re != NULL); - rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, offsets, 1); + pcre2_match_data *match = pcre2_match_data_create_from_pattern(re, NULL); + + rc = pcre2_match(re, (PCRE2_SPTR)str, strlen(str), 0, 0, match, NULL); if( rc >= 0) { - return RESULT_SUCCESS; + out = RESULT_SUCCESS; } else { - return RESULT_FAILURE; + out = RESULT_FAILURE; } + + pcre2_match_data_free(match); + pcre2_code_free(re); + return out; } @@ -319,29 +325,15 @@ int is_ipv6(CIDR *address) return(result); } -/* Is it a correct IPv6 host address? */ +/* Is it a correct IPv6 host address? + Everything except the unspecified address is. + */ int is_ipv6_host(CIDR *address) { int result; - /* We reuse the same logic that prevents IPv4 network addresses - from being assigned to interfaces (address == network_address), - but the reason is slightly differnt. - - As per https://www.rfc-editor.org/rfc/rfc4291 section 2.6.1, - >[Subnet-Router anycast address] is syntactically - >the same as a unicast address for an interface on the link with the - >interface identifier set to zero. - - So, the first address of the subnet must not be used for link addresses, - even if the semantic reason is different. - There's absolutely nothing wrong with assigning the last address, though, - since there's no broadcast in IPv6. - */ - if( (cidr_get_proto(address) == CIDR_IPV6) && - ((cidr_equals(address, cidr_addr_network(address)) < 0) || - (cidr_get_pflen(address) >= 127)) ) + (cidr_equals(address, cidr_from_str(IPV6_UNSPECIFIED)) != 0) ) { result = RESULT_SUCCESS; } @@ -546,7 +538,10 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) If the regex check succeeded, we know the hyphen is there. */ split_range(range_str, left, right); - if( !is_ipv4_single(left) ) + CIDR* left_addr = cidr_from_str(left); + CIDR* right_addr = cidr_from_str(right); + + if( !(is_ipv4_single(left) && is_valid_address(left_addr)) ) { if( verbose ) { @@ -554,7 +549,7 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) } result = RESULT_FAILURE; } - else if( !is_ipv4_single(right) ) + else if( !(is_ipv4_single(right) && is_valid_address(right_addr)) ) { if( verbose ) { @@ -564,12 +559,10 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) } else { - CIDR* left_addr = cidr_from_str(left); - CIDR* right_addr = cidr_from_str(right); struct in_addr* left_in_addr = cidr_to_inaddr(left_addr, NULL); struct in_addr* right_in_addr = cidr_to_inaddr(right_addr, NULL); - if( left_in_addr->s_addr <= right_in_addr->s_addr ) + if( ntohl(left_in_addr->s_addr) <= ntohl(right_in_addr->s_addr) ) { /* If non-zero prefix_length is given, check if the right address is within the network of the first one. */ @@ -577,10 +570,13 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) { char left_pref_str[19]; - /* XXX: Prefix length size is checked elsewhere, so it can't be more than 2 characters (32) + /* XXX: Prefix length size is checked elsewhere with a regex, so it can't be more than 2 characters (32) and overflow cannot occur. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-overflow=" sprintf(left_pref_str, "%s/%u", left, prefix_length); + #pragma GCC diagnostic pop CIDR* left_addr_with_pref = cidr_from_str(left_pref_str); CIDR* left_net = cidr_addr_network(left_addr_with_pref); if( cidr_contains(left_net, right_addr) == 0 ) @@ -608,9 +604,9 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) result = RESULT_FAILURE; } - cidr_free(left_addr); - cidr_free(right_addr); } + cidr_free(left_addr); + cidr_free(right_addr); } return(result); @@ -644,7 +640,11 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) If the regex check succeeded, we know the hyphen is there. */ split_range(range_str, left, right); - if( !is_ipv6_single(left) ) + CIDR* left_addr = cidr_from_str(left); + CIDR* right_addr = cidr_from_str(right); + + if( !(is_ipv6_single(left) && + is_valid_address(left_addr) && !duplicate_double_colons(left)) ) { if( verbose ) { @@ -652,7 +652,8 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) } result = RESULT_FAILURE; } - else if( !is_ipv6_single(right) ) + else if( !(is_ipv6_single(right) && + is_valid_address(right_addr) && !duplicate_double_colons(right)) ) { if( verbose ) { @@ -662,8 +663,6 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) } else { - CIDR* left_addr = cidr_from_str(left); - CIDR* right_addr = cidr_from_str(right); struct in6_addr* left_in6_addr = cidr_to_in6addr(left_addr, NULL); struct in6_addr* right_in6_addr = cidr_to_in6addr(right_addr, NULL); @@ -675,10 +674,13 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) { char left_pref_str[44]; - /* XXX: Prefix length size is checked elsewhere, so it can't be more than 3 characters (128) + /* XXX: Prefix length size is checked elsewhere with a regex, so it can't be more than 3 characters (128) and overflow cannot occur. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-overflow=" sprintf(left_pref_str, "%s/%u", left, prefix_length); + #pragma GCC diagnostic pop CIDR* left_addr_with_pref = cidr_from_str(left_pref_str); CIDR* left_net = cidr_addr_network(left_addr_with_pref); if( cidr_contains(left_net, right_addr) == 0 ) @@ -705,10 +707,9 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) } result = RESULT_FAILURE; } - - cidr_free(left_addr); - cidr_free(right_addr); } + cidr_free(left_addr); + cidr_free(right_addr); } return(result); diff --git a/src/ipaddrcheck_functions.h b/src/ipaddrcheck_functions.h index 9b5e55f..bd131cf 100644 --- a/src/ipaddrcheck_functions.h +++ b/src/ipaddrcheck_functions.h @@ -2,7 +2,7 @@ * ipaddrcheck_functions.h: macros and prototypes for ipaddrcheck * * Copyright (C) 2013 Daniil Baturin - * Copyright (C) 2018-2024 VyOS maintainers and contributors + * Copyright (C) 2018-2025 VyOS maintainers and contributors * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,11 +23,13 @@ #ifndef IPADDRCHECK_FUNCTIONS_H #define IPADDRCHECK_FUNCTIONS_H +#define PCRE2_CODE_UNIT_WIDTH 8 + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <getopt.h> -#include <pcre.h> +#include <pcre2.h> #include <libcidr.h> #define INVALID_PROTO -1 @@ -48,6 +50,7 @@ #define IPV6_MULTICAST "ff00::/8" #define IPV6_LINKLOCAL "fe80::/64" #define IPV6_LOOPBACK "::1/128" +#define IPV6_UNSPECIFIED "::/0" #define NO_LOOPBACK 0 #define LOOPBACK_ALLOWED 1 diff --git a/src/ipaddrcheck_functions.o b/src/ipaddrcheck_functions.o Binary files differdeleted file mode 100644 index a689dac..0000000 --- a/src/ipaddrcheck_functions.o +++ /dev/null diff --git a/tests/Makefile.am b/tests/Makefile.am index 5c0a09a..f7b824a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,3 +1,5 @@ +AM_CPPFLAGS = $(PCRE2_CFLAGS) + TESTS = check_ipaddrcheck integration_tests.sh TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) PATH=.:$(top_srcdir)/src:$$PATH @@ -5,4 +7,4 @@ TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) PATH=.:$(top_srcdir)/src:$$PATH check_PROGRAMS = check_ipaddrcheck check_ipaddrcheck_SOURCES = check_ipaddrcheck.c ../src/ipaddrcheck_functions.c check_ipaddrcheck_CFLAGS = @CHECK_CFLAGS@ -check_ipaddrcheck_LDADD = -lcidr -lpcre @CHECK_LIBS@ +check_ipaddrcheck_LDADD = -lcidr $(PCRE2_LIBS) @CHECK_LIBS@ diff --git a/tests/check_ipaddrcheck.c b/tests/check_ipaddrcheck.c index ebae1e1..fe3876c 100644 --- a/tests/check_ipaddrcheck.c +++ b/tests/check_ipaddrcheck.c @@ -2,7 +2,7 @@ * check_ipaddrcheck.c: ipaddrcheck unit tests * * Copyright (C) 2013 Daniil Baturin - * Copyright (C) 2018-2024 VyOS maintainers and contributors + * Copyright (C) 2018-2025 VyOS maintainers and contributors * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 or later as @@ -289,11 +289,6 @@ START_TEST (test_is_ipv6_host) CIDR* good_address_cidr = cidr_from_str(good_address_str_cidr); ck_assert_int_eq(is_ipv6_host(good_address_cidr), RESULT_SUCCESS); cidr_free(good_address_cidr); - - char* bad_address_str = "2001:db8:f::/48"; - CIDR* bad_address = cidr_from_str(bad_address_str); - ck_assert_int_eq(is_ipv6_host(bad_address), RESULT_FAILURE); - cidr_free(bad_address); } END_TEST @@ -367,15 +362,20 @@ START_TEST (test_is_any_host) ck_assert_int_eq(is_any_host(good_address_v6), RESULT_SUCCESS); cidr_free(good_address_v6); + char* good_address_str_v6_all_zero = "2001:db8::/32"; + CIDR* good_address_v6_all_zero = cidr_from_str(good_address_str_v6_all_zero); + ck_assert_int_eq(is_any_host(good_address_v6_all_zero), RESULT_SUCCESS); + cidr_free(good_address_v6_all_zero); + char* bad_address_str_v4 = "192.0.2.0/24"; CIDR* bad_address_v4 = cidr_from_str(bad_address_str_v4); ck_assert_int_eq(is_any_host(bad_address_v4), RESULT_FAILURE); cidr_free(bad_address_v4); - char* bad_address_str_v6 = "2001:db8::/32"; - CIDR* bad_address_v6 = cidr_from_str(bad_address_str_v6); - ck_assert_int_eq(is_any_host(bad_address_v6), RESULT_FAILURE); - cidr_free(bad_address_v6); + char* bad_address_str_v6_unspec = "::/0"; + CIDR* bad_address_v6_unspec = cidr_from_str(bad_address_str_v6_unspec); + ck_assert_int_eq(is_any_host(bad_address_v6_unspec), RESULT_FAILURE); + cidr_free(bad_address_v6_unspec); } END_TEST @@ -408,6 +408,7 @@ START_TEST (test_is_ipv4_range) ck_assert_int_eq(is_ipv4_range("192.0.2.0-192.0.2.10", 0, 1), RESULT_SUCCESS); ck_assert_int_eq(is_ipv4_range("192.0.2.-", 0, 1), RESULT_FAILURE); ck_assert_int_eq(is_ipv4_range("192.0.2.99-192.0.2.11", 0, 1), RESULT_FAILURE); + ck_assert_int_eq(is_ipv4_range("192.0.2.0-1.8.2.1", 0, 1), RESULT_FAILURE); } END_TEST diff --git a/tests/integration_tests.sh b/tests/integration_tests.sh index 3a1e4ea..9c937df 100755 --- a/tests/integration_tests.sh +++ b/tests/integration_tests.sh @@ -3,7 +3,7 @@ # integration_tests.sh: ipaddrcheck integration tests # # Copyright (C) 2013 Daniil Baturin -# Copyright (C) 2018-2024 VyOS maintainers and contributors +# Copyright (C) 2018-2025 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -56,6 +56,29 @@ ipv4_range_negative=( 192.0.2.-192.0.2.100 192.0.2.0- 192.0.2.200-192.0.2.100 + 192.0.2.1-192.0.2.500 +) + +ipv4_interface_address_positive=( + 192.0.2.1/24 + 192.168.1.0/23 +) + +ipv4_interface_address_negative=( + 192.0.2.0/24 # Network address + 192.0.2.255/24 # Broadcast + 224.0.0.1/24 # Multicast + 0.0.0.0/0 # Unspecified +) + +ipv6_interface_address_positive=( + 2001:db8::1/64 + 2001:db8::/64 +) + +ipv6_interface_address_negative=( + ff02::1:2 # Multicast + ::/0 # Unspecified ) ipv6_range_positive=( @@ -66,6 +89,8 @@ ipv6_range_negative=( 2001:db8:xx-2001:db8::99 2001:db:- 2001:db8::99-2001:db8::1 + 2001::db8::1:1-2001::db8::1::10 + 2001:db8:pqrs::1-2001:db8:uvwx::100 ) ipv6_single_positive=( @@ -108,10 +133,11 @@ ipv4_host_negative=( ipv6_host_positive=( 2001:db8:1::1/64 2001:db8:1::1/127 + 2001:db8:1::/64 # All-zero IPv6 addresses are valid host addresses ) ipv6_host_negative=( - 2001:db8::/32 + ::/0 ) string="garbage" @@ -269,7 +295,31 @@ done # --is-ipv6-net # --is-ipv6-multicast # --is-ipv6-link-local + # --is-valid-intf-address +for address in \ + ${ipv4_interface_address_positive[*]} +do + assert_raises "$IPADDRCHECK --is-valid-intf-address $address" 0 +done + +for address in \ + ${ipv4_interface_address_negative[*]} +do + assert_raises "$IPADDRCHECK --is-valid-intf-address $address" 1 +done + +for address in \ + ${ipv6_interface_address_positive[*]} +do + assert_raises "$IPADDRCHECK --is-valid-intf-address $address" 0 +done + +for address in \ + ${ipv6_interface_address_negative[*]} +do + assert_raises "$IPADDRCHECK --is-valid-intf-address $address" 1 +done # --is-ipv4-range for range in \ |
