Commit e23b3c9c authored by Tom Gundersen's avatar Tom Gundersen

Squashed 'shared/n-dhcp4/' content from commit fb1d43449

git-subtree-dir: shared/n-dhcp4
git-subtree-split: fb1d43449ba80a54c70b0fe14cd0b7fd31d8504f
parents
#!/bin/bash
set -e
rm -Rf "./ci-build"
mkdir "./ci-build"
cd "./ci-build"
${CHERRY_LIB_MESONSETUP} . "${CHERRY_LIB_SRCDIR}"
${CHERRY_LIB_NINJABUILD}
${CHERRY_LIB_MESONTEST}
# no valgrind tests, since setns(2) is not supported by it
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
[*.{c,h}]
indent_style = space
indent_size = 8
[submodule "subprojects/c-list"]
path = subprojects/c-list
url = https://github.com/c-util/c-list.git
[submodule "subprojects/c-siphash"]
path = subprojects/c-siphash
url = https://github.com/c-util/c-siphash.git
[submodule "subprojects/c-stdaux"]
path = subprojects/c-stdaux
url = https://github.com/c-util/c-stdaux.git
os: linux
dist: trusty
language: c
services:
- docker
before_install:
- curl -O -L "https://raw.githubusercontent.com/cherry-pick/cherry-images/v1/scripts/vmrun"
- curl -O -L "https://raw.githubusercontent.com/cherry-pick/cherry-ci/v1/scripts/cherryci"
- chmod +x "./vmrun" "./cherryci"
jobs:
include:
- stage: test
script:
- ./vmrun -- ../src/cherryci -d ../src/.cherryci -s c-util -m
- script:
- ./vmrun -T armv7hl -- ../src/cherryci -d ../src/.cherryci -s c-util
- script:
- ./vmrun -T i686 -- ../src/cherryci -d ../src/.cherryci -s c-util
LICENSE:
This project is dual-licensed under both the Apache License, Version
2.0, and the GNU Lesser General Public License, Version 2.1+.
AUTHORS-ASL:
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
AUTHORS-LGPL:
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; If not, see <http://www.gnu.org/licenses/>.
COPYRIGHT: (ordered alphabetically)
Copyright (C) 2015-2019 Red Hat, Inc.
AUTHORS: (ordered alphabetically)
David Rheinsberg <david.rheinsberg@gmail.com>
Tom Gundersen <teg@jklm.no>
# n-dhcp4 - Dynamic Host Configuration Protocol for IPv4
## CHANGES WITH 1:
* Initial release of n-dhcp4, an implementation of the IPv4 Dynamic
Host Configuration Protocol as defined in RFC-2132+.
* This is a pre-release. The code is not yet ready for production.
Furthermore, the server implementation is incomplete and subject to
change.
The client implementation is considered complete, but the API is not
set in stone. We will have to adapt it according to the needs of the
users. Hence, this release does not provide any ABI stability
guarantees, yet.
* The n-dhcp4 project is now dual-licensed: ASL-2.0 and LGPL-2.1+
Contributions from: David Rheinsberg, Tom Gundersen
- Tübingen, 2019-05-10
n-dhcp4
=======
Dynamic Host Configuration Protocol for IPv4
The n-dhcp4 project implements the IPv4 Dynamic Host Configuration Protocol as
defined in RFC-2132+.
### Project
* **Website**: <https://nettools.github.io/n-dhcp4>
* **Bug Tracker**: <https://github.com/nettools/n-dhcp4/issues>
* **Mailing-List**: <https://groups.google.com/forum/#!forum/nettools-devel>
### Requirements
The requirements for this project are:
* `Linux kernel >= 3.19`
* `libc` (e.g., `glibc >= 2.16`)
At build-time, the following software is required:
* `meson >= 0.41`
* `pkg-config >= 0.29`
### Build
The meson build-system is used for this project. Contact upstream
documentation for detailed help. In most situations the following
commands are sufficient to build and install from source:
```sh
mkdir build
cd build
meson setup ..
ninja
meson test
ninja install
```
No custom configuration options are available.
### Repository:
- **web**: <https://github.com/nettools/n-dhcp4>
- **https**: `https://github.com/nettools/n-dhcp4.git`
- **ssh**: `git@github.com:nettools/n-dhcp4.git`
### License:
- **Apache-2.0** OR **LGPL-2.1-or-later**
- See AUTHORS file for details.
project(
'n-dhcp4',
'c',
version: '1',
license: 'Apache',
default_options: [
'c_std=c11',
],
)
project_description = 'Dynamic Host Configuration Protocol for IPv4'
add_project_arguments('-D_GNU_SOURCE', language: 'c')
mod_pkgconfig = import('pkgconfig')
sub_clist = subproject('c-list')
sub_csiphash = subproject('c-siphash')
sub_cstdaux = subproject('c-stdaux')
dep_clist = sub_clist.get_variable('libclist_dep')
dep_csiphash = sub_csiphash.get_variable('libcsiphash_dep')
dep_cstdaux = sub_cstdaux.get_variable('libcstdaux_dep')
subdir('src')
LIBNDHCP4_1 {
global:
n_dhcp4_client_config_new;
n_dhcp4_client_config_free;
n_dhcp4_client_config_set_ifindex;
n_dhcp4_client_config_set_transport;
n_dhcp4_client_config_set_request_broadcast;
n_dhcp4_client_config_set_mac;
n_dhcp4_client_config_set_broadcast_mac;
n_dhcp4_client_config_set_client_id;
n_dhcp4_client_probe_config_new;
n_dhcp4_client_probe_config_free;
n_dhcp4_client_probe_config_set_inform_only;
n_dhcp4_client_probe_config_set_init_reboot;
n_dhcp4_client_probe_config_set_requested_ip;
n_dhcp4_client_probe_config_set_start_delay;
n_dhcp4_client_probe_config_request_option;
n_dhcp4_client_probe_config_append_option;
n_dhcp4_client_new;
n_dhcp4_client_ref;
n_dhcp4_client_unref;
n_dhcp4_client_get_fd;
n_dhcp4_client_dispatch;
n_dhcp4_client_pop_event;
n_dhcp4_client_update_mtu;
n_dhcp4_client_probe;
n_dhcp4_client_probe_free;
n_dhcp4_client_probe_get_userdata;
n_dhcp4_client_probe_set_userdata;
n_dhcp4_client_lease_ref;
n_dhcp4_client_lease_unref;
n_dhcp4_client_lease_get_yiaddr;
n_dhcp4_client_lease_get_lifetime;
n_dhcp4_client_lease_query;
n_dhcp4_client_lease_select;
n_dhcp4_client_lease_accept;
n_dhcp4_client_lease_decline;
n_dhcp4_server_config_new;
n_dhcp4_server_config_free;
n_dhcp4_server_config_set_ifindex;
n_dhcp4_server_new;
n_dhcp4_server_ref;
n_dhcp4_server_unref;
n_dhcp4_server_get_fd;
n_dhcp4_server_dispatch;
n_dhcp4_server_pop_event;
n_dhcp4_server_add_ip;
n_dhcp4_server_ip_free;
n_dhcp4_server_lease_ref;
n_dhcp4_server_lease_unref;
n_dhcp4_server_lease_query;
n_dhcp4_server_lease_append;
n_dhcp4_server_lease_offer;
n_dhcp4_server_lease_ack;
n_dhcp4_server_lease_nack;
local:
*;
};
#
# target: libndhcp4.so
#
libndhcp4_symfile = join_paths(meson.current_source_dir(), 'libndhcp4.sym')
libndhcp4_deps = [
dep_clist,
dep_csiphash,
dep_cstdaux,
]
libndhcp4_private = static_library(
'ndhcp4-private',
[
'n-dhcp4-c-connection.c',
'n-dhcp4-c-lease.c',
'n-dhcp4-c-probe.c',
'n-dhcp4-client.c',
'n-dhcp4-incoming.c',
'n-dhcp4-outgoing.c',
'n-dhcp4-s-connection.c',
'n-dhcp4-s-lease.c',
'n-dhcp4-server.c',
'n-dhcp4-socket.c',
'util/link.c',
'util/netns.c',
'util/packet.c',
'util/socket.c',
],
c_args: [
'-fvisibility=hidden',
'-fno-common'
],
dependencies: libndhcp4_deps,
pic: true,
)
libndhcp4_shared = shared_library(
'ndhcp4',
objects: libndhcp4_private.extract_all_objects(),
dependencies: libndhcp4_deps,
install: not meson.is_subproject(),
soversion: 0,
link_depends: libndhcp4_symfile,
link_args: [
'-Wl,--no-undefined',
'-Wl,--version-script=@0@'.format(libndhcp4_symfile)
],
)
libndhcp4_dep = declare_dependency(
include_directories: include_directories('.'),
link_with: libndhcp4_private,
dependencies: libndhcp4_deps,
version: meson.project_version(),
)
if not meson.is_subproject()
install_headers('n-dhcp4.h')
mod_pkgconfig.generate(
libraries: libndhcp4_shared,
version: meson.project_version(),
name: 'libndhcp4',
filebase: 'libndhcp4',
description: project_description,
)
endif
#
# target: test-*
#
test_api = executable('test-api', ['test-api.c'], link_with: libndhcp4_shared)
test('API Symbol Visibility', test_api)
test_connection = executable('test-connection', ['test-connection.c'], dependencies: libndhcp4_dep)
test('Connection Handling', test_connection)
test_message = executable('test-message', ['test-message.c'], dependencies: libndhcp4_dep)
test('Message Handling', test_message)
test_run_client = executable('test-run-client', ['test-run-client.c'], dependencies: libndhcp4_dep)
test('Client Runner', test_run_client, args: ['--test'])
test_socket = executable('test-socket', ['test-socket.c'], dependencies: libndhcp4_dep)
test('Socket Handling', test_socket)
test_util_packet = executable('test-util-packet', ['util/test-packet.c'], dependencies: libndhcp4_dep)
test('Packet Utility Library', test_util_packet)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* XXX
*/
#include <assert.h>
#include <c-list.h>
#include <c-stdaux.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "n-dhcp4.h"
#include "n-dhcp4-private.h"
/**
* n_dhcp4_server_lease_new() - XXX
*/
int n_dhcp4_server_lease_new(NDhcp4ServerLease **leasep, NDhcp4Incoming *message) {
_c_cleanup_(n_dhcp4_server_lease_unrefp) NDhcp4ServerLease *lease = NULL;
c_assert(leasep);
lease = malloc(sizeof(*lease));
if (!lease)
return -ENOMEM;
*lease = (NDhcp4ServerLease)N_DHCP4_SERVER_LEASE_NULL(*lease);
lease->request = message;
*leasep = lease;
lease = NULL;
return 0;
}
static void n_dhcp4_server_lease_free(NDhcp4ServerLease *lease) {
c_assert(!lease->server);
c_list_unlink(&lease->server_link);
n_dhcp4_incoming_free(lease->request);
free(lease);
}
/**
* n_dhcp4_server_lease_ref() - XXX
*/
_c_public_ NDhcp4ServerLease *n_dhcp4_server_lease_ref(NDhcp4ServerLease *lease) {
if (lease)
++lease->n_refs;
return lease;
}
/**
* n_dhcp4_server_lease_unref() - XXX
*/
_c_public_ NDhcp4ServerLease *n_dhcp4_server_lease_unref(NDhcp4ServerLease *lease) {
if (lease && !--lease->n_refs)
n_dhcp4_server_lease_free(lease);
return NULL;
}
/**
* n_dhcp4_server_lease_query() - XXX
*/
_c_public_ int n_dhcp4_server_lease_query(NDhcp4ServerLease *lease, uint8_t option, uint8_t **datap, size_t *n_datap) {
switch (option) {
case N_DHCP4_OPTION_PAD:
case N_DHCP4_OPTION_REQUESTED_IP_ADDRESS:
case N_DHCP4_OPTION_IP_ADDRESS_LEASE_TIME:
case N_DHCP4_OPTION_OVERLOAD:
case N_DHCP4_OPTION_MESSAGE_TYPE:
case N_DHCP4_OPTION_SERVER_IDENTIFIER:
case N_DHCP4_OPTION_PARAMETER_REQUEST_LIST:
case N_DHCP4_OPTION_ERROR_MESSAGE:
case N_DHCP4_OPTION_MAXIMUM_MESSAGE_SIZE:
case N_DHCP4_OPTION_RENEWAL_T1_TIME:
case N_DHCP4_OPTION_REBINDING_T2_TIME:
case N_DHCP4_OPTION_END:
return N_DHCP4_E_INTERNAL;
}
return n_dhcp4_incoming_query(lease->request, option, datap, n_datap);
}
_c_public_ int n_dhcp4_server_lease_append(NDhcp4ServerLease *lease, uint8_t option, uint8_t *data, size_t n_data) {
/* XXX */
return -ENOTRECOVERABLE;
}
_c_public_ int n_dhcp4_server_lease_offer(NDhcp4ServerLease *lease) {
/* XXX */
return -ENOTRECOVERABLE;
}
_c_public_ int n_dhcp4_server_lease_ack(NDhcp4ServerLease *lease) {
/* XXX */
return -ENOTRECOVERABLE;
}
_c_public_ int n_dhcp4_server_lease_nack(NDhcp4ServerLease *lease) {
/* XXX */
return -ENOTRECOVERABLE;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* API Visibility Tests
* This verifies the visibility and availability of the exported API.
*/
#undef NDEBUG
#include <assert.h>
#include <stdlib.h>
#include "n-dhcp4.h"
static void test_api_constants(void) {
assert(1 + N_DHCP4_CLIENT_START_DELAY_RFC2131);
assert(1 + _N_DHCP4_E_SUCCESS);
assert(1 + N_DHCP4_E_PREEMPTED);
assert(1 + N_DHCP4_E_INTERNAL);
assert(1 + N_DHCP4_E_INVALID_IFINDEX);
assert(1 + N_DHCP4_E_INVALID_TRANSPORT);
assert(1 + N_DHCP4_E_INVALID_ADDRESS);
assert(1 + N_DHCP4_E_INVALID_CLIENT_ID);
assert(1 + N_DHCP4_E_DUPLICATE_OPTION);
assert(1 + N_DHCP4_E_UNSET);
assert(1 + _N_DHCP4_E_N);
assert(1 + N_DHCP4_TRANSPORT_ETHERNET);
assert(1 + N_DHCP4_TRANSPORT_INFINIBAND);
assert(1 + _N_DHCP4_TRANSPORT_N);
assert(1 + N_DHCP4_CLIENT_EVENT_DOWN);
assert(1 + N_DHCP4_CLIENT_EVENT_OFFER);
assert(1 + N_DHCP4_CLIENT_EVENT_GRANTED);
assert(1 + N_DHCP4_CLIENT_EVENT_RETRACTED);
assert(1 + N_DHCP4_CLIENT_EVENT_EXTENDED);
assert(1 + N_DHCP4_CLIENT_EVENT_EXPIRED);
assert(1 + N_DHCP4_CLIENT_EVENT_CANCELLED);
assert(1 + _N_DHCP4_CLIENT_EVENT_N);
assert(1 + N_DHCP4_SERVER_EVENT_DOWN);
assert(1 + N_DHCP4_SERVER_EVENT_DISCOVER);
assert(1 + N_DHCP4_SERVER_EVENT_REQUEST);
assert(1 + N_DHCP4_SERVER_EVENT_RENEW);
assert(1 + N_DHCP4_SERVER_EVENT_DECLINE);
assert(1 + N_DHCP4_SERVER_EVENT_RELEASE);
assert(1 + _N_DHCP4_SERVER_EVENT_N);
}
static void test_api_types(void) {
assert(sizeof(NDhcp4ClientConfig*) > 0);
assert(sizeof(NDhcp4ClientProbeConfig*) > 0);
assert(sizeof(NDhcp4Client*) > 0);
assert(sizeof(NDhcp4ClientEvent) > 0);
assert(sizeof(NDhcp4ClientProbe*) > 0);
assert(sizeof(NDhcp4ClientLease*) > 0);
assert(sizeof(NDhcp4Server*) > 0);
assert(sizeof(NDhcp4ServerConfig*) > 0);
assert(sizeof(NDhcp4ServerEvent) > 0);
assert(sizeof(NDhcp4ServerIp*) > 0);
assert(sizeof(NDhcp4ServerLease*) > 0);
}
static void test_api_functions(void) {
void *fns[] = {
(void *)n_dhcp4_client_config_new,
(void *)n_dhcp4_client_config_free,
(void *)n_dhcp4_client_config_freep,
(void *)n_dhcp4_client_config_freev,
(void *)n_dhcp4_client_config_set_ifindex,
(void *)n_dhcp4_client_config_set_transport,
(void *)n_dhcp4_client_config_set_request_broadcast,
(void *)n_dhcp4_client_config_set_mac,
(void *)n_dhcp4_client_config_set_broadcast_mac,
(void *)n_dhcp4_client_config_set_client_id,
(void *)n_dhcp4_client_probe_config_new,
(void *)n_dhcp4_client_probe_config_free,
(void *)n_dhcp4_client_probe_config_freep,
(void *)n_dhcp4_client_probe_config_freev,
(void *)n_dhcp4_client_probe_config_set_inform_only,
(void *)n_dhcp4_client_probe_config_set_init_reboot,
(void *)n_dhcp4_client_probe_config_set_requested_ip,
(void *)n_dhcp4_client_probe_config_set_start_delay,
(void *)n_dhcp4_client_probe_config_request_option,
(void *)n_dhcp4_client_probe_config_append_option,
(void *)n_dhcp4_client_new,
(void *)n_dhcp4_client_ref,
(void *)n_dhcp4_client_unref,
(void *)n_dhcp4_client_unrefp,
(void *)n_dhcp4_client_unrefv,
(void *)n_dhcp4_client_get_fd,
(void *)n_dhcp4_client_dispatch,
(void *)n_dhcp4_client_pop_event,
(void *)n_dhcp4_client_update_mtu,
(void *)n_dhcp4_client_probe,
(void *)n_dhcp4_client_probe_free,
(void *)n_dhcp4_client_probe_freep,
(void *)n_dhcp4_client_probe_freev,
(void *)n_dhcp4_client_probe_get_userdata,
(void *)n_dhcp4_client_probe_set_userdata,
(void *)n_dhcp4_client_lease_ref,
(void *)n_dhcp4_client_lease_unref,
(void *)n_dhcp4_client_lease_unrefp,
(void *)n_dhcp4_client_lease_unrefv,
(void *)n_dhcp4_client_lease_get_yiaddr,
(void *)n_dhcp4_client_lease_get_lifetime,
(void *)n_dhcp4_client_lease_query,
(void *)n_dhcp4_client_lease_select,
(void *)n_dhcp4_client_lease_accept,
(void *)n_dhcp4_client_lease_decline,
(void *)n_dhcp4_server_config_new,
(void *)n_dhcp4_server_config_free,
(void *)n_dhcp4_server_config_freep,
(void *)n_dhcp4_server_config_freev,
(void *)n_dhcp4_server_config_set_ifindex,
(void *)n_dhcp4_server_new,
(void *)n_dhcp4_server_ref,
(void *)n_dhcp4_server_unref,
(void *)n_dhcp4_server_unrefp,
(void *)n_dhcp4_server_unrefv,
(void *)n_dhcp4_server_get_fd,
(void *)n_dhcp4_server_dispatch,
(void *)n_dhcp4_server_pop_event,
(void *)n_dhcp4_server_add_ip,
(void *)n_dhcp4_server_ip_free,
(void *)n_dhcp4_server_ip_freep,
(void *)n_dhcp4_server_ip_freev,
(void *)n_dhcp4_server_lease_ref,
(void *)n_dhcp4_server_lease_unref,
(void *)n_dhcp4_server_lease_unrefp,
(void *)n_dhcp4_server_lease_unrefv,
(void *)n_dhcp4_server_lease_query,
(void *)n_dhcp4_server_lease_append,
(void *)n_dhcp4_server_lease_offer,
(void *)n_dhcp4_server_lease_ack,
(void *)n_dhcp4_server_lease_nack,
};
size_t i;
for (i = 0; i < sizeof(fns) / sizeof(*fns); ++i)
assert(!!fns[i]);
}
int main(int argc, char **argv) {
test_api_constants();
test_api_types();
test_api_functions();
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#pragma once
/*
* Link Management
*
* This utility provides easy access to network links. It is meant for testing
* purposes only and relies on call-outs to ip(1). A proper implementation
* should rather use netlink directly to interact with the kernel.
*
* Furthermore, for simplification this is limited to ethernet links.
*/
#include <c-stdaux.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <stdlib.h>
typedef struct Link Link;
struct Link {
int netns;
int ifindex;
struct ether_addr mac;
};
#define LINK_NULL(_x) { \
.netns = -1, \
}
void link_deinit(Link *link);
void link_new_veth(Link *veth_parentp, Link *veth_childp, int netns_parent, int netns_child);
void link_new_bridge(Link *bridgep, int netns);
void link_add_ip4(Link *link, const struct in_addr *addr, unsigned int prefix);
void link_del_ip4(Link *link, const struct in_addr *addr, unsigned int prefix);
void link_set_master(Link *link, int if_master);
void link_socket(Link *link, int *socketp, int family, int type);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#pragma once
/*
* Socket Utilities
*/
#include <c-stdaux.h>
#include <stdlib.h>
int socket_SIOCGIFNAME(int socket, int ifindex, char (*ifnamep)[IFNAMSIZ]);
int socket_bind_if(int socket, int ifindex);
This diff is collapsed.
Subproject commit 2e4b605c6217cd3c8a1ef773f82f5cc329ba650d
Subproject commit 7c42c592581906fef19458372b8db2b643278211
Subproject commit 11930d259212605a15430523472ef54e0c7654ee
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment