diff --git a/.gitignore b/.gitignore index a254288..ed3e449 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -libnet-1.1.5.tar.gz -/libnet-1.1.6.tar.gz +/libnet-*.tar.gz diff --git a/libnet.spec b/libnet.spec index ce0912c..0d32577 100644 --- a/libnet.spec +++ b/libnet.spec @@ -1,13 +1,13 @@ -Summary: C library for portable packet creation and injection -Name: libnet -Version: 1.1.6 -Release: 20%{?dist} -License: BSD -URL: http://www.sourceforge.net/projects/libnet-dev/ -Source: http://downloads.sourceforge.net/libnet-dev/%{name}-%{version}.tar.gz -%if 0%{?fedora} >= 17 || 0%{?rhel} >= 7 -BuildRequires: autoconf, automake, libtool -%endif +Summary: C library for portable packet creation and injection +Name: libnet +Version: 1.2 +Release: 1%{?dist} +License: BSD +URL: https://github.com/libnet/libnet +Source0: https://github.com/libnet/libnet/releases/download/v%{version}/%{name}-%{version}.tar.gz +BuildRequires: gcc +BuildRequires: make +BuildRequires: %{_bindir}/pod2man %description Libnet is an API to help with the construction and handling of network @@ -18,80 +18,84 @@ layer and at the link layer as well as a host of supplementary and complementary functionality. %package devel -Summary: Development files for the libnet library -Requires: %{name}%{?_isa} = %{version}-%{release} +Summary: Development files for the libnet library +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: pkgconfig %description devel The libnet-devel package includes header files and libraries necessary -for developing programs which use the libnet library. Libnet is very handy -with which to write network tools and network test code. See the manpage -and sample test code for more detailed information. +for developing programs which use the libnet library. Libnet is very +handy with which to write network tools and network test code. See the +man page and sample test code for more detailed information. + +%if 0%{!?_without_doc:1} +%package doc +Summary: Documentation files for the libnet library +BuildArch: noarch +BuildRequires: doxygen +BuildRequires: graphviz + +%description doc +Libnet is an API to help with the construction and handling of network +packets. It provides a portable framework for low-level network packet +writing and handling. This package contains the API documentation for +developing applications that use libnet. +%endif %prep %setup -q -%if 0%{?fedora} >= 17 || 0%{?rhel} >= 7 -autoreconf --force --install -%endif - -# Keep the sample directory untouched by make -rm -rf __dist_sample -mkdir __dist_sample -cp -a sample __dist_sample +# Avoid library soname bump (https://github.com/libnet/libnet/issues/115) +sed -e 's/-version-info 9:0:0/-version-info 9:0:8/' -i src/Makefile.{am,in} %build -%if 0%{?fedora} < 17 && 0%{?rhel} < 7 -%configure --libdir=/%{_lib} -%else %configure -%endif -make %{?_smp_mflags} +%make_build %install -rm -rf $RPM_BUILD_ROOT -make DESTDIR=$RPM_BUILD_ROOT INSTALL='install -p' install +%make_install INSTALL='install -p' -%if 0%{?fedora} < 17 && 0%{?rhel} < 7 -# Move %{name}.so to %{_libdir}, remove static .a and libtool .la files -rm -f $RPM_BUILD_ROOT/%{_lib}/%{name}.{a,la,so} -pushd $RPM_BUILD_ROOT/%{_lib} -mkdir -p $RPM_BUILD_ROOT%{_libdir} -ln -sf ../../%{_lib}/$(ls %{name}.so.?.?.?) $RPM_BUILD_ROOT%{_libdir}/%{name}.so -popd -%else +# Don't install any libtool .la files rm -f $RPM_BUILD_ROOT%{_libdir}/%{name}.{a,la} -%endif -# Prepare samples directory and perform some fixes -rm -rf __dist_sample/sample/win32 -rm -f __dist_sample/sample/Makefile.{am,in} -sed -e 's@#include "../include/libnet.h"@#include @' \ - __dist_sample/sample/libnet_test.h > __dist_sample/sample/libnet_test.h.new -touch -c -r __dist_sample/sample/libnet_test.h{,.new} -mv -f __dist_sample/sample/libnet_test.h{.new,} +# Clean up for later usage in documentation +rm -rf $RPM_BUILD_ROOT%{_defaultdocdir} -# Remove makefile relics from documentation -rm -f doc/html/Makefile* +# Prepare samples for usage in documentation +rm -rf sample/{Makefile*,win32} +for file in sample/*.[hc]; do + sed \ + -e 's@#include "../include/libnet.h"@#include @' \ + -e 's@#include "../include/config.h"@#include @' \ + $file > $file.new + touch -c -r $file{,.new} + mv -f $file{.new,} +done %ldconfig_scriptlets %files -%doc README doc/CHANGELOG doc/CONTRIB doc/COPYING -%if 0%{?fedora} < 17 && 0%{?rhel} < 7 -/%{_lib}/%{name}.so.* -%else +%license LICENSE +%doc README.md ChangeLog.md %{_libdir}/%{name}.so.* -%endif %files devel -%doc doc/CHANGELOG doc/CONTRIB doc/COPYING doc/DESIGN_NOTES doc/MIGRATION doc/PACKET_BUILDING -%doc doc/RAWSOCKET_NON_SEQUITUR doc/TODO doc/html/ __dist_sample/sample/ +%doc doc/MIGRATION.md doc/RAWSOCKET.md sample/ %{_bindir}/%{name}-config %{_libdir}/%{name}.so -%{_includedir}/libnet.h +%{_libdir}/pkgconfig/%{name}.pc +%{_includedir}/%{name}.h %{_includedir}/%{name}/ %{_mandir}/man3/%{name}*.3* +%if 0%{!?_without_doc:1} +%files doc +%doc doc/html/ +%endif + %changelog +* Sat Jan 02 2021 Robert Scheck 1.2-1 +- Upgrade to 1.2 (#1912031) + * Tue Jul 28 2020 Fedora Release Engineering - 1.1.6-20 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild diff --git a/sources b/sources index 265489b..6b3f072 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -710296fe424a49344e5fcc0d09e53317 libnet-1.1.6.tar.gz +SHA512 (libnet-1.2.tar.gz) = 84430f24e000eb7728b1fbb5e620716d13d193e8b9e024cf56a08fbeeeaaf56c9122caaf7647f01e6b38b73212e592fa5cc4e8ff56b1d5f5a73aea462e84edd6 diff --git a/tests/sanity-tests/Makefile b/tests/sanity-tests/Makefile new file mode 100644 index 0000000..351c7c6 --- /dev/null +++ b/tests/sanity-tests/Makefile @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libnet +# Description: Sanity +# Author: Susant Sahani +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +export TEST=/CoreOS/libnet +export TESTVERSION=1.0 + +INCLUDES = +OBJS = test-libnet.c +CFLAG = -Wall -g3 +CC = gcc +LIBS = -lnet -lcmocka -lpcap -lpthread + +test-libnet:${OBJ} + ${CC} ${CFLAGS} ${INCLUDES} -o $@ ${OBJS} ${LIBS} + +run: test-libnet + ./runtest.sh +clean: + -rm -f *~ test-libnet + +.c.o: + ${CC} ${CFLAGS} ${INCLUDES} -c $< + +CC = gcc + +include /usr/share/rhts/lib/rhts-make.include +$(METADATA): Makefile + @echo "Owner: Susant Sahani" > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Test libnet sanity" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: libnet" >> $(METADATA) + @echo "Requires: libnet libnet-devel" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -Fedora 29" >> $(METADATA) + rhts-lint $(METADATA) diff --git a/tests/sanity-tests/runtest.sh b/tests/sanity-tests/runtest.sh new file mode 100755 index 0000000..353cdf0 --- /dev/null +++ b/tests/sanity-tests/runtest.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1+ +# ~~~ +# runtest.sh of libnet +# Description: Tests for libnet +# +# Author: Susant Sahani +# Copyright (c) 2018 Red Hat, Inc. +# ~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="libnet" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm $PACKAGE + + rlLog "Setting up veth Interface " + rlRun "ip link add veth-test type veth peer name veth-peer" + rlRun "ip addr add 192.168.50.5 dev veth-test" + rlRun "ip addr add 192.168.50.6 dev veth-peer" + rlRun "ip link set dev veth-test up" + rlRun "ip link set dev veth-peer up" + + rlRun "cp test-libnet /usr/bin/" + rlRun "systemctl daemon-reload" + rlPhaseEnd + + rlPhaseStartTest + rlLog "Starting libnet tests ..." + rlRun "/usr/bin/test-libnet" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "rm /usr/bin/test-libnet" + rlRun "ip link del veth-test" + rlLog "libnet tests done" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd + +rlGetTestState diff --git a/tests/sanity-tests/test-libnet b/tests/sanity-tests/test-libnet new file mode 100755 index 0000000..476092b Binary files /dev/null and b/tests/sanity-tests/test-libnet differ diff --git a/tests/sanity-tests/test-libnet.c b/tests/sanity-tests/test-libnet.c new file mode 100644 index 0000000..9fd0e96 --- /dev/null +++ b/tests/sanity-tests/test-libnet.c @@ -0,0 +1,229 @@ +/* +# SPDX-License-Identifier: LGPL-2.1+ +# ~~~ +# Description: libnet tests +# +# Author: Susant Sahani +# Copyright (c) 2018 Red Hat, Inc. +# ~~~ +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PCAP_FILE "/var/run/libnet-test.pcap" + +pcap_t *handle; + +struct UDP_hdr { + u_short uh_sport; /* source port */ + u_short uh_dport; /* destination port */ + u_short uh_ulen; /* datagram length */ + u_short uh_sum; /* datagram checksum */ +}; + +static void assert_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { + unsigned int ipl; + uint32_t src, dst; + struct ip *ip; + struct ether_header *eth_header; + + eth_header = (struct ether_header *) packet; + if (ntohs(eth_header->ether_type) != ETHERTYPE_IP) + return; + + packet += sizeof(struct ether_header); + ip = (struct ip *) packet; + ipl = ip->ip_hl * 4; + + src = inet_addr("192.168.50.6"); + dst = inet_addr("192.168.50.5"); + + assert_memory_equal(&dst, &ip->ip_dst, sizeof(uint32_t)); + assert_memory_equal(&src, &ip->ip_src, sizeof(uint32_t)); + + if (ip->ip_p == IPPROTO_UDP) { + struct UDP_hdr *udp; + + packet += ipl; + + udp = (struct UDP_hdr *) packet; + + printf("UDP src_port=%d dst_port=%d\n", ntohs(udp->uh_sport), ntohs(udp->uh_dport)); + + assert_int_equal(2425, ntohs(udp->uh_sport)); + assert_int_equal(2426, ntohs(udp->uh_dport)); + } else if (ip->ip_p == IPPROTO_TCP) { + struct tcphdr *tcp; + packet += ipl; + + tcp = (struct tcphdr *) packet; + + printf("TCP src_port=%d dst_port=%d\n", ntohs(tcp->th_sport), ntohs(tcp->th_dport)); + + assert_int_equal(2425, ntohs(tcp->th_sport)); + assert_int_equal(2426, ntohs(tcp->th_dport)); + } +} + +void *capture_packet_live(void *ptr) { + char dev[] = "veth-test"; + char error_buffer[PCAP_ERRBUF_SIZE]; + struct bpf_program filter; + bpf_u_int32 subnet_mask, ip; + int total_packet_count; + int r; + + r = pcap_lookupnet(dev, &ip, &subnet_mask, error_buffer); + assert_true(r >=0); + + handle = pcap_open_live(dev, BUFSIZ, 1, 1000, error_buffer); + assert_non_null(handle); + + r = pcap_compile(handle, &filter, ptr, 0, ip); + assert_true(r >= 0); + + r = pcap_setfilter(handle, &filter); + assert_true(r >= 0); + + pcap_loop(handle, total_packet_count, assert_packet, NULL); + + return 0; +} + +void terminate_thread(int signum) { + + pcap_breakloop(handle); + pcap_close(handle); + + handle = NULL; + pthread_exit(NULL); +} + +static void test_udp_packet_ipv4(void **state) { + char dst[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + char src[6] = {0x12,0x34,0x56,0x78,0x9a,0xab}; + char err_buf[LIBNET_ERRBUF_SIZE] = {}; + char buf[1024] = {}; + libnet_t* l; + int r, i; + uint32_t len; + pthread_t pcap_thread; + struct itimerval tval; + + timerclear(& tval.it_interval); /* zero interval means no reset of timer */ + timerclear(& tval.it_value); + tval.it_value.tv_sec = 10; /* 10 second timeout */ + + (void) signal(SIGALRM, terminate_thread); + (void) setitimer(ITIMER_REAL, & tval, NULL); + + r = pthread_create(&pcap_thread, NULL, capture_packet_live, "udp port 2425"); + assert_true(r >=0); + + l = libnet_init(LIBNET_LINK_ADV, "veth-peer", err_buf); + assert_non_null(l); + len = sprintf(buf, "1:1:1111111111111:32:hello world%d", 1); + + for (i = 0; i < 5; i++) { + + r = libnet_build_udp(2425, 2426, len + 8, 0, buf, len, l, 0); + assert_true(r >= 0); + + r = libnet_build_ipv4(20 + 8 + len, 0, 0, 0, 128, 17, 0, inet_addr("192.168.50.6"), inet_addr("192.168.50.5"), NULL, 0, l, 0); + assert_true(r >= 0); + + r = libnet_build_ethernet(dst, src, 0x0800, NULL, 0, l, 0); + assert_true(r >= 0); + + r = libnet_write(l); + assert_true(r >= 0); + + sleep(1); + } + + libnet_destroy(l); +} + +static void test_tcp_packet_ipv4(void **state) { + char dst[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + char src[6] = {0x12,0x34,0x56,0x78,0x9a,0xab}; + char errbuf[LIBNET_ERRBUF_SIZE]; + uint8_t *payload, payload_s; + libnet_ptag_t tcp, ip, eth; + int c, i, j, seqn, ack; + char buf[1024] = {}; + pthread_t pcap_thread; + struct itimerval tval; + uint32_t len; + libnet_t *l; + int r; + + timerclear(& tval.it_interval); + timerclear(& tval.it_value); + tval.it_value.tv_sec = 10; + + (void) signal(SIGALRM, terminate_thread); + (void) setitimer(ITIMER_REAL, & tval, NULL); + + r = pthread_create(&pcap_thread, NULL, capture_packet_live, "tcp port 2425"); + assert_true(r >=0); + + payload_s = 10; + payload = malloc(payload_s*sizeof(uint8_t)); + assert_non_null(payload); + memset(payload,0,payload_s); + + l = libnet_init(LIBNET_LINK, "veth-peer", errbuf); + assert_non_null(l); + + tcp = ip = eth = LIBNET_PTAG_INITIALIZER; + for (i=0; i<5; i++){ + seqn=i * (LIBNET_TCP_H+payload_s + 1); + r = libnet_build_tcp(2425, 2426, seqn, seqn + LIBNET_TCP_H + payload_s + 1, + TH_SYN, 32767, 0, 10, LIBNET_TCP_H + payload_s, + payload, payload_s, l, tcp); + assert_true(r >=0); + + r = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_TCP_H + payload_s,0,242,0,64,IPPROTO_TCP,0, + inet_addr("192.168.50.6"), inet_addr("192.168.50.5"), + NULL,0,l,ip); + assert_true(r >=0); + + r = libnet_build_ethernet(dst, src, ETHERTYPE_IP, NULL, 0, l, eth); + assert_true(r >=0); + + r = libnet_write(l); + assert_true(r >=0); + + sleep(1); + } +} + +int main(int argc, char *argv[]) { + const struct CMUnitTest libnet_tests[] = { + cmocka_unit_test(test_udp_packet_ipv4), + cmocka_unit_test(test_tcp_packet_ipv4), + }; + + return cmocka_run_group_tests(libnet_tests, NULL, NULL); +} diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..6f5f1cc --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,17 @@ +- hosts: localhost + roles: + - role: standard-test-beakerlib + tags: + - classic + tests: + - sanity-tests + required_packages: + - libnet + - libnet-devel + - libpcap + - libpcap-devel + - systemd + - wireshark-cli + - libcmocka + - libcmocka-devel + - gcc