82 Commits

Author SHA1 Message Date
Vadim Vetrov
1f0cb673e9 Configs update 2025-12-28 12:55:30 +03:00
Vadim Vetrov
814980f5b2 Fix --udp-stun-filter not applied in luci-app 2025-08-15 08:38:36 +03:00
Vadim Vetrov
6e0e0089d3 Bump kmod 2025-08-14 23:41:12 +03:00
Vadim Vetrov
b4a61b4684 Bump version 2025-08-14 17:26:40 +03:00
Vadim Vetrov
87b5d4d367 Add STUN filter 2025-08-14 17:22:18 +03:00
Vadim Vetrov
45304309e8 Merge pull request #208 from HiHat/patch-2 2025-03-16 16:24:25 +03:00
Vadim Vetrov
8a41b77999 Add conntrack to dependencies
Reported by @MayanKoyote in https://github.com/Waujito/youtubeUnblock/discussions/172#discussioncomment-12453450
2025-03-16 15:44:39 +03:00
Vadim Vetrov
8647d9298c Bump version 2025-02-21 00:21:12 +03:00
Vadim Vetrov
afefb8e14e Merge pull request #226 from proninyaroslav/patch-1
Fix UDP faking description
2025-01-28 21:51:13 +03:00
Yaroslav Pronin
d75870dc02 Formatting the UDP mode description 2025-01-28 20:05:41 +03:00
Yaroslav Pronin
089155544d Fix UDP faking description 2025-01-28 20:03:32 +03:00
Vadim Vetrov
ede843e2a5 Bump version 2025-01-28 19:38:15 +03:00
Vadim Vetrov
3e676f9e25 Fix trace and silent 2025-01-07 13:49:59 +03:00
Vadim Vetrov
13fbd7b45b Add section-specific post args 2025-01-07 13:37:08 +03:00
Vadim Vetrov
6664a921d0 Move sni_detection flag to Domains section 2025-01-04 17:53:49 +03:00
HiHat
e547244250 Update S51youtubeUnblock
Entware style changes
2024-12-31 20:35:03 +03:00
Vadim Vetrov
fcc5c6f331 Fix HttpError 404 in OpenWRT 22 and 21 2024-12-30 16:28:18 +03:00
Vadim Vetrov
9e299d2592 Support for #207 2024-12-30 13:08:13 +03:00
Vadim Vetrov
b49d3b6bc0 Update commit hashes to new version 2024-12-28 20:37:27 +03:00
Vadim Vetrov
833a4507fd Add autoreset for old configuration 2024-12-27 19:17:35 +03:00
Vadim Vetrov
47ac81c318 Update UI for luci-app status 2024-12-23 01:14:24 +03:00
Vadim Vetrov
e915e3ef51 Add notice about sections order 2024-12-22 17:26:50 +03:00
Vadim Vetrov
c6618769e9 Fix predefined configs 2024-12-22 17:16:17 +03:00
Vadim Vetrov
5dd23c0148 Merge pull request #205 from Waujito/luci_update
Luci update
2024-12-22 16:55:03 +03:00
Vadim Vetrov
c496b3131f Implement luci flags with JS 2024-12-22 16:39:31 +03:00
Vadim Vetrov
c9202aeedf Remaster luci-app-youtubeUnblock from deprecated lua scripts to
client-side JS
2024-12-21 02:56:11 +03:00
Vadim Vetrov
e7329a11ef Fix page reloads on button click. 2024-12-20 20:00:22 +03:00
Vadim Vetrov
add9a58af1 Update firewall rules
Support for all UDP ports
2024-12-20 00:33:27 +03:00
Vadim Vetrov
0a989c662a Merge pull request #202 from Waujito/opewnrt_luci
Add unified args, remove verbose togglers
2024-12-19 01:26:39 +03:00
Vadim Vetrov
b29787efb1 Add unified args, remove verbose togglers
For later development it's better to just update args in normal youtubeUnblock
and use luci module just as a way to manage it better
2024-12-18 18:13:36 +03:00
Vadim Vetrov
48fab764a4 Bump release version to 5 2024-12-02 20:44:14 +03:00
Vadim Vetrov
227d216483 Bump version 2024-12-01 19:30:44 +03:00
Vadim Vetrov
a6db941371 Update versions for APK 2024-11-30 15:50:18 +03:00
Vadim Vetrov
1728f4f9ff Move entware from separate branch to openwrt 2024-11-30 14:03:52 +03:00
Vadim Vetrov
ab982ce14b Bump version 2024-11-30 13:54:05 +03:00
Vadim Vetrov
765c74c235 Bump version 2024-11-30 13:51:40 +03:00
Vadim Vetrov
79f47b2fbd Fix #192
postinst скрипт создает файл /1
2024-11-28 18:07:45 +03:00
Vadim Vetrov
2154e2699e Bump versions 2024-11-26 18:11:49 +03:00
Vadim Vetrov
99601ea5ce Merge pull request #190 by MayanKoyote
youtubeUnblock.lua: minor correction of typos
2024-11-25 22:36:19 +03:00
MayanKoyote
9a50ee50a6 youtubeUnblock.lua: minor correction of typos 2024-11-25 23:55:09 +05:00
Vadim Vetrov
e764a20baa Add post args for youtubeUnblock 2024-10-29 02:27:33 +03:00
Vadim Vetrov
62d542d1f4 Fix typo
Reported in #148
2024-10-13 23:56:31 +03:00
Vadim Vetrov
276de58331 Add postinst defender for build
Reported in #154
2024-10-13 17:32:55 +03:00
Vadim Vetrov
c7397a4694 Add new flags from #132 to configuration interfaces 2024-10-12 18:05:01 +03:00
Vadim Vetrov
1bf4f38c1c Update build scripts: split luci-app-youtubeUnblock from youtubeUnblock 2024-10-11 22:17:07 +03:00
Vadim Vetrov
bfde178061 Bump version to v1.0.0 2024-09-21 19:22:53 +03:00
Vadim Vetrov
74472b8d16 Bump the version
Reported in #119
2024-09-18 21:04:45 -07:00
Vadim Vetrov
ac0635dda6 Bump the version of kmod 2024-09-17 19:29:46 +03:00
Vadim Vetrov
c9aa1edfe7 Default boolean to 0 2024-09-14 18:43:15 +03:00
Vadim Vetrov
de1cfab8cd Create config file in uci-defaults
This may solve #114
2024-09-14 17:38:37 +03:00
Vadim Vetrov
0c08d7c5f2 Merge pull request #110 from Waujito/openwrt_luci
Add luci support for youtubeUnblock Part 1
2024-09-14 02:26:19 -07:00
Vadim Vetrov
0becd2fb18 Reload after apply 2024-09-14 12:25:48 +03:00
Vadim Vetrov
d7df9cbc6d More detailed logs 2024-09-14 11:32:32 +03:00
Vadim Vetrov
dba6078f2c Update nftables to allow quic drop 2024-09-14 10:58:22 +03:00
Vadim Vetrov
9dacead2ee Fix uci-defaults 2024-09-13 22:59:05 +03:00
Vadim Vetrov
6725e22de7 Add new option 2024-09-13 21:19:16 +03:00
Vadim Vetrov
6b6f53c942 All in one package 2024-09-12 23:49:06 +03:00
Vadim Vetrov
484d8555de Add luci.mk 2024-09-12 23:19:08 +03:00
Vadim Vetrov
37ae420e23 Add luci package 2024-09-12 22:57:33 +03:00
Vadim Vetrov
ad9a337795 Add kernel module build unit 2024-09-02 01:09:52 +03:00
Vadim Vetrov
db1f5ee4f1 Update Makefile 2024-08-29 00:03:50 +03:00
Vadim Vetrov
d549615037 Update Makefile 2024-08-28 09:46:56 +03:00
Vadim Vetrov
b2bdad30c0 Update Makefile 2024-08-18 21:30:54 +03:00
Vadim Vetrov
b8fe089bf8 #71 2024-08-15 14:10:03 +03:00
Vadim Vetrov
eae8175216 Update youtubeUnblock.owrt 2024-08-13 19:31:22 +03:00
Vadim Vetrov
20b1f6685c Update Makefile 2024-08-12 00:58:04 +03:00
Vadim Vetrov
be4def29ce Update Makefile 2024-08-12 00:57:50 +03:00
Vadim Vetrov
11e51c96d9 Update youtubeUnblock.owrt 2024-08-12 00:57:20 +03:00
Vadim Vetrov
72fccfe3e4 Update Makefile 2024-08-10 02:28:38 +03:00
Vadim Vetrov
3418b7d41e Update Makefile 2024-08-10 02:24:25 +03:00
Vadim Vetrov
2f2cf58023 Update Makefile 2024-08-10 01:30:34 +03:00
Vadim Vetrov
1a64b98fac Merge pull request #45 from aegoroff/openwrt
build: bump openwrt version to 0.2.2
2024-08-09 05:22:31 -07:00
Alexander Egorov
3d7745bb56 build: bump openwrt version to 0.2.2 2024-08-09 15:13:37 +03:00
Vadim Vetrov
2533296c2d Update Makefile 2024-08-08 17:40:57 +03:00
Vadim Vetrov
351b25b362 Update Makefile 2024-08-08 15:39:11 +03:00
Vadim Vetrov
854fbe84f5 Update Makefile 2024-08-07 22:47:10 +03:00
Vadim Vetrov
1050509f37 Update build system 2024-08-07 22:30:21 +03:00
Vadim Vetrov
8655b9380d Add nft queue dependency to support nftables out of the box. 2024-08-06 22:22:16 +03:00
Vadim Vetrov
8e3c939640 Update dependencies 2024-08-05 19:19:36 +03:00
Vadim Vetrov
42dab94a1a Add dependencies 2024-08-05 17:44:43 +03:00
Vadim Vetrov
87f016f27c Add download from github 2024-08-05 16:42:24 +03:00
Vadim Vetrov
48201093c3 OpenWRT SDK build system 2024-08-05 16:02:32 +03:00
227 changed files with 1588 additions and 37364 deletions

View File

@@ -1,10 +0,0 @@
root = true
[*]
indent_style = tab
indent_size = 8
tab_width = 8
[*.yml]
indent_style = space
indent_size = 2

View File

@@ -1,42 +0,0 @@
name: Bug report
description: Use this issue template when you are pretty sure here is a bug. Make sure the trouble you are experiencing haven't been already reported earlier and haven't been talked about in discussions.
body:
- type: markdown
attributes:
value: |
Use this issue template when you are pretty sure here is a bug.
Make sure the trouble you are experiencing haven't been already reported earlier and haven't been talked about in [discussions](https://github.com/Waujito/youtubeUnblock/discussions).
Note, that *bugs* are internal program errors: crashes, freezes and other types of undefined behavior. You may also report problems with routers infrastructure here, but **NOT** questions like *My router doesn't work help please*. Your questions and other stuff with custom routers setup should be discussed [here](https://github.com/Waujito/youtubeUnblock/discussions/172)
Discuss problems like *youtube doesn't unblock* [here](https://github.com/Waujito/youtubeUnblock/discussions/173)
- type: textarea
id: bug-report
attributes:
label: Bug description
validations:
required: true
- type: input
id: linux-distro
attributes:
label: Linux distribution
description: Pass here your linux distro e.g. OpenWRT, Entware, Merlin, Padavan, Ubuntu, Debian
validations:
required: false
- type: textarea
id: architecture
attributes:
label: Device architecture
description: Pass here the architecture of your device. (On openwrt do `cat /etc/openwrt_release`, on other systems `lscpu` or `cat /proc/cpuinfo`)
validations:
required: false
- type: textarea
id: configs
attributes:
label: Configuration
description: Pass here the configuration of youtubeUnblock being used. You may pass output of `cat /etc/config/youtubeUnblock` on OpenWRT or raw flags of youtubeUnblock.
validations:
required: false

View File

@@ -1,10 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---

View File

@@ -1 +0,0 @@
This directory contains dockerfiles for large docker containers. This allows not to rebuild binaries every build and not to utilize cache.

View File

@@ -1,6 +0,0 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/aarch64-3.10.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -1,6 +0,0 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git -b k2.6
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/armv7-2.6.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -1,6 +0,0 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/armv7-3.2.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -1,6 +0,0 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/mips-3.4.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -1,6 +0,0 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/mipsel-3.4.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -1,6 +0,0 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/x64-3.2.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -1,6 +0,0 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git -b k2.6
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/x86-2.6.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -1,12 +0,0 @@
FROM ubuntu:14.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.0.101.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -1,12 +0,0 @@
FROM ubuntu:16.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.10.108.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -1,12 +0,0 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.322.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -1,12 +0,0 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.302.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -1,12 +0,0 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.167.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -1,12 +0,0 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.4.284.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -1,12 +0,0 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.52.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -1,379 +0,0 @@
name: CI
on:
push:
branches:
- main
paths-ignore:
- '.editorconfig'
- '.gitignore'
- 'LICENSE'
- 'README.md'
workflow_dispatch:
pull_request:
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.gh.outputs.version }}
release: ${{ steps.gh.outputs.release }}
sha: ${{ steps.gh.outputs.sha }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: GH
id: gh
env:
REPO: ${{ github.repository }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
echo "version=$(cat Makefile | grep "PKG_VERSION :=" | sed 's/PKG_VERSION := //')" >> $GITHUB_OUTPUT
echo "release=$(cat Makefile | grep "PKG_RELEASE :=" | sed 's/PKG_RELEASE := //')" >> $GITHUB_OUTPUT
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
GITHUB_SHA=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request.head.sha)
fi
echo "sha=$(echo ${GITHUB_SHA::7})" >> $GITHUB_OUTPUT
cat $GITHUB_OUTPUT
build-static:
needs: prepare
name: build ${{ matrix.arch }}
runs-on: ubuntu-latest
strategy:
matrix:
arch: [x86_64, x86, aarch64, armhf, armv7]
branch: [latest-stable]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up ccache
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/.ccache
key: ccache-${{ matrix.arch }}-${{ github.run_id }}
restore-keys: ccache-${{ matrix.arch }}-
- name: Set up Alpine Linux for ${{ matrix.arch }}
uses: jirutka/setup-alpine@v1
with:
arch: ${{ matrix.arch }}
branch: ${{ matrix.branch }}
packages: >
bash build-base ccache coreutils findutils gawk git grep tar wget xz
autoconf automake libtool pkgconf linux-headers
shell-name: alpine.sh
- name: Build inside chroot
id: build
env:
ARCH: ${{ matrix.arch }}
CCACHE_DIR: ${{ github.workspace }}/.ccache
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
shell: alpine.sh {0}
run: |
case $ARCH in
x86_64) PLATFORM=x86-64 ;;
x86) PLATFORM=x86 ;;
aarch64) PLATFORM=arm64 ;;
armhf) PLATFORM=arm ;;
*) PLATFORM=$ARCH ;;
esac
make -j$(nproc) CC="ccache gcc -static-libgcc -static" || exit 1
strip -s build/youtubeUnblock
cp -va build/youtubeUnblock .
tar -czvf youtubeUnblock-$VERSION-$RELEASE-$SHA-$PLATFORM-static.tar.gz youtubeUnblock youtubeUnblock.service README.md
ccache --show-stats
- name: Upload artifacts
if: steps.build.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: youtubeUnblock-static-${{ matrix.arch }}
path: ./**/youtubeUnblock*.tar.gz
build-static-cross:
needs: prepare
name: build ${{ matrix.arch }}
runs-on: ubuntu-latest
strategy:
matrix:
include:
- arch: mips64el
tool: mips64el-unknown-linux-musl
- arch: mips64
tool: mips64-unknown-linux-musl
- arch: mipsel
tool: mipsel-unknown-linux-musl
- arch: mipselsf
tool: mipsel-unknown-linux-muslsf
- arch: mips
tool: mips-unknown-linux-musl
- arch: mipssf
tool: mips-unknown-linux-muslsf
- arch: armv7sf
tool: armv7-unknown-linux-musleabi
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up build tools
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: 'musl-cross/musl-cross'
TOOL: ${{ matrix.tool }}
run: |
mkdir -p $HOME/tools
gh api repos/$REPO/releases/latest --jq '.tag_name' |\
xargs -I{} wget -qO- https://github.com/$REPO/releases/download/{}/$TOOL.tar.xz | tar -C $HOME/tools -xJ || exit 1
[ -d "$HOME/tools/$TOOL/bin" ] && echo "$HOME/tools/$TOOL/bin" >> $GITHUB_PATH
- name: Build
id: build
env:
ARCH: ${{ matrix.arch }}
TOOL: ${{ matrix.tool }}
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
run: |
make -j$(nproc) \
CC="$TOOL-gcc -static-libgcc -static" \
LD=$TOOL-ld \
AR=$TOOL-ar \
NM=$TOOL-nm \
STRIP=$TOOL-strip \
CROSS_COMPILE_PLATFORM=$TOOL || exit 1
$TOOL-strip -s build/youtubeUnblock
cp -va build/youtubeUnblock .
tar -czvf youtubeUnblock-$VERSION-$RELEASE-$SHA-$ARCH-static.tar.gz youtubeUnblock youtubeUnblock.service README.md
- name: Upload artifacts
if: steps.build.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: youtubeUnblock-static-${{ matrix.arch }}
path: ./**/youtubeUnblock*.tar.gz
build-openwrt:
needs: prepare
runs-on: ubuntu-latest
strategy:
matrix:
branch:
- openwrt-23.05
arch:
- aarch64_cortex-a53
- aarch64_cortex-a72
- aarch64_generic
- arm_arm1176jzf-s_vfp
- arm_arm926ej-s
- arm_cortex-a15_neon-vfpv4
- arm_cortex-a5_vfpv4
- arm_cortex-a7
- arm_cortex-a7_neon-vfpv4
- arm_cortex-a7_vfpv4
- arm_cortex-a8_vfpv3
- arm_cortex-a9
- arm_cortex-a9_neon
- arm_cortex-a9_vfpv3-d16
- arm_fa526
- arm_mpcore
- arm_xscale
- mips64_octeonplus
- mips_24kc
- mips_4kec
- mips_mips32
- mipsel_24kc
- mipsel_24kc_24kf
- mipsel_74kc
- mipsel_mips32
- x86_64
container:
image: openwrt/sdk:${{ matrix.arch }}-${{ matrix.branch }}
options: --user root
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: 'openwrt'
- name: Prepare build
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
run: |
sed -i "s/PKG_REV:=.*$/PKG_REV:=$SHA/;s/PKG_VERSION:=.*$/PKG_VERSION:=$VERSION-$RELEASE-$SHA/" youtubeUnblock/Makefile
- name: Initilalize SDK
id: init_sdk
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
working-directory: /builder
run: |
HOME=/builder ./setup.sh
- name: Build packages
id: build
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
working-directory: /builder
run: |
echo "src-link youtubeUnblock $GITHUB_WORKSPACE" >> feeds.conf
cat feeds.conf
./scripts/feeds update youtubeUnblock
./scripts/feeds install -a -p youtubeUnblock
make defconfig
make package/youtubeUnblock/compile V=s
mv $(find ./bin -type f -name 'youtubeUnblock*.ipk') ./youtubeUnblock-$VERSION-$RELEASE-$SHA-${{ matrix.arch }}-${{ matrix.branch }}.ipk
- name: Upload packages
if: steps.build.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: youtubeUnblock-${{ matrix.branch }}-${{ matrix.arch }}
path: /builder/youtubeUnblock*.ipk
if-no-files-found: error
build-openwrt-luci:
needs: prepare
runs-on: ubuntu-latest
container:
image: openwrt/sdk:x86_64-openwrt-23.05
options: --user root
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: 'openwrt'
- name: Prepare build
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
run: |
sed -i "s/PKG_REV:=.*$/PKG_REV:=$SHA/;s/PKG_VERSION:=.*$/PKG_VERSION:=$VERSION-$RELEASE-$SHA/" youtubeUnblock/Makefile
- name: Initilalize SDK
id: init_sdk
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
working-directory: /builder
run: |
HOME=/builder ./setup.sh
- name: Build packages
id: build
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
working-directory: /builder
run: |
echo "src-link youtubeUnblock $GITHUB_WORKSPACE" >> feeds.conf
cat feeds.conf
./scripts/feeds update youtubeUnblock
./scripts/feeds install -a -p youtubeUnblock
make defconfig
make package/luci-app-youtubeUnblock/compile V=s
mv $(find ./bin -type f -name 'luci-app-youtubeUnblock*.ipk') ./luci-app-youtubeUnblock-$VERSION-$RELEASE-$SHA.ipk
- name: Upload packages
if: steps.build.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: luci-app-youtubeUnblock
path: /builder/luci-app-youtubeUnblock*.ipk
if-no-files-found: error
build-entware:
needs: prepare
runs-on: ubuntu-latest
strategy:
matrix:
arch:
- aarch64-3.10
- armv7-3.2
- mips-3.4
- mipsel-3.4
- x64-3.2
- x86-2.6
- armv7-2.6
container:
image: waujito/entware_builder:${{ matrix.arch }}
options: --user root
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: 'openwrt'
- name: Prepare build
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
run: |
sed -i "s/PKG_REV:=.*$/PKG_REV:=$SHA/;s/PKG_VERSION:=.*$/PKG_VERSION:=$VERSION-$RELEASE-$SHA/" youtubeUnblockEntware/Makefile
- name: Build packages
id: build
working-directory: /home/me/Entware
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
run: |
echo "src-link youtubeUnblock $GITHUB_WORKSPACE" >> feeds.conf
cat feeds.conf
./scripts/feeds update youtubeUnblock
./scripts/feeds install -a -p youtubeUnblock
echo "CONFIG_PACKAGE_youtubeUnblockEntware=m" | tee -a .config
make package/youtubeUnblockEntware/compile V=s
mv $(find ./bin -type f -name 'youtubeUnblockEntware*.ipk') ./youtubeUnblock-$VERSION-$RELEASE-$SHA-entware-${{ matrix.arch }}.ipk
- name: Upload packages
if: steps.build.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: youtubeUnblock-entware-${{ matrix.arch }}
path: /home/me/Entware/youtubeUnblock*.ipk
if-no-files-found: error
pre-release:
if: github.event_name != 'pull_request' && github.ref_name == 'main'
needs: [build-static, build-static-cross, build-openwrt, build-entware, build-openwrt-luci]
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Upload assets
uses: slord399/action-automatic-releases@v1.0.1
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
automatic_release_tag: 'continuous'
prerelease: true
draft: true
title: 'Development build'
files: |
./**/youtubeUnblock*.ipk
./**/youtubeUnblock*.tar.gz
./**/luci-app-youtubeUnblock*.ipk

View File

@@ -1,130 +0,0 @@
name: "youtubeUnblock build test"
on:
push:
branches:
- main
paths-ignore:
- '.editorconfig'
- '.gitignore'
- 'LICENSE'
- 'README.md'
workflow_dispatch:
pull_request:
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.gh.outputs.version }}
sha: ${{ steps.gh.outputs.sha }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: 'openwrt'
- name: GH
id: gh
env:
REPO: ${{ github.repository }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
echo "version=$(cat youtubeUnblock/Makefile | grep PKG_VERSION | sed 's/PKG_VERSION:=//')" >> $GITHUB_OUTPUT
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
echo "sha=$(echo ${GITHUB_SHA::7})" >> $GITHUB_OUTPUT
else
echo "sha=$(gh api repos/$REPO/commits/main --jq '.sha[:7]')" >> $GITHUB_OUTPUT
fi
build-static:
needs: prepare
name: build-static ${{ matrix.arch }}
runs-on: ubuntu-latest
strategy:
matrix:
arch: [x86_64]
branch: [latest-stable]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
id: build
env:
ARCH: ${{ matrix.arch }}
VERSION: ${{ needs.prepare.outputs.version }}
SHA: ${{ needs.prepare.outputs.sha }}
shell: bash
run: |
make -j$(nproc)
strip -s build/youtubeUnblock
cp -va build/youtubeUnblock .
tar -czvf static-youtubeUnblock-$VERSION-$SHA-$PLATFORM.tar.gz youtubeUnblock youtubeUnblock.service README.md
- name: Upload artifacts
if: steps.build.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: static-youtubeUnblock-${{ matrix.arch }}
path: ./**/static-youtubeUnblock*.tar.gz
test:
needs: prepare
name: test
runs-on: ubuntu-latest
strategy:
matrix:
arch: [x86_64]
branch: [latest-stable]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
id: build
shell: bash
run: |
make build_test -j$(nproc)
- name: Test
id: test
run:
./build/testYoutubeUnblock
build-kmod:
needs: prepare
name: build-kmod ${{ matrix.kernel_version }}
runs-on: ubuntu-latest
strategy:
matrix:
kernel_version:
- 6.6.52
- 5.15.167
- 5.4.284
- 4.19.322
- 4.4.302
- 3.10.108
- 3.0.101
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build kernel module
id: build
env:
VERSION: ${{ needs.prepare.outputs.version }}
SHA: ${{ needs.prepare.outputs.sha }}
shell: bash
run: |
docker run --rm -v ./:/youtubeUnblock -w /youtubeUnblock waujito/kernel-bins:${{ matrix.kernel_version }} make kmake KERNEL_BUILDER_MAKEDIR:=/linux
tar -czvf kmod-youtubeUnblock-$VERSION-$SHA-linux-${{ matrix.kernel_version }}.tar.gz kyoutubeUnblock.ko
- name: Upload artifacts
if: steps.build.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: kmod-youtubeUnblock-linux-${{ matrix.kernel_version }}
path: ./**/kmod-youtubeUnblock*.tar.gz

18
.gitignore vendored
View File

@@ -1,18 +0,0 @@
compile_commands.json
.cache
build
configure~
# Kernel module files
*.o
.*
*.mod.*
*.mod
modules.order
Module.symvers
*.so
*.ko
*.a
!/.github

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule ".github/builder_containers/entware_docker"]
path = .github/builder_containers/entware_docker
url = https://github.com/Entware/docker.git

3
Kbuild
View File

@@ -1,3 +0,0 @@
obj-m := kyoutubeUnblock.o
kyoutubeUnblock-objs := src/kytunblock.o src/mangle.o src/quic.o src/quic_crypto.o src/utils.o src/tls.o src/getopt.o src/inet_ntop.o src/args.o deps/cyclone/aes.o deps/cyclone/cpu_endian.o deps/cyclone/ecb.o deps/cyclone/gcm.o deps/cyclone/hkdf.o deps/cyclone/hmac.o deps/cyclone/sha256.o
ccflags-y := -std=gnu99 -DKERNEL_SPACE -Wno-error -Wno-declaration-after-statement -I$(src)/src -I$(src)/deps/cyclone/include

View File

@@ -1,32 +0,0 @@
USPACE_TARGETS := default all install uninstall dev run_dev
KMAKE_TARGETS := kmake kload kunload kreload xmod xtclean
PKG_VERSION := 1.0.0
PKG_RELEASE := 6
PKG_FULLVERSION := $(PKG_VERSION)-$(PKG_RELEASE)
export PKG_VERSION PKG_RELEASE PKG_FULLVERSION
.PHONY: $(USPACE_TARGETS) $(KMAKE_TARGETS) test build_test clean distclean kclean
$(USPACE_TARGETS):
@$(MAKE) -f uspace.mk $@
$(KMAKE_TARGETS):
@$(MAKE) -f kmake.mk $@
build_test:
-@$(MAKE) -f uspace.mk build_test
test:
-@$(MAKE) -f uspace.mk test
clean:
-@$(MAKE) -f uspace.mk clean
distclean: clean
-@$(MAKE) -f uspace.mk distclean
kclean:
-@$(MAKE) -f kmake.mk kclean

View File

@@ -1,30 +0,0 @@
## Padavan
На падаване есть раздел, доступный для записи (/etc/storage), и, докинув нужные модули, можно запустить youtubeUblock на уже установленной прошивке без USB. Установка самого youtubeUblock мало будет отличаться от классичкской установки. Наибольшая сложность заключается в получении модулей ядра специально для вашего роутера.
**Версия youtubeUblock должна быть не меньше v1.0.0-rc4.**
### Сборка прошивки с модулями
Необходимо собрать ядро с модулями nfqueue. Собирать можно у себя локально, а можно и в github actions (https://github.com/shvchk/padavan-builder-workflow)
Добавить строки ниже в `padavan-ng/trunk/configs/boards/TPLINK/TL_C5-V4/kernel-3.4.x.config` (вместо TPLINK/TL_C5-V4 нужно выбрать свою модель):
```sh
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP6_NF_QUEUE=m
```
Сборка
```sh
cd padavan-ng/trunk
cp configs/templates/tplink/tl_c5-v4.config .config
./build_firmware.sh
```
Если финальный размер превышает максимум, то можно отключить что-нибудь в .config, например FTP.
После сборки необходимо установить прошивку на роутер. Подробнее в гитлабе падавана: https://gitlab.com/hadzhioglu/padavan-ng. Как устанавливать: https://4pda.to/forum/index.php?showtopic=975687&st=12980#Spoil-115912586-5
Далее скачать youtubeUnblock, закинуть его на роутер, добавить правила фаервола и запустить. Можно скачивать static бинарник и запускать вручную, а можно загрузить entware на usb или в память, и поставить соответствующую версию youtubeUblock.

484
README.md
View File

@@ -1,484 +0,0 @@
- [youtubeUnblock](#youtubeunblock)
- [Configuration](#configuration)
- [OpenWRT pre configuration](#openwrt-pre-configuration)
- [Entware](#entware)
- [PC configuration](#pc-configuration)
- [Firewall configuration](#firewall-configuration)
- [nftables rules](#nftables-rules)
- [Iptables rules](#iptables-rules)
- [IPv6](#ipv6)
- [Check it](#check-it)
- [Flags](#flags)
- [UDP/QUIC/Voice Chats](#udpquicvoice-chats)
- [Troubleshooting](#troubleshooting)
- [TV](#tv)
- [Troubleshooting EPERMS (Operation not permitted)](#troubleshooting-eperms-operation-not-permitted)
- [Conntrack](#conntrack-troubleshooting)
- [NAT Hardware/Software offloading](#nat-hardwaresoftware-offloading)
- [Compilation](#compilation)
- [OpenWRT case](#openwrt-case)
- [Building OpenWRT .ipk package](#building-openwrt-ipk-package)
- [Building with toolchain](#building-with-toolchain)
- [Kernel module](#kernel-module)
- [Building kernel module](#building-kernel-module)
- [Building on host system](#building-on-host-system)
- [Building on any kernel](#building-on-any-kernel)
- [Building with openwrt SDK](#building-with-openwrt-sdk)
- [Padavan](#padavan)
# youtubeUnblock
Bypasses Deep Packet Inspection (DPI) systems that relies on SNI. The package is for Linux only. It is also fully compatible with routers running [OpenWRT](https://github.com/openwrt).
The program was primarily developed to bypass YouTube Outage in Russia.
```
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 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 General Public License for more details.
```
The program is distributed in two version:
- A userspace application works on top of nfnetlink queue which requires nfnetlink modules in the kernel and firewall rules. This approach is default and normally should be used but it has some limitations on embedded devices which may have no nfnetlink support. Also this solution may break down the internet speed and CPU load on your device because of jumps between userspace and kernelspace for each packet (this behavior may be fixed with connbytes but it also requires conntrack kernel module).
- A kernel module which integrates deeply within the netfilter stack and does not interact with the userspace firewall. The module requires only netfilter kernel support but it definetly present on every device connected to the Internet. The only difficulity is how to build it. I cannot provide modules within Github Actions for each single one kernel, even if we talk only about OpenWRT versions. If you want to learn more about the module, jump on [its section in the README](#kernel-module). Whats the benefits of the kernel module? The benefits come for some specific cases: the kernel module is the fastest thing that allows us to process every single packet sent to the linux network stack, while the normal youtubeUnblock requires connbytes to keep the internet speed. Speaking about connbytes, it also requires conntrack to operate, which may be a limitation on some transit-traffic machines. Also userspace youtubeUnblock requires modules for netlink queue, userspace firewall application and modules for it. The kernel module is much simpler and requires only the linux kernel with netfilter built in.
The program is compatible with routers based on OpenWRT, Entware(Keenetic/ASUS) and host machines. The program offers binaries via Github Actions. The binaries are also available via [github releases](https://github.com/Waujito/youtubeUnblock/releases). Use the latest pre-release for the most up to date build. Check out [Github Actions](https://github.com/Waujito/youtubeUnblock/actions/workflows/build-ci.yml) if you want to see all the binaries compiled ever. You should know the arcitecture of your hardware to use binaries. On OpenWRT you can check it with command `grep ARCH /etc/openwrt_release`.
On both OpenWRT and Entware install the program with opkg. If you got read-only filesystem error you may unpack the binary manually or specify opkg path `opkg -o <destdir>`.
For Windows use [GoodbyeDPI by ValdikSS](https://github.com/ValdikSS/GoodbyeDPI) (you can find how to use it for YouTube [here](https://github.com/ValdikSS/GoodbyeDPI/issues/378)) The same behavior is also implemented in [zapret package for linux](https://github.com/bol-van/zapret).
## Configuration
### OpenWRT pre configuration
When you got the release package, you should install it. Go to your router interface, to *System->Software*, do *Update lists* and install youtubeUnblock via *install_package* button. Then, you should go to *System-Startup* menu and reload the firewall (You may also do it within *Services->youtubeUnblock* menu).
Since OpenWRT **main** branch switched to apk instead of opkg, but this is not released yet, here is not deploys for apk in **Releases**. But **apk is supported** in PR #196.
To make it work you should register an iptables rule and install required kernel modules. The list of modules depends on the version of OpenWRT and which firewall do you use (iptables or nftables). For most modern versions of OpenWRT (v23.x, v22.x) you should use nftables rules, for older ones it depends, but typically iptables.
The common dependency is
```text
kmod-nfnetlink-queue
```
but it is provided as dependency for another firewall packages.
So, if you are on **iptables** you should install:
```text
kmod-ipt-nfqueue
iptables-mod-nfqueue
kmod-ipt-conntrack-extra
iptables-mod-conntrack-extra
```
and of course, iptables user-space app should be available.
On **nftables** the dependencies are:
```text
kmod-nft-queue
kmod-nf-conntrack
```
Next step is to add required firewall rules.
For nftables on OpenWRT rules comes out-of-the-box and stored under `/usr/share/nftables.d/ruleset-post/537-youtubeUnblock.nft`. All you need is install requirements and do `/etc/init.d/firewall reload`. If no, go to [Firewall configuration](#firewall-configuration).
Now we go to the configuration. For OpenWRT here is configuration via [UCI](https://openwrt.org/docs/guide-user/base-system/uci) and [LuCI](https://openwrt.org/docs/guide-user/luci/start) available (CLI and GUI respectively).
For **LuCI** aka **GUI** aka **web-interface of router** you should install **luci-app-youtubeUnblock** package like you did it with the normal youtubeUnblock package. Note, that lists of official opkg feeds should be loaded (**Do it with Update lists option**).
If you got ` * pkg_hash_check_unresolved: cannot find dependency luci-lua-runtime for luci-app-youtubeUnblock` error, you are using old openwrt. Install [this dummy package](https://github.com/xiaorouji/openwrt-passwall/files/12605732/luci-lua-runtime_all_fake.zip). [Check this comment](https://github.com/Waujito/youtubeUnblock/issues/168#issuecomment-2449227547) for more details.
LuCI configuration lives in **Services->youtubeUnblock** section. It is self descriptive, with description for each flag. Note, that after you push `Save & Apply` button, the configuration is applied automatically and the service is restarted.
UCI configuration is available in /etc/config/youtubeUnblock file, in section `youtubeUnblock.youtubeUnblock`. You may pass any args as a string to parameter `args`, but before it disable interactive flags (You can configurate with it but it is a way harder and I recommend to use it only with `luci-app-youtubeUnblock`):
```sh
uci set youtubeUnblock.youtubeUnblock.conf_strat="args"
uci set youtubeUnblock.youtubeUnblock.args="--queue-num=537 --threads=1"
```
To save the configs you should do `uci commit` and then `reload_config` to restart youtubeUnblock
You can check the logs in CLI mode with `logread -l 200 | grep youtubeUnblock` command.
In CLI mode you will use youtubeUnblock as a normal init.d service:
for example, you can enable it with `/etc/init.d/youtubeUnblock enable`.
### Entware
For Entware on Keenetic here is an [installation guide (russian)](https://help.keenetic.com/hc/ru/articles/360021214160-%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BE%D0%B2-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8F-Entware-%D0%BD%D0%B0-USB-%D0%BD%D0%B0%D0%BA%D0%BE%D0%BF%D0%B8%D1%82%D0%B5%D0%BB%D1%8C).
Install the binary with `opkg install youtubeUnblock-*.ipk`. After installation, the binary in /opt/bin and the init script in /opt/etc/init.d/S51youtubeUnblock will be available. To run the youtubeUnblock, simply run `/opt/etc/init.d/S51youtubeUnblock start`
### NFNETLINK_QUEUE kernel modules
Note, that you should feed the target kernel with nfnetlink_queue kernel module. The module may be disabled or even not present. Entware S51youtubeUnblock will try to insert kmods any way but if they are not provided by software, you should install them manually. AFAIK on keenetics here is a repository with modules compiled by customer. You can find them somewhere in the web interface of your device. On other routers you may want to do deeper research in that case and find your kmods. If you can't find anything, you may ask the customer for GPL codes of linux kernel (and may be even OpenWRT) and compile kmods manually.
You should insert the module with (this step may be omitted on Entware and OpenWRT):
```sh
modprobe nfnetlink_queue
```
### PC configuration
On local host make sure to change **FORWARD** to **OUTPUT** chain in the following Firewall rulesets.
Copy `youtubeUnblock.service` to `/usr/lib/systemd/system` (you should change the path inside the file to the program position, for example `/usr/bin/youtubeUnblock`, also you may want to delete default iptables rule addition in systemd file to controll it manually). And run `systemctl start youtubeUnblock`.
### Firewall configuration
#### nftables rules
On nftables you should put next nftables rules:
```sh
nft add chain inet fw4 youtubeUnblock '{ type filter hook postrouting priority mangle - 1; policy accept; }'
nft add rule inet fw4 youtubeUnblock 'tcp dport 443 ct original packets < 20 counter queue num 537 bypass'
nft add rule inet fw4 youtubeUnblock 'meta l4proto udp ct original packets < 9 counter queue num 537 bypass'
nft insert rule inet fw4 output 'mark and 0x8000 == 0x8000 counter accept'
```
#### Iptables rules
On iptables you should put next iptables rules:
```sh
iptables -t mangle -N YOUTUBEUNBLOCK
iptables -t mangle -A YOUTUBEUNBLOCK -p tcp --dport 443 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 537 --queue-bypass
iptables -t mangle -A YOUTUBEUNBLOCK -p udp -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:8 -j NFQUEUE --queue-num 537 --queue-bypass
iptables -t mangle -A POSTROUTING -j YOUTUBEUNBLOCK
iptables -I OUTPUT -m mark --mark 32768/32768 -j ACCEPT
```
#### IPv6
For IPv6 on iptables you need to duplicate rules above for ip6tables:
```sh
ip6tables -t mangle -N YOUTUBEUNBLOCK
ip6tables -t mangle -A YOUTUBEUNBLOCK -p tcp --dport 443 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 537 --queue-bypass
ip6tables -t mangle -A YOUTUBEUNBLOCK -p udp -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:8 -j NFQUEUE --queue-num 537 --queue-bypass
ip6tables -t mangle -A POSTROUTING -j YOUTUBEUNBLOCK
ip6tables -I OUTPUT -m mark --mark 32768/32768 -j ACCEPT
```
Note that above rules use *conntrack* to route only first 20 packets from the connection to **youtubeUnblock**.
If you got some troubles with it, for example **youtubeUnblock** doesn't detect YouTube, try to delete *connbytes* from the rules. But it is an unlikely behavior and you should probably check your ruleset.
You can use `--queue-balance` with multiple instances of **youtubeUnblock** for performance. This behavior is supported via multithreading. Just pass `--threads=n` where n stands for an number of threads you want to be enabled. The n defaults to **1**. The maximum threads defaults to **16** but may be altered programmatically. Note, that if you are about to increase it, here is 100% chance that you are on the wrong way.
Also [DNS over HTTPS](https://github.com/curl/curl/wiki/DNS-over-HTTPS) is preferred for additional anonymity.
## Check it
Here is the command to test whether it working or not:
```sh
curl -o/dev/null -k --connect-to ::google.com -k -L -H Host:\ mirror.gcr.io https://test.googlevideo.com/v2/cimg/android/blobs/sha256:6fd8bdac3da660bde7bd0b6f2b6a46e1b686afb74b9a4614def32532b73f5eaa
```
It should return low speed without **youtubeUnblock** and faster with it. With **youtubeUnblock** the speed should be the same as fast with the next command:
```sh
curl -o/dev/null -k --connect-to ::google.com -k -L -H Host:\ mirror.gcr.io https://mirror.gcr.io/v2/cimg/android/blobs/sha256:6fd8bdac3da660bde7bd0b6f2b6a46e1b686afb74b9a4614def32532b73f5eaa
```
## Flags
Put flags to the **BINARY**, not an init script. If you are on OpenWRT you should put the flags inside the script: open `/etc/init.d/youtubeUnblock` with any text editor, like vi or nano and put your flags after `procd_set_param command /usr/bin/youtubeUnblock` line.
Available flags:
#### General flags
Flags that do not scoped to a specific section, used over all the youtubeUnblock
- `--queue-num=<number of netfilter queue>` The number of netfilter queue **youtubeUnblock** will be linked to. Defaults to **537**.
- `--silent` Disables verbose mode.
- `--trace` Maximum verbosity for debugging purposes.
- `--instaflush` Used with tracing. Flushes the buffer instantly, without waiting for explicit new line. Highly useful for debugging crushes.
- `--no-gso` Disables support for TCP fat packets which uses GSO. This feature is well tested now, so this flag probably won't fix anything.
- `--use-conntrack` Enables support for conntrack in youtubeUnblock. Disabled by default. Enabled in kernel module.
- `--no-ipv6` Disables support for ipv6. May be useful if you don't want for ipv6 socket to be opened.
- `--threads=<threads number>` Specifies the amount of threads you want to be running for your program. This defaults to **1** and shouldn't be edited for normal use. But if you really want multiple queue instances of youtubeUnblock, note that you should change --queue-num to --queue balance. For example, with 4 threads, use `--queue-balance 537:540` on iptables and `queue num 537-540` on nftables.
- `--connbytes-limit=<pkts>` **Kernel module only!** Specify how much packets of connection should be processed by kyoutubeUnblock. Pass 0 if you want for each packet to be processed. This flag may be useful for UDP traffic since unlimited youtubeUnblock may lead to traffic flood and unexpected bans. Defaults to 19. In most cases you don't want to change it.
- `--daemonize` Daemonizes the youtubeUnblock (forks and detaches it from the shell). Terminate the program with `killall youtubeUnblock`. If you want to track the logs of youtubeUnblock in logread or journalctl, use **--syslog** flag.
- `--syslog` Redirects logs to the system log. You can read it with `journalctl` or `logread`.
- `--noclose` Usable only with `--daemonize`. Will not redirect io streams to /dev/null.
- `--packet-mark=<mark>` Use this option if youtubeUnblock conflicts with other systems rely on packet mark. Note that you may want to change accept rule for iptables to follow the mark.
#### Section scoped flags
- `--fbegin` and `--fend` flags: youtubeUnblock supports multiple sets of strategies for specific filters. You may want to initiate a new set after the default one, like: `--sni-domains=googlevideo.com --faking-strategy=md5sum --fbegin --sni-domains=youtube.com --faking-strategy=tcp_check --fbegin --sni-domains=l.google.com --faking-strategy=pastseq`. Note, that the priority of these sets goes backwards: last is first, default (one that does not start with --fbegin) is last. If you start the new section, the default settings are implemented just like youtubeUnblock without any parameters. Note that the config above is just an example and won't work for you.
- `--tls={enabled|disabled}` Set it if you want not to process TLS traffic in current section. May be used if you want to set only UDP-based section. (Here section is a unit between `--fbegin` and `--fend` flags).
- `--fake-sni={0|1}` This flag enables fake-sni which forces **youtubeUnblock** to send at least three packets instead of one with TLS *ClientHello*: Fake *ClientHello*, 1st part of original *ClientHello*, 2nd part of original *ClientHello*. This flag may be related to some Operation not permitted error messages, so before open an issue refer to [Troubleshooting for EPERMS](#troubleshooting-eperms-operation-not-permitted). Defaults to **1**.
- `--fake-sni-seq-len=<length>` This flag specifies **youtubeUnblock** to build a complicated construction of fake client hello packets. length determines how much fakes will be sent. Defaults to **1**.
- `--fake-sni-type={default|custom|random}` This flag specifies which faking message type should be used for fake packets. For `random`, the message of random length and with random payload will be sent. For `default` the default payload (sni=www.google.com) is used. And for the `custom` option, the payload from `--fake-custom-payload` section utilized. Defaults to `default`.
- `--fake-custom-payload=<payload>` Useful with `--fake-sni-type=custom`. You should specify the payload for fake message manually. Use hex format: `--fake-custom-payload=0001020304` mean that 5 bytes sequence: `0x00`, `0x01`, `0x02`, `0x03`, `0x04` used as fake.
- `--fake-custom-payload-file=<binary file containing TLS message>` Same as `--fake-custom-payload` but binary file instead of hex. The file should contain raw binary TLS message (TCP payload).
- `--faking-strategy={randseq|ttl|tcp_check|pastseq|md5sum}` This flag determines the strategy of fake packets invalidation. Defaults to `randseq`
- `randseq` specifies that random sequence/acknowledgment random will be set. This option may be handled by provider which uses *conntrack* with drop on invalid *conntrack* state firewall rule enabled.
- `ttl` specifies that packet will be invalidated after `--faking-ttl=n` hops. `ttl` is better but may cause issues if unconfigured.
- `pastseq` is like `randseq` but sequence number is not random but references the packet sent in the past (before current).
- `tcp_check` will invalidate faking packet with invalid checksum. May be handled and dropped by some providers/TSPUs.
- `md5sum` will invalidate faking packet with invalid TCP md5sum. md5sum is a TCP option which is handled by the destination server but may be skipped by TSPU.
- `--faking-ttl=<ttl>` Tunes the time to live (TTL) of fake SNI messages. TTL is specified like that the packet will go through the DPI system and captured by it, but will not reach the destination server. Defaults to **8**.
- `--fake-seq-offset` Tunes the offset from original sequence number for fake packets. Used by randseq faking strategy. Defaults to 10000. If 0, random sequence number will be set.
- `--frag={tcp,ip,none}` Specifies the fragmentation strategy for the packet. tcp is used by default. Ip fragmentation may be blocked by DPI system. None specifies no fragmentation. Probably this won't work, but may be will work for some fake sni strategies.
- `--frag-sni-reverse={0|1}` Specifies **youtubeUnblock** to send *ClientHello* fragments in the reverse order. Defaults to **1**.
- `--frag-sni-faked={0|1}` Specifies **youtubeUnblock** to send fake packets near *ClientHello* (fills payload with zeroes). Defaults to **0**.
- `--frag-middle-sni={0|1}` With this options **youtubeUnblock** will split the packet in the middle of SNI data. Defaults to 1.
- `--frag-sni-pos=<pos>` With this option **youtubeUnblock** will split the packet at the position pos. Defaults to 1.
- `--fk-winsize=<winsize>` Specifies window size for the fragmented TCP packet. Applicable if you want for response to be fragmented. May slowdown connection initialization.
- `--synfake={1|0}` If 1, syn payload will be sent before each request. The idea is taken from syndata from zapret project. Syn payload will normally be discarded by endpoint but may be handled by TSPU. This option sends normal fake in that payload. Please note, that the option works for all the sites, so --sni-domains won't change anything.
- `--synfake-len=<len>` The fake packet sent in synfake may be too large. If you experience issues, lower up synfake-len. where len stands for how much bytes should be sent as syndata. Pass 0 if you want to send an entire fake packet. Defaults to 0
- `--sni-detection={parse|brute}` Specifies how to detect SNI. Parse will normally detect it by parsing the Client Hello message. Brute will go through the entire message and check possibility of SNI occurrence. Please note, that when `--sni-domains` option is not all brute will be O(nm) time complexity where n stands for length of the message and m is number of domains. Defaults to parse.
- `--seg2delay=<delay>` This flag forces **youtubeUnblock** to wait a little bit before send the 2nd part of the split packet.
- `--sni-domains=<comma separated domain list>|all` List of domains you want to be handled by SNI. Use this string if you want to change default domain list. Defaults to `googlevideo.com,ggpht.com,ytimg.com,youtube.com,play.google.com,youtu.be,googleapis.com,googleusercontent.com,gstatic.com,l.google.com`. You can pass **all** if you want for every *ClientHello* to be handled. You can exclude some domains with `--exclude-domains` flag.
- `--exclude-domains=<comma separated domain list>` List of domains to be excluded from targeting.
- `--sni-domains-file=<file contains comma or new-line separated list>` Same as `--sni-domains` but accepts path to container file instead of inline domains list. The format is file may consist of both comma-separated domains list as well as new-line separated list.
- `--exclude-domains-file=<file contains comma or new-line separated list>` Same as `--exclude-domains` but accepts path to container file instead of inline domains list. The format is file may consist of both comma-separated domains list as well as new-line separated list.
- `--udp-mode={drop|fake}` This flag specifies udp handling strategy. If drop udp packets will be dropped (useful for quic when browser can fallback to tcp), if fake udp will be faked. Defaults to fake.
- `--udp-fake-seq-len=<amount of faking packets sent>` Specifies how much faking packets will be sent over the network. Defaults to 6.
- `--udp-fake-len=<size of udp fake>` Size of udp fake payload (typically payload is zeroes). Defaults to 64.
- `--udp-dport-filter=<5,6,200-500>` Filter the UDP destination ports. Defaults to no ports. Specifie the ports you want to be handled by youtubeUnblock.
- `--udp-faking-strategy={checksum|ttl|none}` Faking strategy for udp. `checksum` will fake UDP checksum, `ttl` won't fake but will make UDP content relatively small, `none` is no faking. Defaults to none.
- `--udp-filter-quic={disabled|all|parse}` Enables QUIC filtering for UDP handler. If disabled, quic won't be processed, if all, all quic initial packets will be handled. `parse` will decrypt and parse QUIC initial message and match it with `--sni-domains`. Defaults to disabled.
- `--quic-drop` Drop all QUIC packets which goes to youtubeUnblock. Won't affect any other UDP packets. Just an alias for `--udp-filter-quic=all --udp-mode=drop`.
- `--no-dport-filter` By default, youtubeUnblock will filter for TLS and QUIC 443. If you want to disable it, pass this flag. (this does not affect `--udp-dport-filter`)
## UDP/QUIC/Voice Chats
UDP is another communication protocol. Well-known technologies that use it are DNS, QUIC, voice chats. UDP does not provide reliable connection and its header is much simpler than TCP thus fragmentation is limited. The support provided primarily by faking.
**For UDP faking in kernel module** Make sure to decrease `--connbytes-limit` up to 5. This will allow not to process additional packets and prevent network flood.
Right now, QUIC faking may not work well, so use `--udp-mode=drop` option.
QUIC is enabled with `--udp-filter-quic` flag. The flag supports two modes: `all` will handle all the QUIC initial messages and `parse` will decrypt and parse the QUIC initial message, and then compare it with `--sni-domains` flag.
**I recommend to use** `--udp-mode=drop --udp-filter-quic=parse`.
For **other UDP protocols** I recommend to configure UDP support in the separate section from TCP, like `--fbegin --udp-dport-filter=50000-50099 --tls=disabled`. See more in flags related to udp and [tickets tagged with udp label](https://github.com/Waujito/youtubeUnblock/issues?q=label%3Audp+).
## Troubleshooting
Check up [this issue](https://github.com/Waujito/youtubeUnblock/issues/148) for useful configs.
If you got troubles with some sites and you sure that they are blocked by SNI (youtube for example), use may play around with [flags](#flags) and their combinations. At first it is recommended to try `--faking-strategy` flag and `--frag-sni-faked=1`.
If you have troubles with some sites being proxied, you can play with flags values. For example, for someone `--faking-strategy=ttl` works. You should specify proper `--fake-sni-ttl=<ttl value>` where ttl is the amount of hops between you and DPI.
If you are on Chromium you may have to disable *kyber* (the feature that makes the TLS *ClientHello* very big). I've got the problem with it on router, so to escape possible errors, so it is better to disable it: in `chrome://flags` search for kyber and switch it to disabled state. Alternatively you may set `--sni-detection=brute` and probably adjust `--sni-domains` flag.
*Kyber* on firefox disables with `security.tls.enable_kyber` in `about:config`.
If your browser is using QUIC it may not work properly. Disable it in Chrome in `chrome://flags` and in Firefox `network.http.http{2,3}.enable(d)` in `about:config` option.
It seems like some TSPUs started to block wrongseq packets, so you should play around with faking strategies. I personally recommend to start with `md5sum` faking strategy.
### TV
Televisions are the biggest headache.
In [this issue](https://github.com/Waujito/youtubeUnblock/issues/59) the problem has been resolved. And now youtubeUnblock should work with default flags. If not, play around with faking strategies and other flags. Also you might be have to disable QUIC. To do it you may use `--quic-drop` [flag](#flags) with proper firewall configuration (check description of the flag). Note, that this flag won't disable gQUIC and some TVs may relay on it. To disable gQUIC you will need to block the entire 443 port for udp in firewall configuration:
For **nftables** do
```
nft insert rule inet fw4 forward ip saddr 192.168.. udp dport 443 counter drop
```
For **iptables**
```
iptables -I FORWARD --src 192.168.. -p udp --dport 443 -j DROP
```
Where you have to replace 192.168.. with ip of your television.
### Troubleshooting EPERMS (Operation not permitted)
*EPERM* may occur in a lot of places but generally here are two: *mnl_cb_run* and when sending the packet via *rawsocket* (raw_frags_send and send fake sni).
- **mnl_cb_run** *Operation not permitted* indicates that another instance of youtubeUnblock is running on the specified queue-num.
- **rawsocket** *Operation not permitted* indicates that the packet is being dropped by nefilter rules. In fact this is a hint from the kernel that something wrong is going on and we should check the firewall rules. Before dive into the problem let's make it clean how the mangled packets are being sent. Nefilter queue provides us with the ability to mangle the packet on fly but that is not suitable for this program because we need to split the packet to at least two independent packets. So we are using [linux raw sockets](https://man7.org/linux/man-pages/man7/raw.7.html) which allows us to send any ipv4 packet. **The packet goes from the OUTPUT chain even when NFQUEUE is set up on FORWARD (suitable for OpenWRT).** So we need to escape packet rejects here.
* raw_frags_send EPERM: just make sure outgoing traffic is allowed (RELATED,ESTABLISHED should work, if not, go to step 3)
* send fake sni EPERM: Fake SNI is out-of-state thing and will likely corrupt the connection (the behavior is expected). conntrack considers it as an invalid packet. By default OpenWRT set up to drop outgoing packets like this one. You may delete nftables/iptables rule that drops packets with invalid conntrack state, but I don't recommend to do this. The step 3 is better solution.
* Step 3, ultimate solution. Use mark (don't confuse with connmark). The youtubeUnblock uses mark internally to avoid infinity packet loops (when the packet is sent by youtubeUnblock but on next step handled by itself). Currently it uses mark (1 << 15) = 32768. You should put iptables/nftables that ultimately accepts such marks at the very start of the filter OUTPUT chain: `iptables -I OUTPUT -m mark --mark 32768/32768 -j ACCEPT` or `nft insert rule inet fw4 output mark and 0x8000 == 0x8000 counter accept`.
### Conntrack troubleshooting
youtubeUnblock *optionally* depends on conntrack.
For kernel module, if conntrack breaks dependencies, compile it with `make kmake EXTRA_CFLAGS="-DNO_CONNTRACK"` to disable it completly.
If you want to be able to use connbytes in custom stack where conntrack is broken, check #220 and #213 for possible references.
### NAT Hardware/Software offloading
youtubeUnblock will conflict with offloading. But hopefully youtubeUnblock need to process only a bunch of first packets in the connection. So, on some devices it is indeed possible to use youtubeUnblock alongside with offloading, especially on ones driven by nftables (OpenWRT 23+). Note, that this is not tested by me but [reported as a workaround](https://github.com/Waujito/youtubeUnblock/issues/199#issuecomment-2519418553) by users:
Edit `/usr/share/firewall4/templates/ruleset.uc` by replacing
```
meta l4proto { tcp, udp } flow offload @ft;
```
with
```
meta l4proto { tcp, udp } ct original packets ge 30 flow offload @ft;
```
And restart firewall with `service firewall restart`
## Compilation
Before compilation make sure `gcc`, `make`, `autoconf`, `automake`, `pkg-config` and `libtool` is installed. For Fedora `glibc-static` should be installed as well.
Compile with `make`. Install with `make install`. The package include `libnetfilter_queue`, `libnfnetlink` and `libmnl` as static dependencies. The package requires `linux-headers` and kernel built with netfilter nfqueue support.
## OpenWRT case
The package is also compatible with routers. The router should be running by linux-based system such as [OpenWRT](https://openwrt.org/).
You can build under OpenWRT with two options: first - through the SDK, which is preferred way and second is cross-compile manually with OpenWRT toolchain.
### Building OpenWRT .ipk package
OpenWRT provides a high-level SDK for the package builds.
First step is to download or compile OpenWRT SDK for your specific platform. The SDK can be compiled according to [this tutorial](https://openwrt.org/docs/guide-developer/toolchain/using_the_sdk).
Beside of raw source code of SDK, OpenWRT also offers precompiled SDKs for your router. You can find it on the router page. For example, I have ramips/mt76x8 based router so for me the sdk is on https://downloads.openwrt.org/releases/23.05.3/targets/ramips/mt76x8/ and called `openwrt-sdk-23.05.3-ramips-mt76x8_gcc-12.3.0_musl.Linux-x86_64`.
You will need to [install sdk requirements on your system](https://openwrt.org/docs/guide-developer/toolchain/install-buildsystem) If you have any problems, use docker ubuntu:24.04 image. Make sure to be a non-root user since some makesystem fails with it. Next, untar the SDK and cd into it.
Do
```sh
echo "src-git youtubeUnblock https://github.com/Waujito/youtubeUnblock.git;openwrt" >> feeds.conf
./scripts/feeds update youtubeUnblock
./scripts/feeds install -a -p youtubeUnblock
make package/youtubeUnblock/compile
```
Now the packet is built and you can import it to the router. Find it in `bin/packages/<target>/youtubeUnblock/youtubeUnblock-<version>.ipk`.
### Building with toolchain
The precompiled toolchain located near the SDK. For example it is called `openwrt-toolchain-23.05.3-ramips-mt76x8_gcc-12.3.0_musl.Linux-x86_64.tar.xz`. When you download the toolchain, untar it somewhere. Now we are ready for compilation. My cross gcc asked me to create a staging dir for it and pass it as an environment variable. Also you should notice toolsuite packages and replace my make command with yours.
```
STAGING_DIR=temp make CC=/usr/bin/mipsel-openwrt-linux-gcc LD=/usr/bin/mipsel-openwrt-linux-ld AR=/usr/bin/mipsel-openwrt-linux-ar OBJDUMP=/usr/bin/mipsel-openwrt-linux-objdump NM=/usr/bin/mipsel-openwrt-linux-nm STRIP=/usr/bin/mipsel-openwrt-linux-strip CROSS_COMPILE_PLATFORM=mipsel-buildroot-linux-gnu
```
Take a look at `CROSS_COMPILE_PLATFORM` It is required by autotools but I think it is not necessary. Anyways I put `mipsel-buildroot-linux-gnu` in here. For your router model name maybe an [automake cross-compile manual](https://www.gnu.org/software/automake/manual/html_node/Cross_002dCompilation.html) will be helpful.
When compilation is done, the binary file will be in build directory. Copy it to your router. Note that a ssh access is likely to be required to proceed. *sshfs* don't work on my model so I injected the application to the router via *Software Upload Package* page. It has given me an error, but also a `/tmp/upload.ipk` file which I copied in root directory, `chmod +x` it and run.
## Kernel module
This section describes the kernel module version of youtubeUnblock. The kernel module operates as a normal module inside the kernel and integrates within the netfilter stack to statelessly mangle the packets sent over the Internet.
You can configure the module with its flags:
```sh
insmod kyoutubeUnblock.ko
echo "--fake_sni=1 --exclude_domains=.ru --quic_drop" | sudo tee /sys/module/kyoutubeUnblock/parameters/parameters
```
You can also do
```sh
cat /sys/module/kyoutubeUnblock/parameters/parameters
```
and check all the parameters configured.
### Building kernel module
#### Building on host system
To build the kernel module on your host system you should install `linux-headers` which will provide build essential tools and `gcc` compiler suite. On host system you may build the module with
```sh
make kmake
```
#### Building on any kernel
To build the module for external kernel you should build that kernel locally and point make to it. Use `KERNEL_BUILDER_MAKEDIR=~/linux` flag for make, for example:
```
make kmake KERNEL_BUILDER_MAKEDIR=~/linux
```
Note, that the kernel should be already configured and built. See linux kernel building manuals for more information about your specific case.
#### Building with openwrt SDK
Building with openwrt SDK is not such a hard thing. The only thing you should do is to obtain the sdk. You can find it by looking to your architecture and version of the openwrt currently used. You should use the exactly your version of openwrt since kernels there change often. You can find the sdk in two ways: by downloading it from their site or by using the openwrt sdk docker container (recommended).
If you decide to download the tar archive, follow next steps:
For me the archive lives in https://downloads.openwrt.org/releases/23.05.3/targets/ramips/mt76x8/ and called `openwrt-sdk-23.05.3-ramips-mt76x8_gcc-12.3.0_musl.Linux-x86_64`. You will need to [install sdk requirements on your system](https://openwrt.org/docs/guide-developer/toolchain/install-buildsystem) If you have any problems, use docker ubuntu:24.04 image. Make sure to be a non-root user since some makesystem fails with it. Next, untar the SDK and cd into it.
Or you can obtain the docker image with sdk built-in: [https://hub.docker.com/u/openwrt/sdk](https://hub.docker.com/u/openwrt/sdk). In my case the image has tag `ramips-mt76x8-23.05.3`. A good thing here is that you don't need to install any dependencies inside the docker container. Also docker hub has a perfect search around tags if you don't sure which one corresponds to your device.
When you unpacked/installed the sdk, you is ready to start with building the kernel module.
Do
```sh
echo "src-git youtubeUnblock https://github.com/Waujito/youtubeUnblock.git;openwrt" >> feeds.conf
./scripts/feeds update youtubeUnblock
./scripts/feeds install -a -p youtubeUnblock
make defconfig
make package/kyoutubeUnblock/compile V=s
```
When the commands finish, the module is ready. Find it with `find bin -name "kmod-youtubeUnblock*.ipk"`, copy to your host and install to the router via gui software interface. The module should start immediately. If not, do `modprobe kyoutubeUnblock`.
## Padavan
YoutubeUnblock may also run on Padavan. [Check the manual here\[rus\]](Padavan.md)
>If you have any questions/suggestions/problems feel free to open an [issue](https://github.com/Waujito/youtubeUnblock/issues).

24
deps/cyclone/Makefile vendored
View File

@@ -1,24 +0,0 @@
SRCS := $(shell find -name "*.c")
OBJS := $(SRCS:%.c=build/%.o)
override CFLAGS += -Iinclude -Wno-pedantic
LIBNAME := libcyclone.a
CC := gcc
run: $(OBJS)
@echo "AR $(LIBNAME)"
@ar rcs libcyclone.a $(OBJS)
prep_dirs:
mkdir -p build
build/%.o: %.c prep_dirs
$(CC) $(CFLAGS) -c -o $@ $<
clean:
@rm $(OBJS) || true
@rm libcyclone.a || true
@rm -rf build || true

577
deps/cyclone/aes.c vendored
View File

@@ -1,577 +0,0 @@
/**
* @file aes.c
* @brief AES (Advanced Encryption Standard)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @section Description
*
* AES is an encryption standard based on Rijndael algorithm, a symmetric block
* cipher that can process data blocks of 128 bits, using cipher keys with
* lengths of 128, 192, and 256 bits. Refer to FIPS 197 for more details
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
//Switch to the appropriate trace level
#define TRACE_LEVEL CRYPTO_TRACE_LEVEL
//Dependencies
#include "core/crypto.h"
#include "cipher/aes.h"
//Check crypto library configuration
#if (AES_SUPPORT == ENABLED)
//Substitution table used by encryption algorithm (S-box)
static const uint8_t sbox[256] =
{
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};
//Substitution table used by decryption algorithm (inverse S-box)
static const uint8_t isbox[256] =
{
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};
//Precalculated table (encryption)
static const uint32_t te[256] =
{
0xA56363C6, 0x847C7CF8, 0x997777EE, 0x8D7B7BF6, 0x0DF2F2FF, 0xBD6B6BD6, 0xB16F6FDE, 0x54C5C591,
0x50303060, 0x03010102, 0xA96767CE, 0x7D2B2B56, 0x19FEFEE7, 0x62D7D7B5, 0xE6ABAB4D, 0x9A7676EC,
0x45CACA8F, 0x9D82821F, 0x40C9C989, 0x877D7DFA, 0x15FAFAEF, 0xEB5959B2, 0xC947478E, 0x0BF0F0FB,
0xECADAD41, 0x67D4D4B3, 0xFDA2A25F, 0xEAAFAF45, 0xBF9C9C23, 0xF7A4A453, 0x967272E4, 0x5BC0C09B,
0xC2B7B775, 0x1CFDFDE1, 0xAE93933D, 0x6A26264C, 0x5A36366C, 0x413F3F7E, 0x02F7F7F5, 0x4FCCCC83,
0x5C343468, 0xF4A5A551, 0x34E5E5D1, 0x08F1F1F9, 0x937171E2, 0x73D8D8AB, 0x53313162, 0x3F15152A,
0x0C040408, 0x52C7C795, 0x65232346, 0x5EC3C39D, 0x28181830, 0xA1969637, 0x0F05050A, 0xB59A9A2F,
0x0907070E, 0x36121224, 0x9B80801B, 0x3DE2E2DF, 0x26EBEBCD, 0x6927274E, 0xCDB2B27F, 0x9F7575EA,
0x1B090912, 0x9E83831D, 0x742C2C58, 0x2E1A1A34, 0x2D1B1B36, 0xB26E6EDC, 0xEE5A5AB4, 0xFBA0A05B,
0xF65252A4, 0x4D3B3B76, 0x61D6D6B7, 0xCEB3B37D, 0x7B292952, 0x3EE3E3DD, 0x712F2F5E, 0x97848413,
0xF55353A6, 0x68D1D1B9, 0x00000000, 0x2CEDEDC1, 0x60202040, 0x1FFCFCE3, 0xC8B1B179, 0xED5B5BB6,
0xBE6A6AD4, 0x46CBCB8D, 0xD9BEBE67, 0x4B393972, 0xDE4A4A94, 0xD44C4C98, 0xE85858B0, 0x4ACFCF85,
0x6BD0D0BB, 0x2AEFEFC5, 0xE5AAAA4F, 0x16FBFBED, 0xC5434386, 0xD74D4D9A, 0x55333366, 0x94858511,
0xCF45458A, 0x10F9F9E9, 0x06020204, 0x817F7FFE, 0xF05050A0, 0x443C3C78, 0xBA9F9F25, 0xE3A8A84B,
0xF35151A2, 0xFEA3A35D, 0xC0404080, 0x8A8F8F05, 0xAD92923F, 0xBC9D9D21, 0x48383870, 0x04F5F5F1,
0xDFBCBC63, 0xC1B6B677, 0x75DADAAF, 0x63212142, 0x30101020, 0x1AFFFFE5, 0x0EF3F3FD, 0x6DD2D2BF,
0x4CCDCD81, 0x140C0C18, 0x35131326, 0x2FECECC3, 0xE15F5FBE, 0xA2979735, 0xCC444488, 0x3917172E,
0x57C4C493, 0xF2A7A755, 0x827E7EFC, 0x473D3D7A, 0xAC6464C8, 0xE75D5DBA, 0x2B191932, 0x957373E6,
0xA06060C0, 0x98818119, 0xD14F4F9E, 0x7FDCDCA3, 0x66222244, 0x7E2A2A54, 0xAB90903B, 0x8388880B,
0xCA46468C, 0x29EEEEC7, 0xD3B8B86B, 0x3C141428, 0x79DEDEA7, 0xE25E5EBC, 0x1D0B0B16, 0x76DBDBAD,
0x3BE0E0DB, 0x56323264, 0x4E3A3A74, 0x1E0A0A14, 0xDB494992, 0x0A06060C, 0x6C242448, 0xE45C5CB8,
0x5DC2C29F, 0x6ED3D3BD, 0xEFACAC43, 0xA66262C4, 0xA8919139, 0xA4959531, 0x37E4E4D3, 0x8B7979F2,
0x32E7E7D5, 0x43C8C88B, 0x5937376E, 0xB76D6DDA, 0x8C8D8D01, 0x64D5D5B1, 0xD24E4E9C, 0xE0A9A949,
0xB46C6CD8, 0xFA5656AC, 0x07F4F4F3, 0x25EAEACF, 0xAF6565CA, 0x8E7A7AF4, 0xE9AEAE47, 0x18080810,
0xD5BABA6F, 0x887878F0, 0x6F25254A, 0x722E2E5C, 0x241C1C38, 0xF1A6A657, 0xC7B4B473, 0x51C6C697,
0x23E8E8CB, 0x7CDDDDA1, 0x9C7474E8, 0x211F1F3E, 0xDD4B4B96, 0xDCBDBD61, 0x868B8B0D, 0x858A8A0F,
0x907070E0, 0x423E3E7C, 0xC4B5B571, 0xAA6666CC, 0xD8484890, 0x05030306, 0x01F6F6F7, 0x120E0E1C,
0xA36161C2, 0x5F35356A, 0xF95757AE, 0xD0B9B969, 0x91868617, 0x58C1C199, 0x271D1D3A, 0xB99E9E27,
0x38E1E1D9, 0x13F8F8EB, 0xB398982B, 0x33111122, 0xBB6969D2, 0x70D9D9A9, 0x898E8E07, 0xA7949433,
0xB69B9B2D, 0x221E1E3C, 0x92878715, 0x20E9E9C9, 0x49CECE87, 0xFF5555AA, 0x78282850, 0x7ADFDFA5,
0x8F8C8C03, 0xF8A1A159, 0x80898909, 0x170D0D1A, 0xDABFBF65, 0x31E6E6D7, 0xC6424284, 0xB86868D0,
0xC3414182, 0xB0999929, 0x772D2D5A, 0x110F0F1E, 0xCBB0B07B, 0xFC5454A8, 0xD6BBBB6D, 0x3A16162C
};
//Precalculated table (decryption)
static const uint32_t td[256] =
{
0x50A7F451, 0x5365417E, 0xC3A4171A, 0x965E273A, 0xCB6BAB3B, 0xF1459D1F, 0xAB58FAAC, 0x9303E34B,
0x55FA3020, 0xF66D76AD, 0x9176CC88, 0x254C02F5, 0xFCD7E54F, 0xD7CB2AC5, 0x80443526, 0x8FA362B5,
0x495AB1DE, 0x671BBA25, 0x980EEA45, 0xE1C0FE5D, 0x02752FC3, 0x12F04C81, 0xA397468D, 0xC6F9D36B,
0xE75F8F03, 0x959C9215, 0xEB7A6DBF, 0xDA595295, 0x2D83BED4, 0xD3217458, 0x2969E049, 0x44C8C98E,
0x6A89C275, 0x78798EF4, 0x6B3E5899, 0xDD71B927, 0xB64FE1BE, 0x17AD88F0, 0x66AC20C9, 0xB43ACE7D,
0x184ADF63, 0x82311AE5, 0x60335197, 0x457F5362, 0xE07764B1, 0x84AE6BBB, 0x1CA081FE, 0x942B08F9,
0x58684870, 0x19FD458F, 0x876CDE94, 0xB7F87B52, 0x23D373AB, 0xE2024B72, 0x578F1FE3, 0x2AAB5566,
0x0728EBB2, 0x03C2B52F, 0x9A7BC586, 0xA50837D3, 0xF2872830, 0xB2A5BF23, 0xBA6A0302, 0x5C8216ED,
0x2B1CCF8A, 0x92B479A7, 0xF0F207F3, 0xA1E2694E, 0xCDF4DA65, 0xD5BE0506, 0x1F6234D1, 0x8AFEA6C4,
0x9D532E34, 0xA055F3A2, 0x32E18A05, 0x75EBF6A4, 0x39EC830B, 0xAAEF6040, 0x069F715E, 0x51106EBD,
0xF98A213E, 0x3D06DD96, 0xAE053EDD, 0x46BDE64D, 0xB58D5491, 0x055DC471, 0x6FD40604, 0xFF155060,
0x24FB9819, 0x97E9BDD6, 0xCC434089, 0x779ED967, 0xBD42E8B0, 0x888B8907, 0x385B19E7, 0xDBEEC879,
0x470A7CA1, 0xE90F427C, 0xC91E84F8, 0x00000000, 0x83868009, 0x48ED2B32, 0xAC70111E, 0x4E725A6C,
0xFBFF0EFD, 0x5638850F, 0x1ED5AE3D, 0x27392D36, 0x64D90F0A, 0x21A65C68, 0xD1545B9B, 0x3A2E3624,
0xB1670A0C, 0x0FE75793, 0xD296EEB4, 0x9E919B1B, 0x4FC5C080, 0xA220DC61, 0x694B775A, 0x161A121C,
0x0ABA93E2, 0xE52AA0C0, 0x43E0223C, 0x1D171B12, 0x0B0D090E, 0xADC78BF2, 0xB9A8B62D, 0xC8A91E14,
0x8519F157, 0x4C0775AF, 0xBBDD99EE, 0xFD607FA3, 0x9F2601F7, 0xBCF5725C, 0xC53B6644, 0x347EFB5B,
0x7629438B, 0xDCC623CB, 0x68FCEDB6, 0x63F1E4B8, 0xCADC31D7, 0x10856342, 0x40229713, 0x2011C684,
0x7D244A85, 0xF83DBBD2, 0x1132F9AE, 0x6DA129C7, 0x4B2F9E1D, 0xF330B2DC, 0xEC52860D, 0xD0E3C177,
0x6C16B32B, 0x99B970A9, 0xFA489411, 0x2264E947, 0xC48CFCA8, 0x1A3FF0A0, 0xD82C7D56, 0xEF903322,
0xC74E4987, 0xC1D138D9, 0xFEA2CA8C, 0x360BD498, 0xCF81F5A6, 0x28DE7AA5, 0x268EB7DA, 0xA4BFAD3F,
0xE49D3A2C, 0x0D927850, 0x9BCC5F6A, 0x62467E54, 0xC2138DF6, 0xE8B8D890, 0x5EF7392E, 0xF5AFC382,
0xBE805D9F, 0x7C93D069, 0xA92DD56F, 0xB31225CF, 0x3B99ACC8, 0xA77D1810, 0x6E639CE8, 0x7BBB3BDB,
0x097826CD, 0xF418596E, 0x01B79AEC, 0xA89A4F83, 0x656E95E6, 0x7EE6FFAA, 0x08CFBC21, 0xE6E815EF,
0xD99BE7BA, 0xCE366F4A, 0xD4099FEA, 0xD67CB029, 0xAFB2A431, 0x31233F2A, 0x3094A5C6, 0xC066A235,
0x37BC4E74, 0xA6CA82FC, 0xB0D090E0, 0x15D8A733, 0x4A9804F1, 0xF7DAEC41, 0x0E50CD7F, 0x2FF69117,
0x8DD64D76, 0x4DB0EF43, 0x544DAACC, 0xDF0496E4, 0xE3B5D19E, 0x1B886A4C, 0xB81F2CC1, 0x7F516546,
0x04EA5E9D, 0x5D358C01, 0x737487FA, 0x2E410BFB, 0x5A1D67B3, 0x52D2DB92, 0x335610E9, 0x1347D66D,
0x8C61D79A, 0x7A0CA137, 0x8E14F859, 0x893C13EB, 0xEE27A9CE, 0x35C961B7, 0xEDE51CE1, 0x3CB1477A,
0x59DFD29C, 0x3F73F255, 0x79CE1418, 0xBF37C773, 0xEACDF753, 0x5BAAFD5F, 0x146F3DDF, 0x86DB4478,
0x81F3AFCA, 0x3EC468B9, 0x2C342438, 0x5F40A3C2, 0x72C31D16, 0x0C25E2BC, 0x8B493C28, 0x41950DFF,
0x7101A839, 0xDEB30C08, 0x9CE4B4D8, 0x90C15664, 0x6184CB7B, 0x70B632D5, 0x745C6C48, 0x4257B8D0
};
//Round constant word array
static const uint32_t rcon[11] =
{
0x00000000,
0x00000001,
0x00000002,
0x00000004,
0x00000008,
0x00000010,
0x00000020,
0x00000040,
0x00000080,
0x0000001B,
0x00000036
};
//AES128-ECB OID (2.16.840.1.101.3.4.1.1)
const uint8_t AES128_ECB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x01};
//AES128-CBC OID (2.16.840.1.101.3.4.1.2)
const uint8_t AES128_CBC_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02};
//AES128-OFB OID (2.16.840.1.101.3.4.1.3)
const uint8_t AES128_OFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x03};
//AES128-CFB OID (2.16.840.1.101.3.4.1.4)
const uint8_t AES128_CFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x04};
//AES128-GCM OID (2.16.840.1.101.3.4.1.6)
const uint8_t AES128_GCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x06};
//AES128-CCM OID (2.16.840.1.101.3.4.1.7)
const uint8_t AES128_CCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x07};
//AES192-ECB OID (2.16.840.1.101.3.4.1.21)
const uint8_t AES192_ECB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x15};
//AES192-CBC OID (2.16.840.1.101.3.4.1.22)
const uint8_t AES192_CBC_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16};
//AES192-OFB OID (2.16.840.1.101.3.4.1.23)
const uint8_t AES192_OFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x17};
//AES192-CFB OID (2.16.840.1.101.3.4.1.24)
const uint8_t AES192_CFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x18};
//AES192-GCM OID (2.16.840.1.101.3.4.1.26)
const uint8_t AES192_GCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1A};
//AES192-CCM OID (2.16.840.1.101.3.4.1.27)
const uint8_t AES192_CCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1B};
//AES256-ECB OID (2.16.840.1.101.3.4.1.41)
const uint8_t AES256_ECB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x29};
//AES256-CBC OID (2.16.840.1.101.3.4.1.42)
const uint8_t AES256_CBC_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2A};
//AES256-OFB OID (2.16.840.1.101.3.4.1.43)
const uint8_t AES256_OFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2B};
//AES256-CFB OID (2.16.840.1.101.3.4.1.44)
const uint8_t AES256_CFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2C};
//AES256-GCM OID (2.16.840.1.101.3.4.1.46)
const uint8_t AES256_GCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2E};
//AES256-CCM OID (2.16.840.1.101.3.4.1.47)
const uint8_t AES256_CCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2F};
//Common interface for encryption algorithms
const CipherAlgo aesCipherAlgo =
{
"AES",
sizeof(AesContext),
CIPHER_ALGO_TYPE_BLOCK,
AES_BLOCK_SIZE,
(CipherAlgoInit) aesInit,
NULL,
NULL,
(CipherAlgoEncryptBlock) aesEncryptBlock,
(CipherAlgoDecryptBlock) aesDecryptBlock,
(CipherAlgoDeinit) aesDeinit
};
/**
* @brief Key expansion
* @param[in] context Pointer to the AES context to initialize
* @param[in] key Pointer to the key
* @param[in] keyLen Length of the key
* @return Error code
**/
__weak_func error_t aesInit(AesContext *context, const uint8_t *key,
size_t keyLen)
{
uint_t i;
uint32_t temp;
size_t keyScheduleSize;
//Check parameters
if(context == NULL || key == NULL)
return ERROR_INVALID_PARAMETER;
//Check the length of the key
if(keyLen == 16)
{
//10 rounds are required for 128-bit key
context->nr = 10;
}
else if(keyLen == 24)
{
//12 rounds are required for 192-bit key
context->nr = 12;
}
else if(keyLen == 32)
{
//14 rounds are required for 256-bit key
context->nr = 14;
}
else
{
//Report an error
return ERROR_INVALID_KEY_LENGTH;
}
//Determine the number of 32-bit words in the key
keyLen /= 4;
//Copy the original key
for(i = 0; i < keyLen; i++)
{
context->ek[i] = LOAD32LE(key + (i * 4));
}
//The size of the key schedule depends on the number of rounds
keyScheduleSize = 4 * (context->nr + 1);
//Generate the key schedule (encryption)
for(i = keyLen; i < keyScheduleSize; i++)
{
//Save previous word
temp = context->ek[i - 1];
//Apply transformation
if((i % keyLen) == 0)
{
context->ek[i] = sbox[(temp >> 8) & 0xFF];
context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 8);
context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 16);
context->ek[i] |= (sbox[temp & 0xFF] << 24);
context->ek[i] ^= rcon[i / keyLen];
}
else if(keyLen > 6 && (i % keyLen) == 4)
{
context->ek[i] = sbox[temp & 0xFF];
context->ek[i] |= (sbox[(temp >> 8) & 0xFF] << 8);
context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 16);
context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 24);
}
else
{
context->ek[i] = temp;
}
//Update the key schedule
context->ek[i] ^= context->ek[i - keyLen];
}
//Generate the key schedule (decryption)
for(i = 0; i < keyScheduleSize; i++)
{
//Apply the InvMixColumns transformation to all round keys but the first
//and the last
if(i < 4 || i >= (keyScheduleSize - 4))
{
context->dk[i] = context->ek[i];
}
else
{
context->dk[i] = td[sbox[context->ek[i] & 0xFF]];
temp = td[sbox[(context->ek[i] >> 8) & 0xFF]];
context->dk[i] ^= ROL32(temp, 8);
temp = td[sbox[(context->ek[i] >> 16) & 0xFF]];
context->dk[i] ^= ROL32(temp, 16);
temp = td[sbox[(context->ek[i] >> 24) & 0xFF]];
context->dk[i] ^= ROL32(temp, 24);
}
}
//No error to report
return NO_ERROR;
}
/**
* @brief Encrypt a 16-byte block using AES algorithm
* @param[in] context Pointer to the AES context
* @param[in] input Plaintext block to encrypt
* @param[out] output Ciphertext block resulting from encryption
**/
__weak_func void aesEncryptBlock(AesContext *context, const uint8_t *input,
uint8_t *output)
{
uint_t i;
uint32_t s0;
uint32_t s1;
uint32_t s2;
uint32_t s3;
uint32_t t0;
uint32_t t1;
uint32_t t2;
uint32_t t3;
uint32_t temp;
//Copy the plaintext to the state array
s0 = LOAD32LE(input + 0);
s1 = LOAD32LE(input + 4);
s2 = LOAD32LE(input + 8);
s3 = LOAD32LE(input + 12);
//Initial round key addition
s0 ^= context->ek[0];
s1 ^= context->ek[1];
s2 ^= context->ek[2];
s3 ^= context->ek[3];
//The number of rounds depends on the key length
for(i = 1; i < context->nr; i++)
{
//Apply round function
t0 = te[s0 & 0xFF];
temp = te[(s1 >> 8) & 0xFF];
t0 ^= ROL32(temp, 8);
temp = te[(s2 >> 16) & 0xFF];
t0 ^= ROL32(temp, 16);
temp = te[(s3 >> 24) & 0xFF];
t0 ^= ROL32(temp, 24);
t1 = te[s1 & 0xFF];
temp = te[(s2 >> 8) & 0xFF];
t1 ^= ROL32(temp, 8);
temp = te[(s3 >> 16) & 0xFF];
t1 ^= ROL32(temp, 16);
temp = te[(s0 >> 24) & 0xFF];
t1 ^= ROL32(temp, 24);
t2 = te[s2 & 0xFF];
temp = te[(s3 >> 8) & 0xFF];
t2 ^= ROL32(temp, 8);
temp = te[(s0 >> 16) & 0xFF];
t2 ^= ROL32(temp, 16);
temp = te[(s1 >> 24) & 0xFF];
t2 ^= ROL32(temp, 24);
t3 = te[s3 & 0xFF];
temp = te[(s0 >> 8) & 0xFF];
t3 ^= ROL32(temp, 8);
temp = te[(s1 >> 16) & 0xFF];
t3 ^= ROL32(temp, 16);
temp = te[(s2 >> 24) & 0xFF];
t3 ^= ROL32(temp, 24);
//Round key addition
s0 = t0 ^ context->ek[i * 4];
s1 = t1 ^ context->ek[i * 4 + 1];
s2 = t2 ^ context->ek[i * 4 + 2];
s3 = t3 ^ context->ek[i * 4 + 3];
}
//The last round differs slightly from the first rounds
t0 = sbox[s0 & 0xFF];
t0 |= sbox[(s1 >> 8) & 0xFF] << 8;
t0 |= sbox[(s2 >> 16) & 0xFF] << 16;
t0 |= sbox[(s3 >> 24) & 0xFF] << 24;
t1 = sbox[s1 & 0xFF];
t1 |= sbox[(s2 >> 8) & 0xFF] << 8;
t1 |= sbox[(s3 >> 16) & 0xFF] << 16;
t1 |= sbox[(s0 >> 24) & 0xFF] << 24;
t2 = sbox[s2 & 0xFF];
t2 |= sbox[(s3 >> 8) & 0xFF] << 8;
t2 |= sbox[(s0 >> 16) & 0xFF] << 16;
t2 |= sbox[(s1 >> 24) & 0xFF] << 24;
t3 = sbox[s3 & 0xFF];
t3 |= sbox[(s0 >> 8) & 0xFF] << 8;
t3 |= sbox[(s1 >> 16) & 0xFF] << 16;
t3 |= sbox[(s2 >> 24) & 0xFF] << 24;
//Last round key addition
s0 = t0 ^ context->ek[context->nr * 4];
s1 = t1 ^ context->ek[context->nr * 4 + 1];
s2 = t2 ^ context->ek[context->nr * 4 + 2];
s3 = t3 ^ context->ek[context->nr * 4 + 3];
//The final state is then copied to the output
STORE32LE(s0, output + 0);
STORE32LE(s1, output + 4);
STORE32LE(s2, output + 8);
STORE32LE(s3, output + 12);
}
/**
* @brief Decrypt a 16-byte block using AES algorithm
* @param[in] context Pointer to the AES context
* @param[in] input Ciphertext block to decrypt
* @param[out] output Plaintext block resulting from decryption
**/
__weak_func void aesDecryptBlock(AesContext *context, const uint8_t *input,
uint8_t *output)
{
uint_t i;
uint32_t s0;
uint32_t s1;
uint32_t s2;
uint32_t s3;
uint32_t t0;
uint32_t t1;
uint32_t t2;
uint32_t t3;
uint32_t temp;
//Copy the ciphertext to the state array
s0 = LOAD32LE(input + 0);
s1 = LOAD32LE(input + 4);
s2 = LOAD32LE(input + 8);
s3 = LOAD32LE(input + 12);
//Initial round key addition
s0 ^= context->dk[context->nr * 4];
s1 ^= context->dk[context->nr * 4 + 1];
s2 ^= context->dk[context->nr * 4 + 2];
s3 ^= context->dk[context->nr * 4 + 3];
//The number of rounds depends on the key length
for(i = context->nr - 1; i >= 1; i--)
{
//Apply round function
t0 = td[s0 & 0xFF];
temp = td[(s3 >> 8) & 0xFF];
t0 ^= ROL32(temp, 8);
temp = td[(s2 >> 16) & 0xFF];
t0 ^= ROL32(temp, 16);
temp = td[(s1 >> 24) & 0xFF];
t0 ^= ROL32(temp, 24);
t1 = td[s1 & 0xFF];
temp = td[(s0 >> 8) & 0xFF];
t1 ^= ROL32(temp, 8);
temp = td[(s3 >> 16) & 0xFF];
t1 ^= ROL32(temp, 16);
temp = td[(s2 >> 24) & 0xFF];
t1 ^= ROL32(temp, 24);
t2 = td[s2 & 0xFF];
temp = td[(s1 >> 8) & 0xFF];
t2 ^= ROL32(temp, 8);
temp = td[(s0 >> 16) & 0xFF];
t2 ^= ROL32(temp, 16);
temp = td[(s3 >> 24) & 0xFF];
t2 ^= ROL32(temp, 24);
t3 = td[s3 & 0xFF];
temp = td[(s2 >> 8) & 0xFF];
t3 ^= ROL32(temp, 8);
temp = td[(s1 >> 16) & 0xFF];
t3 ^= ROL32(temp, 16);
temp = td[(s0 >> 24) & 0xFF];
t3 ^= ROL32(temp, 24);
//Round key addition
s0 = t0 ^ context->dk[i * 4];
s1 = t1 ^ context->dk[i * 4 + 1];
s2 = t2 ^ context->dk[i * 4 + 2];
s3 = t3 ^ context->dk[i * 4 + 3];
}
//The last round differs slightly from the first rounds
t0 = isbox[s0 & 0xFF];
t0 |= isbox[(s3 >> 8) & 0xFF] << 8;
t0 |= isbox[(s2 >> 16) & 0xFF] << 16;
t0 |= isbox[(s1 >> 24) & 0xFF] << 24;
t1 = isbox[s1 & 0xFF];
t1 |= isbox[(s0 >> 8) & 0xFF] << 8;
t1 |= isbox[(s3 >> 16) & 0xFF] << 16;
t1 |= isbox[(s2 >> 24) & 0xFF] << 24;
t2 = isbox[s2 & 0xFF];
t2 |= isbox[(s1 >> 8) & 0xFF] << 8;
t2 |= isbox[(s0 >> 16) & 0xFF] << 16;
t2 |= isbox[(s3 >> 24) & 0xFF] << 24;
t3 = isbox[s3 & 0xFF];
t3 |= isbox[(s2 >> 8) & 0xFF] << 8;
t3 |= isbox[(s1 >> 16) & 0xFF] << 16;
t3 |= isbox[(s0 >> 24) & 0xFF] << 24;
//Last round key addition
s0 = t0 ^ context->dk[0];
s1 = t1 ^ context->dk[1];
s2 = t2 ^ context->dk[2];
s3 = t3 ^ context->dk[3];
//The final state is then copied to the output
STORE32LE(s0, output + 0);
STORE32LE(s1, output + 4);
STORE32LE(s2, output + 8);
STORE32LE(s3, output + 12);
}
/**
* @brief Release AES context
* @param[in] context Pointer to the AES context
**/
__weak_func void aesDeinit(AesContext *context)
{
//Clear AES context
osMemset(context, 0, sizeof(AesContext));
}
#endif

View File

@@ -1,151 +0,0 @@
/**
* @file cpu_endian.c
* @brief Byte order conversion
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
//Dependencies
#include "cpu_endian.h"
/**
* @brief Reverse the byte order of a 16-bit word
* @param[in] value 16-bit value
* @return 16-bit value with byte order swapped
**/
uint16_t swapInt16(uint16_t value)
{
return SWAPINT16(value);
}
/**
* @brief Reverse the byte order of a 32-bit word
* @param[in] value 32-bit value
* @return 32-bit value with byte order swapped
**/
uint32_t swapInt32(uint32_t value)
{
return SWAPINT32(value);
}
/**
* @brief Reverse the byte order of a 64-bit word
* @param[in] value 64-bit value
* @return 64-bit value with byte order swapped
**/
uint64_t swapInt64(uint64_t value)
{
return SWAPINT64(value);
}
/**
* @brief Reverse bit order in a 4-bit word
* @param[in] value 4-bit value
* @return 4-bit value with bit order reversed
**/
uint8_t reverseInt4(uint8_t value)
{
value = ((value & 0x0C) >> 2) | ((value & 0x03) << 2);
value = ((value & 0x0A) >> 1) | ((value & 0x05) << 1);
return value;
}
/**
* @brief Reverse bit order in a byte
* @param[in] value 8-bit value
* @return 8-bit value with bit order reversed
**/
uint8_t reverseInt8(uint8_t value)
{
value = ((value & 0xF0) >> 4) | ((value & 0x0F) << 4);
value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
return value;
}
/**
* @brief Reverse bit order in a 16-bit word
* @param[in] value 16-bit value
* @return 16-bit value with bit order reversed
**/
uint16_t reverseInt16(uint16_t value)
{
value = ((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8);
value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
return value;
}
/**
* @brief Reverse bit order in a 32-bit word
* @param[in] value 32-bit value
* @return 32-bit value with bit order reversed
**/
uint32_t reverseInt32(uint32_t value)
{
value = ((value & 0xFFFF0000UL) >> 16) | ((value & 0x0000FFFFUL) << 16);
value = ((value & 0xFF00FF00UL) >> 8) | ((value & 0x00FF00FFUL) << 8);
value = ((value & 0xF0F0F0F0UL) >> 4) | ((value & 0x0F0F0F0FUL) << 4);
value = ((value & 0xCCCCCCCCUL) >> 2) | ((value & 0x33333333UL) << 2);
value = ((value & 0xAAAAAAAAUL) >> 1) | ((value & 0x55555555UL) << 1);
return value;
}
/**
* @brief Reverse bit order in a 64-bit word
* @param[in] value 64-bit value
* @return 64-bit value with bit order reversed
**/
uint64_t reverseInt64(uint64_t value)
{
value = ((value & 0xFFFFFFFF00000000ULL) >> 32) | ((value & 0x00000000FFFFFFFFULL) << 32);
value = ((value & 0xFFFF0000FFFF0000ULL) >> 16) | ((value & 0x0000FFFF0000FFFFULL) << 16);
value = ((value & 0xFF00FF00FF00FF00ULL) >> 8) | ((value & 0x00FF00FF00FF00FFULL) << 8);
value = ((value & 0xF0F0F0F0F0F0F0F0ULL) >> 4) | ((value & 0x0F0F0F0F0F0F0F0FULL) << 4);
value = ((value & 0xCCCCCCCCCCCCCCCCULL) >> 2) | ((value & 0x3333333333333333ULL) << 2);
value = ((value & 0xAAAAAAAAAAAAAAAAULL) >> 1) | ((value & 0x5555555555555555ULL) << 1);
return value;
}

116
deps/cyclone/ecb.c vendored
View File

@@ -1,116 +0,0 @@
/**
* @file ecb.c
* @brief Electronic Codebook (ECB) mode
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @section Description
*
* The Electronic Codebook (ECB) mode is a confidentiality mode that features,
* for a given key, the assignment of a fixed ciphertext block to each
* plaintext block, analogous to the assignment of code words in a codebook.
* Refer to SP 800-38A for more details
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
//Switch to the appropriate trace level
#define TRACE_LEVEL CRYPTO_TRACE_LEVEL
//Dependencies
#include "core/crypto.h"
#include "cipher_modes/ecb.h"
//Check crypto library configuration
#if (ECB_SUPPORT == ENABLED)
/**
* @brief ECB encryption
* @param[in] cipher Cipher algorithm
* @param[in] context Cipher algorithm context
* @param[in] p Plaintext to be encrypted
* @param[out] c Ciphertext resulting from the encryption
* @param[in] length Total number of data bytes to be encrypted
* @return Error code
**/
__weak_func error_t ecbEncrypt(const CipherAlgo *cipher, void *context,
const uint8_t *p, uint8_t *c, size_t length)
{
//ECB mode operates in a block-by-block fashion
while(length >= cipher->blockSize)
{
//Encrypt current block
cipher->encryptBlock(context, p, c);
//Next block
p += cipher->blockSize;
c += cipher->blockSize;
length -= cipher->blockSize;
}
//The plaintext must be a multiple of the block size
if(length != 0)
return ERROR_INVALID_LENGTH;
//Successful encryption
return NO_ERROR;
}
/**
* @brief ECB decryption
* @param[in] cipher Cipher algorithm
* @param[in] context Cipher algorithm context
* @param[in] c Ciphertext to be decrypted
* @param[out] p Plaintext resulting from the decryption
* @param[in] length Total number of data bytes to be decrypted
* @return Error code
**/
__weak_func error_t ecbDecrypt(const CipherAlgo *cipher, void *context,
const uint8_t *c, uint8_t *p, size_t length)
{
//ECB mode operates in a block-by-block fashion
while(length >= cipher->blockSize)
{
//Decrypt current block
cipher->decryptBlock(context, c, p);
//Next block
c += cipher->blockSize;
p += cipher->blockSize;
length -= cipher->blockSize;
}
//The ciphertext must be a multiple of the block size
if(length != 0)
return ERROR_INVALID_LENGTH;
//Successful encryption
return NO_ERROR;
}
#endif

629
deps/cyclone/gcm.c vendored
View File

@@ -1,629 +0,0 @@
/**
* @file gcm.c
* @brief Galois/Counter Mode (GCM)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @section Description
*
* The Galois/Counter Mode (GCM) is an authenticated encryption algorithm
* designed to provide both data authenticity (integrity) and confidentiality.
* Refer to SP 800-38D for more details
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
//Switch to the appropriate trace level
#define TRACE_LEVEL CRYPTO_TRACE_LEVEL
//Dependencies
#include "core/crypto.h"
#include "aead/gcm.h"
//Check crypto library configuration
#if (GCM_SUPPORT == ENABLED)
//Reduction table
static const uint32_t r[GCM_TABLE_N] =
{
#if (GCM_TABLE_W == 4)
0x00000000, 0x1C200000, 0x38400000, 0x24600000, 0x70800000, 0x6CA00000, 0x48C00000, 0x54E00000,
0xE1000000, 0xFD200000, 0xD9400000, 0xC5600000, 0x91800000, 0x8DA00000, 0xA9C00000, 0xB5E00000
#else
0x00000000, 0x01C20000, 0x03840000, 0x02460000, 0x07080000, 0x06CA0000, 0x048C0000, 0x054E0000,
0x0E100000, 0x0FD20000, 0x0D940000, 0x0C560000, 0x09180000, 0x08DA0000, 0x0A9C0000, 0x0B5E0000,
0x1C200000, 0x1DE20000, 0x1FA40000, 0x1E660000, 0x1B280000, 0x1AEA0000, 0x18AC0000, 0x196E0000,
0x12300000, 0x13F20000, 0x11B40000, 0x10760000, 0x15380000, 0x14FA0000, 0x16BC0000, 0x177E0000,
0x38400000, 0x39820000, 0x3BC40000, 0x3A060000, 0x3F480000, 0x3E8A0000, 0x3CCC0000, 0x3D0E0000,
0x36500000, 0x37920000, 0x35D40000, 0x34160000, 0x31580000, 0x309A0000, 0x32DC0000, 0x331E0000,
0x24600000, 0x25A20000, 0x27E40000, 0x26260000, 0x23680000, 0x22AA0000, 0x20EC0000, 0x212E0000,
0x2A700000, 0x2BB20000, 0x29F40000, 0x28360000, 0x2D780000, 0x2CBA0000, 0x2EFC0000, 0x2F3E0000,
0x70800000, 0x71420000, 0x73040000, 0x72C60000, 0x77880000, 0x764A0000, 0x740C0000, 0x75CE0000,
0x7E900000, 0x7F520000, 0x7D140000, 0x7CD60000, 0x79980000, 0x785A0000, 0x7A1C0000, 0x7BDE0000,
0x6CA00000, 0x6D620000, 0x6F240000, 0x6EE60000, 0x6BA80000, 0x6A6A0000, 0x682C0000, 0x69EE0000,
0x62B00000, 0x63720000, 0x61340000, 0x60F60000, 0x65B80000, 0x647A0000, 0x663C0000, 0x67FE0000,
0x48C00000, 0x49020000, 0x4B440000, 0x4A860000, 0x4FC80000, 0x4E0A0000, 0x4C4C0000, 0x4D8E0000,
0x46D00000, 0x47120000, 0x45540000, 0x44960000, 0x41D80000, 0x401A0000, 0x425C0000, 0x439E0000,
0x54E00000, 0x55220000, 0x57640000, 0x56A60000, 0x53E80000, 0x522A0000, 0x506C0000, 0x51AE0000,
0x5AF00000, 0x5B320000, 0x59740000, 0x58B60000, 0x5DF80000, 0x5C3A0000, 0x5E7C0000, 0x5FBE0000,
0xE1000000, 0xE0C20000, 0xE2840000, 0xE3460000, 0xE6080000, 0xE7CA0000, 0xE58C0000, 0xE44E0000,
0xEF100000, 0xEED20000, 0xEC940000, 0xED560000, 0xE8180000, 0xE9DA0000, 0xEB9C0000, 0xEA5E0000,
0xFD200000, 0xFCE20000, 0xFEA40000, 0xFF660000, 0xFA280000, 0xFBEA0000, 0xF9AC0000, 0xF86E0000,
0xF3300000, 0xF2F20000, 0xF0B40000, 0xF1760000, 0xF4380000, 0xF5FA0000, 0xF7BC0000, 0xF67E0000,
0xD9400000, 0xD8820000, 0xDAC40000, 0xDB060000, 0xDE480000, 0xDF8A0000, 0xDDCC0000, 0xDC0E0000,
0xD7500000, 0xD6920000, 0xD4D40000, 0xD5160000, 0xD0580000, 0xD19A0000, 0xD3DC0000, 0xD21E0000,
0xC5600000, 0xC4A20000, 0xC6E40000, 0xC7260000, 0xC2680000, 0xC3AA0000, 0xC1EC0000, 0xC02E0000,
0xCB700000, 0xCAB20000, 0xC8F40000, 0xC9360000, 0xCC780000, 0xCDBA0000, 0xCFFC0000, 0xCE3E0000,
0x91800000, 0x90420000, 0x92040000, 0x93C60000, 0x96880000, 0x974A0000, 0x950C0000, 0x94CE0000,
0x9F900000, 0x9E520000, 0x9C140000, 0x9DD60000, 0x98980000, 0x995A0000, 0x9B1C0000, 0x9ADE0000,
0x8DA00000, 0x8C620000, 0x8E240000, 0x8FE60000, 0x8AA80000, 0x8B6A0000, 0x892C0000, 0x88EE0000,
0x83B00000, 0x82720000, 0x80340000, 0x81F60000, 0x84B80000, 0x857A0000, 0x873C0000, 0x86FE0000,
0xA9C00000, 0xA8020000, 0xAA440000, 0xAB860000, 0xAEC80000, 0xAF0A0000, 0xAD4C0000, 0xAC8E0000,
0xA7D00000, 0xA6120000, 0xA4540000, 0xA5960000, 0xA0D80000, 0xA11A0000, 0xA35C0000, 0xA29E0000,
0xB5E00000, 0xB4220000, 0xB6640000, 0xB7A60000, 0xB2E80000, 0xB32A0000, 0xB16C0000, 0xB0AE0000,
0xBBF00000, 0xBA320000, 0xB8740000, 0xB9B60000, 0xBCF80000, 0xBD3A0000, 0xBF7C0000, 0xBEBE0000
#endif
};
/**
* @brief Initialize GCM context
* @param[in] context Pointer to the GCM context
* @param[in] cipherAlgo Cipher algorithm
* @param[in] cipherContext Pointer to the cipher algorithm context
* @return Error code
**/
__weak_func error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo,
void *cipherContext)
{
uint_t i;
uint_t j;
uint32_t c;
uint32_t h[4];
//Check parameters
if(context == NULL || cipherAlgo == NULL || cipherContext == NULL)
return ERROR_INVALID_PARAMETER;
//GCM supports only symmetric block ciphers whose block size is 128 bits
if(cipherAlgo->type != CIPHER_ALGO_TYPE_BLOCK || cipherAlgo->blockSize != 16)
return ERROR_INVALID_PARAMETER;
//Save cipher algorithm context
context->cipherAlgo = cipherAlgo;
context->cipherContext = cipherContext;
//Let H = 0
h[0] = 0;
h[1] = 0;
h[2] = 0;
h[3] = 0;
//Generate the hash subkey H
context->cipherAlgo->encryptBlock(context->cipherContext, (uint8_t *) h,
(uint8_t *) h);
//Pre-compute M(0) = H * 0
j = GCM_REVERSE_BITS(0);
context->m[j][0] = 0;
context->m[j][1] = 0;
context->m[j][2] = 0;
context->m[j][3] = 0;
//Pre-compute M(1) = H * 1
j = GCM_REVERSE_BITS(1);
context->m[j][0] = betoh32(h[3]);
context->m[j][1] = betoh32(h[2]);
context->m[j][2] = betoh32(h[1]);
context->m[j][3] = betoh32(h[0]);
//Pre-compute all multiples of H (Shoup's method)
for(i = 2; i < GCM_TABLE_N; i++)
{
//Odd value?
if((i & 1) != 0)
{
//Compute M(i) = M(i - 1) + H
j = GCM_REVERSE_BITS(i - 1);
h[0] = context->m[j][0];
h[1] = context->m[j][1];
h[2] = context->m[j][2];
h[3] = context->m[j][3];
//An addition in GF(2^128) is identical to a bitwise exclusive-OR
//operation
j = GCM_REVERSE_BITS(1);
h[0] ^= context->m[j][0];
h[1] ^= context->m[j][1];
h[2] ^= context->m[j][2];
h[3] ^= context->m[j][3];
}
else
{
//Compute M(i) = M(i / 2) * x
j = GCM_REVERSE_BITS(i / 2);
h[0] = context->m[j][0];
h[1] = context->m[j][1];
h[2] = context->m[j][2];
h[3] = context->m[j][3];
//The multiplication of a polynomial by x in GF(2^128) corresponds
//to a shift of indices
c = h[0] & 0x01;
h[0] = (h[0] >> 1) | (h[1] << 31);
h[1] = (h[1] >> 1) | (h[2] << 31);
h[2] = (h[2] >> 1) | (h[3] << 31);
h[3] >>= 1;
//If the highest term of the result is equal to one, then perform
//reduction
h[3] ^= r[GCM_REVERSE_BITS(1)] & ~(c - 1);
}
//Save M(i)
j = GCM_REVERSE_BITS(i);
context->m[j][0] = h[0];
context->m[j][1] = h[1];
context->m[j][2] = h[2];
context->m[j][3] = h[3];
}
//Successful initialization
return NO_ERROR;
}
/**
* @brief Authenticated encryption using GCM
* @param[in] context Pointer to the GCM context
* @param[in] iv Initialization vector
* @param[in] ivLen Length of the initialization vector
* @param[in] a Additional authenticated data
* @param[in] aLen Length of the additional data
* @param[in] p Plaintext to be encrypted
* @param[out] c Ciphertext resulting from the encryption
* @param[in] length Total number of data bytes to be encrypted
* @param[out] t Authentication tag
* @param[in] tLen Length of the authentication tag
* @return Error code
**/
__weak_func error_t gcmEncrypt(GcmContext *context, const uint8_t *iv,
size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p,
uint8_t *c, size_t length, uint8_t *t, size_t tLen)
{
size_t k;
size_t n;
uint8_t b[16];
uint8_t j[16];
uint8_t s[16];
//Make sure the GCM context is valid
if(context == NULL)
return ERROR_INVALID_PARAMETER;
//The length of the IV shall meet SP 800-38D requirements
if(ivLen < 1)
return ERROR_INVALID_LENGTH;
//Check the length of the authentication tag
if(tLen < 4 || tLen > 16)
return ERROR_INVALID_LENGTH;
//Check whether the length of the IV is 96 bits
if(ivLen == 12)
{
//When the length of the IV is 96 bits, the padding string is appended
//to the IV to form the pre-counter block
osMemcpy(j, iv, 12);
STORE32BE(1, j + 12);
}
else
{
//Initialize GHASH calculation
osMemset(j, 0, 16);
//Length of the IV
n = ivLen;
//Process the initialization vector
while(n > 0)
{
//The IV is processed in a block-by-block fashion
k = MIN(n, 16);
//Apply GHASH function
gcmXorBlock(j, j, iv, k);
gcmMul(context, j);
//Next block
iv += k;
n -= k;
}
//The string is appended with 64 additional 0 bits, followed by the
//64-bit representation of the length of the IV
osMemset(b, 0, 8);
STORE64BE(ivLen * 8, b + 8);
//The GHASH function is applied to the resulting string to form the
//pre-counter block
gcmXorBlock(j, j, b, 16);
gcmMul(context, j);
}
//Compute MSB(CIPH(J(0)))
context->cipherAlgo->encryptBlock(context->cipherContext, j, b);
osMemcpy(t, b, tLen);
//Initialize GHASH calculation
osMemset(s, 0, 16);
//Length of the AAD
n = aLen;
//Process AAD
while(n > 0)
{
//Additional data are processed in a block-by-block fashion
k = MIN(n, 16);
//Apply GHASH function
gcmXorBlock(s, s, a, k);
gcmMul(context, s);
//Next block
a += k;
n -= k;
}
//Length of the plaintext
n = length;
//Process plaintext
while(n > 0)
{
//The encryption operates in a block-by-block fashion
k = MIN(n, 16);
//Increment counter
gcmIncCounter(j);
//Encrypt plaintext
context->cipherAlgo->encryptBlock(context->cipherContext, j, b);
gcmXorBlock(c, p, b, k);
//Apply GHASH function
gcmXorBlock(s, s, c, k);
gcmMul(context, s);
//Next block
p += k;
c += k;
n -= k;
}
//Append the 64-bit representation of the length of the AAD and the
//ciphertext
STORE64BE(aLen * 8, b);
STORE64BE(length * 8, b + 8);
//The GHASH function is applied to the result to produce a single output
//block S
gcmXorBlock(s, s, b, 16);
gcmMul(context, s);
//Let T = MSB(GCTR(J(0), S)
gcmXorBlock(t, t, s, tLen);
//Successful encryption
return NO_ERROR;
}
/**
* @brief Authenticated decryption using GCM
* @param[in] context Pointer to the GCM context
* @param[in] iv Initialization vector
* @param[in] ivLen Length of the initialization vector
* @param[in] a Additional authenticated data
* @param[in] aLen Length of the additional data
* @param[in] c Ciphertext to be decrypted
* @param[out] p Plaintext resulting from the decryption
* @param[in] length Total number of data bytes to be decrypted
* @param[in] t Authentication tag
* @param[in] tLen Length of the authentication tag
* @return Error code
**/
__weak_func error_t gcmDecrypt(GcmContext *context, const uint8_t *iv,
size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c,
uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
{
uint8_t mask;
size_t k;
size_t n;
uint8_t b[16];
uint8_t j[16];
uint8_t r[16];
uint8_t s[16];
//Make sure the GCM context is valid
if(context == NULL)
return ERROR_INVALID_PARAMETER;
//The length of the IV shall meet SP 800-38D requirements
if(ivLen < 1)
return ERROR_INVALID_LENGTH;
//Check the length of the authentication tag
if(tLen < 4 || tLen > 16)
return ERROR_INVALID_LENGTH;
//Check whether the length of the IV is 96 bits
if(ivLen == 12)
{
//When the length of the IV is 96 bits, the padding string is appended
//to the IV to form the pre-counter block
osMemcpy(j, iv, 12);
STORE32BE(1, j + 12);
}
else
{
//Initialize GHASH calculation
osMemset(j, 0, 16);
//Length of the IV
n = ivLen;
//Process the initialization vector
while(n > 0)
{
//The IV is processed in a block-by-block fashion
k = MIN(n, 16);
//Apply GHASH function
gcmXorBlock(j, j, iv, k);
gcmMul(context, j);
//Next block
iv += k;
n -= k;
}
//The string is appended with 64 additional 0 bits, followed by the
//64-bit representation of the length of the IV
osMemset(b, 0, 8);
STORE64BE(ivLen * 8, b + 8);
//The GHASH function is applied to the resulting string to form the
//pre-counter block
gcmXorBlock(j, j, b, 16);
gcmMul(context, j);
}
//Compute MSB(CIPH(J(0)))
context->cipherAlgo->encryptBlock(context->cipherContext, j, b);
osMemcpy(r, b, tLen);
//Initialize GHASH calculation
osMemset(s, 0, 16);
//Length of the AAD
n = aLen;
//Process AAD
while(n > 0)
{
//Additional data are processed in a block-by-block fashion
k = MIN(n, 16);
//Apply GHASH function
gcmXorBlock(s, s, a, k);
gcmMul(context, s);
//Next block
a += k;
n -= k;
}
//Length of the ciphertext
n = length;
//Process ciphertext
while(n > 0)
{
//The decryption operates in a block-by-block fashion
k = MIN(n, 16);
//Apply GHASH function
gcmXorBlock(s, s, c, k);
gcmMul(context, s);
//Increment counter
gcmIncCounter(j);
//Decrypt ciphertext
context->cipherAlgo->encryptBlock(context->cipherContext, j, b);
gcmXorBlock(p, c, b, k);
//Next block
c += k;
p += k;
n -= k;
}
//Append the 64-bit representation of the length of the AAD and the
//ciphertext
STORE64BE(aLen * 8, b);
STORE64BE(length * 8, b + 8);
//The GHASH function is applied to the result to produce a single output
//block S
gcmXorBlock(s, s, b, 16);
gcmMul(context, s);
//Let R = MSB(GCTR(J(0), S))
gcmXorBlock(r, r, s, tLen);
//The calculated tag is bitwise compared to the received tag. The message
//is authenticated if and only if the tags match
for(mask = 0, n = 0; n < tLen; n++)
{
mask |= r[n] ^ t[n];
}
//Return status code
return (mask == 0) ? NO_ERROR : ERROR_FAILURE;
}
/**
* @brief Multiplication operation in GF(2^128)
* @param[in] context Pointer to the GCM context
* @param[in, out] x 16-byte block to be multiplied by H
**/
__weak_func void gcmMul(GcmContext *context, uint8_t *x)
{
int_t i;
uint8_t b;
uint8_t c;
uint32_t z[4];
//Let Z = 0
z[0] = 0;
z[1] = 0;
z[2] = 0;
z[3] = 0;
//Fast table-driven implementation (Shoup's method)
for(i = 15; i >= 0; i--)
{
#if (GCM_TABLE_W == 4)
//Get the lower nibble
b = x[i] & 0x0F;
//Multiply 4 bits at a time
c = z[0] & 0x0F;
z[0] = (z[0] >> 4) | (z[1] << 28);
z[1] = (z[1] >> 4) | (z[2] << 28);
z[2] = (z[2] >> 4) | (z[3] << 28);
z[3] >>= 4;
z[0] ^= context->m[b][0];
z[1] ^= context->m[b][1];
z[2] ^= context->m[b][2];
z[3] ^= context->m[b][3];
//Perform reduction
z[3] ^= r[c];
//Get the upper nibble
b = (x[i] >> 4) & 0x0F;
//Multiply 4 bits at a time
c = z[0] & 0x0F;
z[0] = (z[0] >> 4) | (z[1] << 28);
z[1] = (z[1] >> 4) | (z[2] << 28);
z[2] = (z[2] >> 4) | (z[3] << 28);
z[3] >>= 4;
z[0] ^= context->m[b][0];
z[1] ^= context->m[b][1];
z[2] ^= context->m[b][2];
z[3] ^= context->m[b][3];
//Perform reduction
z[3] ^= r[c];
#else
//Get current byte
b = x[i];
//Multiply 8 bits at a time
c = z[0] & 0xFF;
z[0] = (z[0] >> 8) | (z[1] << 24);
z[1] = (z[1] >> 8) | (z[2] << 24);
z[2] = (z[2] >> 8) | (z[3] << 24);
z[3] >>= 8;
z[0] ^= context->m[b][0];
z[1] ^= context->m[b][1];
z[2] ^= context->m[b][2];
z[3] ^= context->m[b][3];
//Perform reduction
z[3] ^= r[c];
#endif
}
//Save the result
STORE32BE(z[3], x);
STORE32BE(z[2], x + 4);
STORE32BE(z[1], x + 8);
STORE32BE(z[0], x + 12);
}
/**
* @brief XOR operation
* @param[out] x Block resulting from the XOR operation
* @param[in] a First block
* @param[in] b Second block
* @param[in] n Size of the block
**/
void gcmXorBlock(uint8_t *x, const uint8_t *a, const uint8_t *b, size_t n)
{
size_t i;
//Perform XOR operation
for(i = 0; i < n; i++)
{
x[i] = a[i] ^ b[i];
}
}
/**
* @brief Increment counter block
* @param[in,out] ctr Pointer to the counter block
**/
void gcmIncCounter(uint8_t *ctr)
{
uint16_t temp;
//The function increments the right-most 32 bits of the block. The remaining
//left-most 96 bits remain unchanged
temp = ctr[15] + 1;
ctr[15] = temp & 0xFF;
temp = (temp >> 8) + ctr[14];
ctr[14] = temp & 0xFF;
temp = (temp >> 8) + ctr[13];
ctr[13] = temp & 0xFF;
temp = (temp >> 8) + ctr[12];
ctr[12] = temp & 0xFF;
}
#endif

226
deps/cyclone/hkdf.c vendored
View File

@@ -1,226 +0,0 @@
/**
* @file hkdf.c
* @brief HKDF (HMAC-based Key Derivation Function)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @section Description
*
* HKDF is a simple HMAC-based key derivation function which can be used as a
* building block in various protocols and applications. Refer to RFC 5869 for
* more details
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
//Switch to the appropriate trace level
#define TRACE_LEVEL CRYPTO_TRACE_LEVEL
//Dependencies
#include "core/crypto.h"
#include "kdf/hkdf.h"
#include "mac/hmac.h"
//Check crypto library configuration
#if (HKDF_SUPPORT == ENABLED)
/**
* @brief HKDF key derivation function
* @param[in] hash Underlying hash function
* @param[in] ikm input keying material
* @param[in] ikmLen Length in the input keying material
* @param[in] salt Optional salt value (a non-secret random value)
* @param[in] saltLen Length of the salt
* @param[in] info Optional application specific information
* @param[in] infoLen Length of the application specific information
* @param[out] okm output keying material
* @param[in] okmLen Length of the output keying material
* @return Error code
**/
error_t hkdf(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen,
const uint8_t *salt, size_t saltLen, const uint8_t *info, size_t infoLen,
uint8_t *okm, size_t okmLen)
{
error_t error;
uint8_t prk[MAX_HASH_DIGEST_SIZE];
//Perform HKDF extract step
error = hkdfExtract(hash, ikm, ikmLen, salt, saltLen, prk);
//Check status code
if(!error)
{
//Perform HKDF expand step
error = hkdfExpand(hash, prk, hash->digestSize, info, infoLen,
okm, okmLen);
}
//Return status code
return error;
}
/**
* @brief HKDF extract step
* @param[in] hash Underlying hash function
* @param[in] ikm input keying material
* @param[in] ikmLen Length in the input keying material
* @param[in] salt Optional salt value (a non-secret random value)
* @param[in] saltLen Length of the salt
* @param[out] prk Pseudorandom key
* @return Error code
**/
error_t hkdfExtract(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen,
const uint8_t *salt, size_t saltLen, uint8_t *prk)
{
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
HmacContext *hmacContext;
#else
HmacContext hmacContext[1];
#endif
//Check parameters
if(hash == NULL || ikm == NULL || prk == NULL)
return ERROR_INVALID_PARAMETER;
//The salt parameter is optional
if(salt == NULL && saltLen != 0)
return ERROR_INVALID_PARAMETER;
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
//Allocate a memory buffer to hold the HMAC context
hmacContext = cryptoAllocMem(sizeof(HmacContext));
//Failed to allocate memory?
if(hmacContext == NULL)
return ERROR_OUT_OF_MEMORY;
#endif
//The salt parameter is optional
if(salt == NULL)
{
//If the salt is not provided, it is set to a string of HashLen zeros
osMemset(hmacContext->digest, 0, hash->digestSize);
salt = hmacContext->digest;
saltLen = hash->digestSize;
}
//Compute PRK = HMAC-Hash(salt, IKM)
hmacInit(hmacContext, hash, salt, saltLen);
hmacUpdate(hmacContext, ikm, ikmLen);
hmacFinal(hmacContext, prk);
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
//Free previously allocated memory
cryptoFreeMem(hmacContext);
#endif
//Successful processing
return NO_ERROR;
}
/**
* @brief HKDF expand step
* @param[in] hash Underlying hash function
* @param[in] prk Pseudorandom key
* @param[in] prkLen Length of the pseudorandom key
* @param[in] info Optional application specific information
* @param[in] infoLen Length of the application specific information
* @param[out] okm output keying material
* @param[in] okmLen Length of the output keying material
* @return Error code
**/
error_t hkdfExpand(const HashAlgo *hash, const uint8_t *prk, size_t prkLen,
const uint8_t *info, size_t infoLen, uint8_t *okm, size_t okmLen)
{
uint8_t i;
size_t tLen;
uint8_t t[MAX_HASH_DIGEST_SIZE];
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
HmacContext *hmacContext;
#else
HmacContext hmacContext[1];
#endif
//Check parameters
if(hash == NULL || prk == NULL || okm == NULL)
return ERROR_INVALID_PARAMETER;
//The application specific information parameter is optional
if(info == NULL && infoLen != 0)
return ERROR_INVALID_PARAMETER;
//PRK must be at least HashLen octets
if(prkLen < hash->digestSize)
return ERROR_INVALID_LENGTH;
//Check the length of the output keying material
if(okmLen > (255 * hash->digestSize))
return ERROR_INVALID_LENGTH;
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
//Allocate a memory buffer to hold the HMAC context
hmacContext = cryptoAllocMem(sizeof(HmacContext));
//Failed to allocate memory?
if(hmacContext == NULL)
return ERROR_OUT_OF_MEMORY;
#endif
//T(0) is an empty string (zero length)
tLen = 0;
//Iterate as many times as required
for(i = 1; okmLen > 0; i++)
{
//Compute T(i) = HMAC-Hash(PRK, T(i-1) | info | i)
hmacInit(hmacContext, hash, prk, prkLen);
hmacUpdate(hmacContext, t, tLen);
hmacUpdate(hmacContext, info, infoLen);
hmacUpdate(hmacContext, &i, sizeof(i));
hmacFinal(hmacContext, t);
//Number of octets in the current block
tLen = MIN(okmLen, hash->digestSize);
//Save the resulting block
osMemcpy(okm, t, tLen);
//Point to the next block
okm += tLen;
okmLen -= tLen;
}
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
//Free previously allocated memory
cryptoFreeMem(hmacContext);
#endif
//Successful processing
return NO_ERROR;
}
#endif

303
deps/cyclone/hmac.c vendored
View File

@@ -1,303 +0,0 @@
/**
* @file hmac.c
* @brief HMAC (Keyed-Hashing for Message Authentication)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @section Description
*
* HMAC is a mechanism for message authentication using cryptographic hash
* functions. HMAC can be used with any iterative cryptographic hash
* function (MD5, SHA-1 or SHA-256) in combination with a secret shared
* key. Refer to RFC 2104 for more details
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
//Switch to the appropriate trace level
#define TRACE_LEVEL CRYPTO_TRACE_LEVEL
//Dependencies
#include "core/crypto.h"
#include "mac/hmac.h"
//Check crypto library configuration
#if (HMAC_SUPPORT == ENABLED)
//HMAC with MD5 OID (1.3.6.1.5.5.8.1.1)
const uint8_t HMAC_WITH_MD5_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x01};
//HMAC with Tiger OID (1.3.6.1.5.5.8.1.3)
const uint8_t HMAC_WITH_TIGER_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x03};
//HMAC with RIPEMD-160 OID (1.3.6.1.5.5.8.1.4)
const uint8_t HMAC_WITH_RIPEMD160_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x04};
//HMAC with SHA-1 OID (1.2.840.113549.2.7)
const uint8_t HMAC_WITH_SHA1_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x07};
//HMAC with SHA-224 OID (1.2.840.113549.2.8)
const uint8_t HMAC_WITH_SHA224_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x08};
//HMAC with SHA-256 OID (1.2.840.113549.2.9)
const uint8_t HMAC_WITH_SHA256_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x09};
//HMAC with SHA-384 OID (1.2.840.113549.2.10)
const uint8_t HMAC_WITH_SHA384_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0A};
//HMAC with SHA-512 OID (1.2.840.113549.2.11)
const uint8_t HMAC_WITH_SHA512_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0B};
//HMAC with SHA-512/224 OID (1.2.840.113549.2.12)
const uint8_t HMAC_WITH_SHA512_224_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0C};
//HMAC with SHA-512/256 OID (1.2.840.113549.2.13)
const uint8_t HMAC_WITH_SHA512_256_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0D};
//HMAC with SHA-3-224 OID (2.16.840.1.101.3.4.2.13)
const uint8_t HMAC_WITH_SHA3_224_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0D};
//HMAC with SHA-3-256 OID (2.16.840.1.101.3.4.2.14)
const uint8_t HMAC_WITH_SHA3_256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0E};
//HMAC with SHA-3-384 OID (2.16.840.1.101.3.4.2.15)
const uint8_t HMAC_WITH_SHA3_384_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0F};
//HMAC with SHA-3-512 OID (2.16.840.1.101.3.4.2.16)
const uint8_t HMAC_WITH_SHA3_512_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x10};
//HMAC with SM3 OID (1.2.156.10197.1.401.3.1)
const uint8_t HMAC_WITH_SM3_OID[10] = {0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x91, 0x03, 0x01};
/**
* @brief Compute HMAC using the specified hash function
* @param[in] hash Hash algorithm used to compute HMAC
* @param[in] key Key to use in the hash algorithm
* @param[in] keyLen Length of the key
* @param[in] data The input data for which to compute the hash code
* @param[in] dataLen Length of the input data
* @param[out] digest The computed HMAC value
* @return Error code
**/
__weak_func error_t hmacCompute(const HashAlgo *hash, const void *key, size_t keyLen,
const void *data, size_t dataLen, uint8_t *digest)
{
error_t error;
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
HmacContext *context;
#else
HmacContext context[1];
#endif
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
//Allocate a memory buffer to hold the HMAC context
context = cryptoAllocMem(sizeof(HmacContext));
//Failed to allocate memory?
if(context == NULL)
return ERROR_OUT_OF_MEMORY;
#endif
//Initialize the HMAC context
error = hmacInit(context, hash, key, keyLen);
//Check status code
if(!error)
{
//Digest the message
hmacUpdate(context, data, dataLen);
//Finalize the HMAC computation
hmacFinal(context, digest);
}
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
//Free previously allocated memory
cryptoFreeMem(context);
#endif
//Return status code
return error;
}
/**
* @brief Initialize HMAC calculation
* @param[in] context Pointer to the HMAC context to initialize
* @param[in] hash Hash algorithm used to compute HMAC
* @param[in] key Key to use in the hash algorithm
* @param[in] keyLen Length of the key
* @return Error code
**/
__weak_func error_t hmacInit(HmacContext *context, const HashAlgo *hash,
const void *key, size_t keyLen)
{
uint_t i;
//Check parameters
if(context == NULL || hash == NULL)
return ERROR_INVALID_PARAMETER;
//Make sure the supplied key is valid
if(key == NULL && keyLen != 0)
return ERROR_INVALID_PARAMETER;
//Hash algorithm used to compute HMAC
context->hash = hash;
//The key is longer than the block size?
if(keyLen > hash->blockSize)
{
//Initialize the hash function context
hash->init(&context->hashContext);
//Digest the original key
hash->update(&context->hashContext, key, keyLen);
//Finalize the message digest computation
hash->final(&context->hashContext, context->key);
//Key is padded to the right with extra zeros
osMemset(context->key + hash->digestSize, 0,
hash->blockSize - hash->digestSize);
}
else
{
//Copy the key
osMemcpy(context->key, key, keyLen);
//Key is padded to the right with extra zeros
osMemset(context->key + keyLen, 0, hash->blockSize - keyLen);
}
//XOR the resulting key with ipad
for(i = 0; i < hash->blockSize; i++)
{
context->key[i] ^= HMAC_IPAD;
}
//Initialize context for the first pass
hash->init(&context->hashContext);
//Start with the inner pad
hash->update(&context->hashContext, context->key, hash->blockSize);
//Successful initialization
return NO_ERROR;
}
/**
* @brief Update the HMAC context with a portion of the message being hashed
* @param[in] context Pointer to the HMAC context
* @param[in] data Pointer to the buffer being hashed
* @param[in] length Length of the buffer
**/
__weak_func void hmacUpdate(HmacContext *context, const void *data, size_t length)
{
const HashAlgo *hash;
//Hash algorithm used to compute HMAC
hash = context->hash;
//Digest the message (first pass)
hash->update(&context->hashContext, data, length);
}
/**
* @brief Finish the HMAC calculation
* @param[in] context Pointer to the HMAC context
* @param[out] digest Calculated HMAC value (optional parameter)
**/
__weak_func void hmacFinal(HmacContext *context, uint8_t *digest)
{
uint_t i;
const HashAlgo *hash;
//Hash algorithm used to compute HMAC
hash = context->hash;
//Finish the first pass
hash->final(&context->hashContext, context->digest);
//XOR the original key with opad
for(i = 0; i < hash->blockSize; i++)
{
context->key[i] ^= HMAC_IPAD ^ HMAC_OPAD;
}
//Initialize context for the second pass
hash->init(&context->hashContext);
//Start with outer pad
hash->update(&context->hashContext, context->key, hash->blockSize);
//Then digest the result of the first hash
hash->update(&context->hashContext, context->digest, hash->digestSize);
//Finish the second pass
hash->final(&context->hashContext, context->digest);
//Copy the resulting HMAC value
if(digest != NULL)
{
osMemcpy(digest, context->digest, hash->digestSize);
}
}
/**
* @brief Release HMAC context
* @param[in] context Pointer to the HMAC context
**/
void hmacDeinit(HmacContext *context)
{
//Make sure the HMAC context is valid
if(context != NULL)
{
//Clear HMAC context
osMemset(context, 0, sizeof(HmacContext));
}
}
/**
* @brief Finish the HMAC calculation (no padding added)
* @param[in] context Pointer to the HMAC context
* @param[out] digest Calculated HMAC value (optional parameter)
**/
void hmacFinalRaw(HmacContext *context, uint8_t *digest)
{
uint_t i;
const HashAlgo *hash;
//Hash algorithm used to compute HMAC
hash = context->hash;
//XOR the original key with opad
for(i = 0; i < hash->blockSize; i++)
{
context->key[i] ^= HMAC_IPAD ^ HMAC_OPAD;
}
//Initialize context for the second pass
hash->init(&context->hashContext);
//Start with outer pad
hash->update(&context->hashContext, context->key, hash->blockSize);
//Then digest the result of the first hash
hash->update(&context->hashContext, context->digest, hash->digestSize);
//Finish the second pass
hash->final(&context->hashContext, context->digest);
//Copy the resulting HMAC value
if(digest != NULL)
{
osMemcpy(digest, context->digest, hash->digestSize);
}
}
#endif

View File

@@ -1,92 +0,0 @@
/**
* @file gcm.h
* @brief Galois/Counter Mode (GCM)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _GCM_H
#define _GCM_H
//Dependencies
#include "core/crypto.h"
//Precalculated table width, in bits
#ifndef GCM_TABLE_W
#define GCM_TABLE_W 4
#elif (GCM_TABLE_W != 4 && GCM_TABLE_W != 8)
#error GCM_TABLE_W parameter is not valid
#endif
//4-bit or 8-bit precalculated table?
#if (GCM_TABLE_W == 4)
#define GCM_TABLE_N 16
#define GCM_REVERSE_BITS(n) reverseInt4(n)
#else
#define GCM_TABLE_N 256
#define GCM_REVERSE_BITS(n) reverseInt8(n)
#endif
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief GCM context
**/
typedef struct
{
const CipherAlgo *cipherAlgo; ///<Cipher algorithm
void *cipherContext; ///<Cipher algorithm context
uint32_t m[GCM_TABLE_N][4]; ///<Precalculated table
} GcmContext;
//GCM related functions
error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo,
void *cipherContext);
error_t gcmEncrypt(GcmContext *context, const uint8_t *iv,
size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p,
uint8_t *c, size_t length, uint8_t *t, size_t tLen);
error_t gcmDecrypt(GcmContext *context, const uint8_t *iv,
size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c,
uint8_t *p, size_t length, const uint8_t *t, size_t tLen);
void gcmMul(GcmContext *context, uint8_t *x);
void gcmXorBlock(uint8_t *x, const uint8_t *a, const uint8_t *b, size_t n);
void gcmIncCounter(uint8_t *ctr);
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,103 +0,0 @@
/**
* @file aes.h
* @brief AES (Advanced Encryption Standard)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _AES_H
#define _AES_H
//Dependencies
#include "core/crypto.h"
//Application specific context
#ifndef AES_PRIVATE_CONTEXT
#define AES_PRIVATE_CONTEXT
#endif
//AES block size
#define AES_BLOCK_SIZE 16
//Common interface for encryption algorithms
#define AES_CIPHER_ALGO (&aesCipherAlgo)
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief AES algorithm context
**/
typedef struct
{
uint_t nr;
uint32_t ek[60];
uint32_t dk[60];
AES_PRIVATE_CONTEXT
} AesContext;
//AES related constants
extern const uint8_t AES128_ECB_OID[9];
extern const uint8_t AES128_CBC_OID[9];
extern const uint8_t AES128_OFB_OID[9];
extern const uint8_t AES128_CFB_OID[9];
extern const uint8_t AES128_GCM_OID[9];
extern const uint8_t AES128_CCM_OID[9];
extern const uint8_t AES192_ECB_OID[9];
extern const uint8_t AES192_CBC_OID[9];
extern const uint8_t AES192_OFB_OID[9];
extern const uint8_t AES192_CFB_OID[9];
extern const uint8_t AES192_GCM_OID[9];
extern const uint8_t AES192_CCM_OID[9];
extern const uint8_t AES256_ECB_OID[9];
extern const uint8_t AES256_CBC_OID[9];
extern const uint8_t AES256_OFB_OID[9];
extern const uint8_t AES256_CFB_OID[9];
extern const uint8_t AES256_GCM_OID[9];
extern const uint8_t AES256_CCM_OID[9];
extern const CipherAlgo aesCipherAlgo;
//AES related functions
error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen);
void aesEncryptBlock(AesContext *context, const uint8_t *input,
uint8_t *output);
void aesDecryptBlock(AesContext *context, const uint8_t *input,
uint8_t *output);
void aesDeinit(AesContext *context);
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,54 +0,0 @@
/**
* @file ecb.h
* @brief Electronic Codebook (ECB) mode
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _ECB_H
#define _ECB_H
//Dependencies
#include "core/crypto.h"
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
//ECB encryption and decryption routines
error_t ecbEncrypt(const CipherAlgo *cipher, void *context,
const uint8_t *p, uint8_t *c, size_t length);
error_t ecbDecrypt(const CipherAlgo *cipher, void *context,
const uint8_t *c, uint8_t *p, size_t length);
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,286 +0,0 @@
/**
* @file compiler_port.h
* @brief Compiler specific definitions
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _COMPILER_PORT_H
#define _COMPILER_PORT_H
//Dependencies
#include "types.h"
//ARM compiler V6?
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include <stdarg.h>
#endif
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
//Types
typedef char char_t;
typedef signed int int_t;
typedef unsigned int uint_t;
#if !defined(R_TYPEDEFS_H) && !defined(USE_CHIBIOS_2)
typedef int bool_t;
#endif
//ARM compiler?
#if defined(__CC_ARM)
#undef PRIu8
#undef PRIu16
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIuSIZE "u"
#define PRIXSIZE "X"
#define PRIuTIME "lu"
//Microchip XC32 compiler?
#elif defined(__XC32)
#if defined(__C32_LEGACY_LIBC__)
#define PRIuSIZE "lu"
#define PRIXSIZE "lX"
#define PRIuTIME "lu"
#else
#define PRIuSIZE "u"
#define PRIXSIZE "X"
#define PRIuTIME "u"
#endif
//NXP MCUXpresso compiler?
#elif defined(__MCUXPRESSO)
#undef PRIu64
#define PRIu64 "llu"
#define PRIuSIZE "u"
#define PRIXSIZE "X"
#define PRIuTIME "lu"
//NXP CodeWarrior compiler?
#elif defined(__CWCC__)
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIX32 "X"
#define PRIuSIZE "u"
#define PRIXSIZE "X"
#define PRIuTIME "u"
//Espressif ESP-IDF compiler?
#elif defined(IDF_VER)
#undef PRIu8
#undef PRIu16
#undef PRIx8
#undef PRIx16
#undef PRIX8
#undef PRIX16
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIuSIZE "u"
#define PRIXSIZE "X"
#define PRIuTIME "lu"
//Linux/FreeBSD GCC compiler
#elif defined(__linux__) || defined(__FreeBSD__)
#define PRIuSIZE "zu"
#define PRIXSIZE "zX"
#define PRIuTIME "lu"
//Win32 compiler?
#elif defined(_WIN32)
#define PRIuSIZE "Iu"
#define PRIXSIZE "IX"
#define PRIuTIME "lu"
//GCC compiler (with newlib-nano runtime library)?
#elif defined(__GNUC__) && defined(_NANO_FORMATTED_IO) && (_NANO_FORMATTED_IO != 0)
#undef PRIu8
#undef PRIu16
#undef PRIx8
#undef PRIx16
#undef PRIX8
#undef PRIX16
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIuSIZE "u"
#define PRIXSIZE "X"
#define PRIuTIME "u"
//GCC compiler (with newlib-standard runtime library)?
#else
#define PRIuSIZE "u"
#define PRIXSIZE "X"
#define PRIuTIME "lu"
#endif
//ARM compiler V6?
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
int vsnprintf(char *dest, size_t size, const char *format, va_list ap);
char *strtok_r(char *s, const char *delim, char **last);
//GCC compiler (for PowerPC architecture)?
#elif defined(__GNUC__) && defined(__PPC_EABI__)
typedef uint32_t time_t;
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t n);
char *strtok_r(char *s, const char *delim, char **last);
//GCC compiler?
#elif defined(__GNUC__)
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t n);
#if !(_SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE)
char *strtok_r(char *s, const char *delim, char **last);
#endif
//Tasking compiler?
#elif defined(__TASKING__)
char *strtok_r(char *s, const char *delim, char **last);
//Microchip XC32 compiler?
#elif defined(__XC32)
#define sprintf _sprintf
int sprintf(char *str, const char *format, ...);
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t n);
char *strtok_r(char *s, const char *delim, char **last);
//NXP CodeWarrior compiler?
#elif defined(__CWCC__)
typedef uint32_t time_t;
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t n);
char *strtok_r(char *s, const char *delim, char **last);
//Renesas CC-RX compiler?
#elif defined(__CCRX__)
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t n);
char *strtok_r(char *s, const char *delim, char **last);
//TI ARM compiler?
#elif defined(__TI_ARM__)
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t n);
char *strtok_r(char *s, const char *delim, char **last);
#endif
//ARM compiler V6?
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#undef __packed_struct
#define __packed_struct struct __attribute__((packed))
#undef __packed_union
#define __packed_union union __attribute__((packed))
//GCC compiler?
#elif defined(__GNUC__)
#undef __packed_struct
#define __packed_struct struct __attribute__((__packed__))
#undef __packed_union
#define __packed_union union __attribute__((__packed__))
//ARM compiler?
#elif defined(__CC_ARM)
#pragma anon_unions
#undef __packed_struct
#define __packed_struct __packed struct
#undef __packed_union
#define __packed_union __packed union
//IAR compiler?
#elif defined(__IAR_SYSTEMS_ICC__)
#undef __packed_struct
#define __packed_struct __packed struct
#undef __packed_union
#define __packed_union __packed union
//Tasking compiler?
#elif defined(__TASKING__)
#undef __packed_struct
#define __packed_struct struct __packed__
#undef __packed_union
#define __packed_union union __packed__
//NXP CodeWarrior compiler?
#elif defined(__CWCC__)
#undef __packed_struct
#define __packed_struct struct
#undef __packed_union
#define __packed_union union
//Renesas CC-RX compiler?
#elif defined(__CCRX__)
#undef __packed_struct
#define __packed_struct struct
#undef __packed_union
#define __packed_union union
//TI ARM compiler?
#elif defined(__TI_ARM__)
#undef __packed_struct
#define __packed_struct struct __attribute__((__packed__))
#undef __packed_union
#define __packed_union union __attribute__((__packed__))
//Win32 compiler?
#elif defined(_WIN32)
#undef interface
#undef __packed_struct
#define __packed_struct struct
#undef __packed_union
#define __packed_union union
#endif
#ifndef __weak_func
//ARM compiler V6?
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __weak_func __attribute__((weak))
//GCC compiler?
#elif defined(__GNUC__)
#define __weak_func __attribute__((weak))
//ARM compiler?
#elif defined(__CC_ARM)
#define __weak_func __weak
//IAR compiler?
#elif defined(__IAR_SYSTEMS_ICC__)
#define __weak_func __weak
//Tasking compiler?
#elif defined(__TASKING__)
#define __weak_func __attribute__((weak))
//NXP CodeWarrior compiler?
#elif defined(__CWCC__)
#define __weak_func
//Renesas CC-RX compiler?
#elif defined(__CCRX__)
#define __weak_func
//TI ARM compiler?
#elif defined(__TI_ARM__)
#define __weak_func __attribute__((weak))
//Win32 compiler?
#elif defined(_WIN32)
#define __weak_func
#endif
#endif
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,68 +0,0 @@
/**
* @file crypto_legacy.h
* @brief Legacy definitions
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _CRYPTO_LEGACY_H
#define _CRYPTO_LEGACY_H
//Deprecated functions
#define mpiReadRaw(r, data, length) mpiImport(r, data, length, MPI_FORMAT_BIG_ENDIAN)
#define mpiWriteRaw(a, data, length) mpiExport(a, data, length, MPI_FORMAT_BIG_ENDIAN)
#ifdef CURVE25519_SUPPORT
#define X25519_SUPPORT CURVE25519_SUPPORT
#endif
#ifdef CURVE448_SUPPORT
#define X448_SUPPORT CURVE448_SUPPORT
#endif
#define ecdsaGenerateKeyPair ecGenerateKeyPair
#define ecdsaGeneratePrivateKey ecGeneratePrivateKey
#define ecdsaGeneratePublicKey ecGeneratePublicKey
#define MAX_HASH_CONTEXT_SIZE sizeof(HashContext)
#define MAX_CIPHER_CONTEXT_SIZE sizeof(CipherContext)
#ifdef SAMD51_CRYPTO_PUKCC_SUPPORT
#define SAMD51_CRYPTO_PKC_SUPPORT SAMD51_CRYPTO_PUKCC_SUPPORT
#endif
#ifdef SAME54_CRYPTO_PUKCC_SUPPORT
#define SAME54_CRYPTO_PKC_SUPPORT SAME54_CRYPTO_PUKCC_SUPPORT
#endif
#define yarrowRelease yarrowDeinit
#define X509CertificateInfo X509CertInfo
#define X509SignatureAlgoId X509SignAlgoId
#define EddsaMessageChunk DataChunk
#endif

View File

@@ -1,481 +0,0 @@
/**
* @file cpu_endian.h
* @brief Byte order conversion
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _CPU_ENDIAN_H
#define _CPU_ENDIAN_H
//Dependencies
#include "os_port.h"
#include "types.h"
//Undefine conflicting definitions
#ifdef HTONS
#undef HTONS
#endif
#ifdef HTONL
#undef HTONL
#endif
#ifdef HTONLL
#undef HTONLL
#endif
#ifdef htons
#undef htons
#endif
#ifdef htonl
#undef htonl
#endif
#ifdef htonll
#undef htonll
#endif
#ifdef NTOHS
#undef NTOHS
#endif
#ifdef NTOHL
#undef NTOHL
#endif
#ifdef NTOHLL
#undef NTOHLL
#endif
#ifdef ntohs
#undef ntohs
#endif
#ifdef ntohl
#undef ntohl
#endif
#ifdef ntohll
#undef ntohll
#endif
#ifdef HTOLE16
#undef HTOLE16
#endif
#ifdef HTOLE32
#undef HTOLE32
#endif
#ifdef HTOLE64
#undef HTOLE64
#endif
#ifdef htole16
#undef htole16
#endif
#ifdef htole32
#undef htole32
#endif
#ifdef htole64
#undef htole64
#endif
#ifdef LETOH16
#undef LETOH16
#endif
#ifdef LETOH32
#undef LETOH32
#endif
#ifdef LETOH64
#undef LETOH64
#endif
#ifdef letoh16
#undef letoh16
#endif
#ifdef letoh32
#undef letoh32
#endif
#ifdef letoh64
#undef letoh64
#endif
#ifdef HTOBE16
#undef HTOBE16
#endif
#ifdef HTOBE32
#undef HTOBE32
#endif
#ifdef HTOBE64
#undef HTOBE64
#endif
#ifdef htobe16
#undef htobe16
#endif
#ifdef htobe32
#undef htobe32
#endif
#ifdef htobe64
#undef htobe64
#endif
#ifdef BETOH16
#undef BETOH16
#endif
#ifdef BETOH32
#undef BETOH32
#endif
#ifdef BETOH64
#undef BETOH64
#endif
#ifdef betoh16
#undef betoh16
#endif
#ifdef betoh32
#undef betoh32
#endif
#ifdef betoh64
#undef betoh64
#endif
//Load unaligned 16-bit integer (little-endian encoding)
#define LOAD16LE(p) ( \
((uint16_t)(((uint8_t *)(p))[0]) << 0) | \
((uint16_t)(((uint8_t *)(p))[1]) << 8))
//Load unaligned 16-bit integer (big-endian encoding)
#define LOAD16BE(p) ( \
((uint16_t)(((uint8_t *)(p))[0]) << 8) | \
((uint16_t)(((uint8_t *)(p))[1]) << 0))
//Load unaligned 24-bit integer (little-endian encoding)
#define LOAD24LE(p) ( \
((uint32_t)(((uint8_t *)(p))[0]) << 0)| \
((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
((uint32_t)(((uint8_t *)(p))[2]) << 16))
//Load unaligned 24-bit integer (big-endian encoding)
#define LOAD24BE(p) ( \
((uint32_t)(((uint8_t *)(p))[0]) << 16) | \
((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
((uint32_t)(((uint8_t *)(p))[2]) << 0))
//Load unaligned 32-bit integer (little-endian encoding)
#define LOAD32LE(p) ( \
((uint32_t)(((uint8_t *)(p))[0]) << 0) | \
((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
((uint32_t)(((uint8_t *)(p))[2]) << 16) | \
((uint32_t)(((uint8_t *)(p))[3]) << 24))
//Load unaligned 32-bit integer (big-endian encoding)
#define LOAD32BE(p) ( \
((uint32_t)(((uint8_t *)(p))[0]) << 24) | \
((uint32_t)(((uint8_t *)(p))[1]) << 16) | \
((uint32_t)(((uint8_t *)(p))[2]) << 8) | \
((uint32_t)(((uint8_t *)(p))[3]) << 0))
//Load unaligned 48-bit integer (little-endian encoding)
#define LOAD48LE(p) ( \
((uint64_t)(((uint8_t *)(p))[0]) << 0) | \
((uint64_t)(((uint8_t *)(p))[1]) << 8) | \
((uint64_t)(((uint8_t *)(p))[2]) << 16) | \
((uint64_t)(((uint8_t *)(p))[3]) << 24) | \
((uint64_t)(((uint8_t *)(p))[4]) << 32) | \
((uint64_t)(((uint8_t *)(p))[5]) << 40)
//Load unaligned 48-bit integer (big-endian encoding)
#define LOAD48BE(p) ( \
((uint64_t)(((uint8_t *)(p))[0]) << 40) | \
((uint64_t)(((uint8_t *)(p))[1]) << 32) | \
((uint64_t)(((uint8_t *)(p))[2]) << 24) | \
((uint64_t)(((uint8_t *)(p))[3]) << 16) | \
((uint64_t)(((uint8_t *)(p))[4]) << 8) | \
((uint64_t)(((uint8_t *)(p))[5]) << 0))
//Load unaligned 64-bit integer (little-endian encoding)
#define LOAD64LE(p) ( \
((uint64_t)(((uint8_t *)(p))[0]) << 0) | \
((uint64_t)(((uint8_t *)(p))[1]) << 8) | \
((uint64_t)(((uint8_t *)(p))[2]) << 16) | \
((uint64_t)(((uint8_t *)(p))[3]) << 24) | \
((uint64_t)(((uint8_t *)(p))[4]) << 32) | \
((uint64_t)(((uint8_t *)(p))[5]) << 40) | \
((uint64_t)(((uint8_t *)(p))[6]) << 48) | \
((uint64_t)(((uint8_t *)(p))[7]) << 56))
//Load unaligned 64-bit integer (big-endian encoding)
#define LOAD64BE(p) ( \
((uint64_t)(((uint8_t *)(p))[0]) << 56) | \
((uint64_t)(((uint8_t *)(p))[1]) << 48) | \
((uint64_t)(((uint8_t *)(p))[2]) << 40) | \
((uint64_t)(((uint8_t *)(p))[3]) << 32) | \
((uint64_t)(((uint8_t *)(p))[4]) << 24) | \
((uint64_t)(((uint8_t *)(p))[5]) << 16) | \
((uint64_t)(((uint8_t *)(p))[6]) << 8) | \
((uint64_t)(((uint8_t *)(p))[7]) << 0))
//Store unaligned 16-bit integer (little-endian encoding)
#define STORE16LE(a, p) \
((uint8_t *)(p))[0] = ((uint16_t)(a) >> 0) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint16_t)(a) >> 8) & 0xFFU
//Store unaligned 16-bit integer (big-endian encoding)
#define STORE16BE(a, p) \
((uint8_t *)(p))[0] = ((uint16_t)(a) >> 8) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint16_t)(a) >> 0) & 0xFFU
//Store unaligned 24-bit integer (little-endian encoding)
#define STORE24LE(a, p) \
((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU
//Store unaligned 24-bit integer (big-endian encoding)
#define STORE24BE(a, p) \
((uint8_t *)(p))[0] = ((uint32_t)(a) >> 16) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
((uint8_t *)(p))[2] = ((uint32_t)(a) >> 0) & 0xFFU
//Store unaligned 32-bit integer (little-endian encoding)
#define STORE32LE(a, p) \
((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU, \
((uint8_t *)(p))[3] = ((uint32_t)(a) >> 24) & 0xFFU
//Store unaligned 32-bit integer (big-endian encoding)
#define STORE32BE(a, p) \
((uint8_t *)(p))[0] = ((uint32_t)(a) >> 24) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint32_t)(a) >> 16) & 0xFFU, \
((uint8_t *)(p))[2] = ((uint32_t)(a) >> 8) & 0xFFU, \
((uint8_t *)(p))[3] = ((uint32_t)(a) >> 0) & 0xFFU
//Store unaligned 48-bit integer (little-endian encoding)
#define STORE48LE(a, p) \
((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \
((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \
((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \
((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \
((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU,
//Store unaligned 48-bit integer (big-endian encoding)
#define STORE48BE(a, p) \
((uint8_t *)(p))[0] = ((uint64_t)(a) >> 40) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint64_t)(a) >> 32) & 0xFFU, \
((uint8_t *)(p))[2] = ((uint64_t)(a) >> 24) & 0xFFU, \
((uint8_t *)(p))[3] = ((uint64_t)(a) >> 16) & 0xFFU, \
((uint8_t *)(p))[4] = ((uint64_t)(a) >> 8) & 0xFFU, \
((uint8_t *)(p))[5] = ((uint64_t)(a) >> 0) & 0xFFU
//Store unaligned 64-bit integer (little-endian encoding)
#define STORE64LE(a, p) \
((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \
((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \
((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \
((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \
((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU, \
((uint8_t *)(p))[6] = ((uint64_t)(a) >> 48) & 0xFFU, \
((uint8_t *)(p))[7] = ((uint64_t)(a) >> 56) & 0xFFU
//Store unaligned 64-bit integer (big-endian encoding)
#define STORE64BE(a, p) \
((uint8_t *)(p))[0] = ((uint64_t)(a) >> 56) & 0xFFU, \
((uint8_t *)(p))[1] = ((uint64_t)(a) >> 48) & 0xFFU, \
((uint8_t *)(p))[2] = ((uint64_t)(a) >> 40) & 0xFFU, \
((uint8_t *)(p))[3] = ((uint64_t)(a) >> 32) & 0xFFU, \
((uint8_t *)(p))[4] = ((uint64_t)(a) >> 24) & 0xFFU, \
((uint8_t *)(p))[5] = ((uint64_t)(a) >> 16) & 0xFFU, \
((uint8_t *)(p))[6] = ((uint64_t)(a) >> 8) & 0xFFU, \
((uint8_t *)(p))[7] = ((uint64_t)(a) >> 0) & 0xFFU
//Swap a 16-bit integer
#define SWAPINT16(x) ( \
(((uint16_t)(x) & 0x00FFU) << 8) | \
(((uint16_t)(x) & 0xFF00U) >> 8))
//Swap a 32-bit integer
#define SWAPINT32(x) ( \
(((uint32_t)(x) & 0x000000FFUL) << 24) | \
(((uint32_t)(x) & 0x0000FF00UL) << 8) | \
(((uint32_t)(x) & 0x00FF0000UL) >> 8) | \
(((uint32_t)(x) & 0xFF000000UL) >> 24))
//Swap a 64-bit integer
#define SWAPINT64(x) ( \
(((uint64_t)(x) & 0x00000000000000FFULL) << 56) | \
(((uint64_t)(x) & 0x000000000000FF00ULL) << 40) | \
(((uint64_t)(x) & 0x0000000000FF0000ULL) << 24) | \
(((uint64_t)(x) & 0x00000000FF000000ULL) << 8) | \
(((uint64_t)(x) & 0x000000FF00000000ULL) >> 8) | \
(((uint64_t)(x) & 0x0000FF0000000000ULL) >> 24) | \
(((uint64_t)(x) & 0x00FF000000000000ULL) >> 40) | \
(((uint64_t)(x) & 0xFF00000000000000ULL) >> 56))
//Big-endian machine?
#if (__BYTE_ORDER == __BIG_ENDIAN)
//Host byte order to network byte order
#define HTONS(value) (value)
#define HTONL(value) (value)
#define HTONLL(value) (value)
#define htons(value) ((uint16_t) (value))
#define htonl(value) ((uint32_t) (value))
#define htonll(value) ((uint64_t) (value))
//Network byte order to host byte order
#define NTOHS(value) (value)
#define NTOHL(value) (value)
#define NTOHLL(value) (value)
#define ntohs(value) ((uint16_t) (value))
#define ntohl(value) ((uint32_t) (value))
#define ntohll(value) ((uint64_t) (value))
//Host byte order to little-endian byte order
#define HTOLE16(value) SWAPINT16(value)
#define HTOLE32(value) SWAPINT32(value)
#define HTOLE64(value) SWAPINT64(value)
#define htole16(value) swapInt16((uint16_t) (value))
#define htole32(value) swapInt32((uint32_t) (value))
#define htole64(value) swapInt64((uint64_t) (value))
//Little-endian byte order to host byte order
#define LETOH16(value) SWAPINT16(value)
#define LETOH32(value) SWAPINT32(value)
#define LETOH64(value) SWAPINT64(value)
#define letoh16(value) swapInt16((uint16_t) (value))
#define letoh32(value) swapInt32((uint32_t) (value))
#define letoh64(value) swapInt64((uint64_t) (value))
//Host byte order to big-endian byte order
#define HTOBE16(value) (value)
#define HTOBE32(value) (value)
#define HTOBE64(value) (value)
#define htobe16(value) ((uint16_t) (value))
#define htobe32(value) ((uint32_t) (value))
#define htobe64(value) ((uint64_t) (value))
//Big-endian byte order to host byte order
#define BETOH16(value) (value)
#define BETOH32(value) (value)
#define BETOH64(value) (value)
#define betoh16(value) ((uint16_t) (value))
#define betoh32(value) ((uint32_t) (value))
#define betoh64(value) ((uint64_t) (value))
//Little-endian machine?
#else
//Host byte order to network byte order
#define HTONS(value) SWAPINT16(value)
#define HTONL(value) SWAPINT32(value)
#define HTONLL(value) SWAPINT64(value)
#define htons(value) swapInt16((uint16_t) (value))
#define htonl(value) swapInt32((uint32_t) (value))
#define htonll(value) swapInt64((uint64_t) (value))
//Network byte order to host byte order
#define NTOHS(value) SWAPINT16(value)
#define NTOHL(value) SWAPINT32(value)
#define NTOHLL(value) SWAPINT64(value)
#define ntohs(value) swapInt16((uint16_t) (value))
#define ntohl(value) swapInt32((uint32_t) (value))
#define ntohll(value) swapInt64((uint64_t) (value))
//Host byte order to little-endian byte order
#define HTOLE16(value) (value)
#define HTOLE32(value) (value)
#define HTOLE64(value) (value)
#define htole16(value) ((uint16_t) (value))
#define htole32(value) ((uint32_t) (value))
#define htole64(value) ((uint64_t) (value))
//Little-endian byte order to host byte order
#define LETOH16(value) (value)
#define LETOH32(value) (value)
#define LETOH64(value) (value)
#define letoh16(value) ((uint16_t) (value))
#define letoh32(value) ((uint32_t) (value))
#define letoh64(value) ((uint64_t) (value))
//Host byte order to big-endian byte order
#define HTOBE16(value) SWAPINT16(value)
#define HTOBE32(value) SWAPINT32(value)
#define HTOBE64(value) SWAPINT64(value)
#define htobe16(value) swapInt16((uint16_t) (value))
#define htobe32(value) swapInt32((uint32_t) (value))
#define htobe64(value) swapInt64((uint64_t) (value))
//Big-endian byte order to host byte order
#define BETOH16(value) SWAPINT16(value)
#define BETOH32(value) SWAPINT32(value)
#define BETOH64(value) SWAPINT64(value)
#define betoh16(value) swapInt16((uint16_t) (value))
#define betoh32(value) swapInt32((uint32_t) (value))
#define betoh64(value) swapInt64((uint64_t) (value))
#endif
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
//Byte order conversion functions
uint16_t swapInt16(uint16_t value);
uint32_t swapInt32(uint32_t value);
uint64_t swapInt64(uint64_t value);
//Bit reversal functions
uint8_t reverseInt4(uint8_t value);
uint8_t reverseInt8(uint8_t value);
uint16_t reverseInt16(uint16_t value);
uint32_t reverseInt32(uint32_t value);
uint64_t reverseInt64(uint64_t value);
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,7 +0,0 @@
#include "os_port.h"
#define HKDF_SUPPORT ENABLED
#define SHA256_SUPPORT ENABLED
#define AES_SUPPORT ENABLED
#define ECB_SUPPORT ENABLED
#define GCM_SUPPORT ENABLED

View File

@@ -1,320 +0,0 @@
/**
* @file error.h
* @brief Error codes description
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _ERROR_H
#define _ERROR_H
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Error codes
**/
typedef enum cyc_error_st
{
NO_ERROR = 0, ///<Success
ERROR_FAILURE = 1, ///<Generic error code
ERROR_INVALID_PARAMETER, ///<Invalid parameter
ERROR_PARAMETER_OUT_OF_RANGE, ///<Specified parameter is out of range
ERROR_BAD_CRC,
ERROR_BAD_BLOCK,
ERROR_INVALID_RECIPIENT, ///<Invalid recipient
ERROR_INVALID_INTERFACE, ///<Invalid interface
ERROR_INVALID_ENDPOINT, ///<Invalid endpoint
ERROR_INVALID_ALT_SETTING, ///<Alternate setting does not exist
ERROR_UNSUPPORTED_REQUEST, ///<Unsupported request
ERROR_UNSUPPORTED_CONFIGURATION, ///<Unsupported configuration
ERROR_UNSUPPORTED_FEATURE, ///<Unsupported feature
ERROR_ENDPOINT_BUSY, ///<Endpoint already in use
ERROR_USB_RESET,
ERROR_ABORTED,
ERROR_OUT_OF_MEMORY = 100,
ERROR_OUT_OF_RESOURCES,
ERROR_INVALID_REQUEST,
ERROR_NOT_IMPLEMENTED,
ERROR_VERSION_NOT_SUPPORTED,
ERROR_INVALID_SYNTAX,
ERROR_AUTHENTICATION_FAILED,
ERROR_UNEXPECTED_RESPONSE,
ERROR_INVALID_RESPONSE,
ERROR_UNEXPECTED_VALUE,
ERROR_WAIT_CANCELED,
ERROR_OPEN_FAILED = 200,
ERROR_CONNECTION_FAILED,
ERROR_CONNECTION_REFUSED,
ERROR_CONNECTION_CLOSING,
ERROR_CONNECTION_RESET,
ERROR_NOT_CONNECTED,
ERROR_ALREADY_CLOSED,
ERROR_ALREADY_CONNECTED,
ERROR_INVALID_SOCKET,
ERROR_PROTOCOL_UNREACHABLE,
ERROR_PORT_UNREACHABLE,
ERROR_INVALID_FRAME,
ERROR_INVALID_HEADER,
ERROR_WRONG_CHECKSUM,
ERROR_WRONG_IDENTIFIER,
ERROR_WRONG_CLIENT_ID,
ERROR_WRONG_SERVER_ID,
ERROR_WRONG_COOKIE,
ERROR_NO_RESPONSE,
ERROR_RECEIVE_QUEUE_FULL,
ERROR_TIMEOUT,
ERROR_WOULD_BLOCK,
ERROR_INVALID_NAME,
ERROR_INVALID_OPTION,
ERROR_UNEXPECTED_STATE,
ERROR_INVALID_COMMAND,
ERROR_INVALID_PROTOCOL,
ERROR_INVALID_STATUS,
ERROR_INVALID_ADDRESS,
ERROR_INVALID_PORT,
ERROR_INVALID_MESSAGE,
ERROR_INVALID_KEY,
ERROR_INVALID_KEY_LENGTH,
ERROR_INVALID_EPOCH,
ERROR_INVALID_SEQUENCE_NUMBER,
ERROR_INVALID_CHARACTER,
ERROR_INVALID_LENGTH,
ERROR_INVALID_PADDING,
ERROR_INVALID_MAC,
ERROR_INVALID_TAG,
ERROR_INVALID_TYPE,
ERROR_INVALID_VALUE,
ERROR_INVALID_CLASS,
ERROR_INVALID_VERSION,
ERROR_INVALID_PIN_CODE,
ERROR_WRONG_LENGTH,
ERROR_WRONG_TYPE,
ERROR_WRONG_ENCODING,
ERROR_WRONG_VALUE,
ERROR_INCONSISTENT_VALUE,
ERROR_UNSUPPORTED_TYPE,
ERROR_UNSUPPORTED_ALGO,
ERROR_UNSUPPORTED_CIPHER_SUITE,
ERROR_UNSUPPORTED_CIPHER_MODE,
ERROR_UNSUPPORTED_CIPHER_ALGO,
ERROR_UNSUPPORTED_HASH_ALGO,
ERROR_UNSUPPORTED_KEY_EXCH_ALGO,
ERROR_UNSUPPORTED_SIGNATURE_ALGO,
ERROR_UNSUPPORTED_ELLIPTIC_CURVE,
ERROR_INVALID_SIGNATURE_ALGO,
ERROR_CERTIFICATE_REQUIRED,
ERROR_MESSAGE_TOO_LONG,
ERROR_OUT_OF_RANGE,
ERROR_MESSAGE_DISCARDED,
ERROR_INVALID_PACKET,
ERROR_BUFFER_EMPTY,
ERROR_BUFFER_OVERFLOW,
ERROR_BUFFER_UNDERFLOW,
ERROR_INVALID_RESOURCE,
ERROR_INVALID_PATH,
ERROR_NOT_FOUND,
ERROR_ACCESS_DENIED,
ERROR_NOT_WRITABLE,
ERROR_AUTH_REQUIRED,
ERROR_TRANSMITTER_BUSY,
ERROR_NO_RUNNING,
ERROR_INVALID_FILE = 300,
ERROR_FILE_NOT_FOUND,
ERROR_FILE_OPENING_FAILED,
ERROR_FILE_READING_FAILED,
ERROR_END_OF_FILE,
ERROR_UNEXPECTED_END_OF_FILE,
ERROR_UNKNOWN_FILE_FORMAT,
ERROR_INVALID_DIRECTORY,
ERROR_DIRECTORY_NOT_FOUND,
ERROR_FILE_SYSTEM_NOT_SUPPORTED = 400,
ERROR_UNKNOWN_FILE_SYSTEM,
ERROR_INVALID_FILE_SYSTEM,
ERROR_INVALID_BOOT_SECTOR_SIGNATURE,
ERROR_INVALID_SECTOR_SIZE,
ERROR_INVALID_CLUSTER_SIZE,
ERROR_INVALID_FILE_RECORD_SIZE,
ERROR_INVALID_INDEX_BUFFER_SIZE,
ERROR_INVALID_VOLUME_DESCRIPTOR_SIGNATURE,
ERROR_INVALID_VOLUME_DESCRIPTOR,
ERROR_INVALID_FILE_RECORD,
ERROR_INVALID_INDEX_BUFFER,
ERROR_INVALID_DATA_RUNS,
ERROR_WRONG_TAG_IDENTIFIER,
ERROR_WRONG_TAG_CHECKSUM,
ERROR_WRONG_MAGIC_NUMBER,
ERROR_WRONG_SEQUENCE_NUMBER,
ERROR_DESCRIPTOR_NOT_FOUND,
ERROR_ATTRIBUTE_NOT_FOUND,
ERROR_RESIDENT_ATTRIBUTE,
ERROR_NOT_RESIDENT_ATTRIBUTE,
ERROR_INVALID_SUPER_BLOCK,
ERROR_INVALID_SUPER_BLOCK_SIGNATURE,
ERROR_INVALID_BLOCK_SIZE,
ERROR_UNSUPPORTED_REVISION_LEVEL,
ERROR_INVALID_INODE_SIZE,
ERROR_INODE_NOT_FOUND,
ERROR_UNEXPECTED_MESSAGE = 500,
ERROR_URL_TOO_LONG,
ERROR_QUERY_STRING_TOO_LONG,
ERROR_NO_ADDRESS,
ERROR_NO_BINDING,
ERROR_NOT_ON_LINK,
ERROR_USE_MULTICAST,
ERROR_NAK_RECEIVED,
ERROR_EXCEPTION_RECEIVED,
ERROR_NO_CARRIER,
ERROR_INVALID_LEVEL,
ERROR_WRONG_STATE,
ERROR_END_OF_STREAM,
ERROR_LINK_DOWN,
ERROR_INVALID_OPTION_LENGTH,
ERROR_IN_PROGRESS,
ERROR_NO_ACK,
ERROR_INVALID_METADATA,
ERROR_NOT_CONFIGURED,
ERROR_ALREADY_CONFIGURED,
ERROR_NAME_RESOLUTION_FAILED,
ERROR_NO_ROUTE,
ERROR_WRITE_FAILED,
ERROR_READ_FAILED,
ERROR_UPLOAD_FAILED,
ERROR_READ_ONLY_ACCESS,
ERROR_INVALID_SIGNATURE,
ERROR_INVALID_TICKET,
ERROR_NO_TICKET,
ERROR_BAD_RECORD_MAC,
ERROR_RECORD_OVERFLOW,
ERROR_HANDSHAKE_FAILED,
ERROR_NO_CERTIFICATE,
ERROR_BAD_CERTIFICATE,
ERROR_UNSUPPORTED_CERTIFICATE,
ERROR_UNKNOWN_CERTIFICATE,
ERROR_CERTIFICATE_EXPIRED,
ERROR_CERTIFICATE_REVOKED,
ERROR_UNKNOWN_CA,
ERROR_DECODING_FAILED,
ERROR_DECRYPTION_FAILED,
ERROR_ILLEGAL_PARAMETER,
ERROR_MISSING_EXTENSION,
ERROR_UNSUPPORTED_EXTENSION,
ERROR_INAPPROPRIATE_FALLBACK,
ERROR_NO_APPLICATION_PROTOCOL,
ERROR_MORE_DATA_REQUIRED,
ERROR_TLS_NOT_SUPPORTED,
ERROR_PRNG_NOT_READY,
ERROR_SERVICE_CLOSING,
ERROR_INVALID_TIMESTAMP,
ERROR_NO_DNS_SERVER,
ERROR_OBJECT_NOT_FOUND,
ERROR_INSTANCE_NOT_FOUND,
ERROR_ADDRESS_NOT_FOUND,
ERROR_UNKNOWN_IDENTITY,
ERROR_UNKNOWN_ENGINE_ID,
ERROR_UNKNOWN_USER_NAME,
ERROR_UNKNOWN_CONTEXT,
ERROR_UNAVAILABLE_CONTEXT,
ERROR_UNSUPPORTED_SECURITY_LEVEL,
ERROR_NOT_IN_TIME_WINDOW,
ERROR_AUTHORIZATION_FAILED,
ERROR_INVALID_FUNCTION_CODE,
ERROR_DEVICE_BUSY,
ERROR_REQUEST_REJECTED,
ERROR_INVALID_CHANNEL,
ERROR_INVALID_GROUP,
ERROR_UNKNOWN_SERVICE,
ERROR_UNKNOWN_REQUEST,
ERROR_FLOW_CONTROL,
ERROR_INVALID_PASSWORD,
ERROR_INVALID_HANDLE,
ERROR_BAD_NONCE,
ERROR_UNEXPECTED_STATUS,
ERROR_RESPONSE_TOO_LARGE,
ERROR_INVALID_SESSION,
ERROR_TICKET_EXPIRED,
ERROR_INVALID_ENTRY,
ERROR_TABLE_FULL,
ERROR_END_OF_TABLE,
ERROR_ALREADY_RUNNING,
ERROR_UNKOWN_KEY,
ERROR_UNKNOWN_TYPE,
ERROR_UNSUPPORTED_OPTION,
ERROR_INVALID_SPI,
ERROR_RETRY,
ERROR_POLICY_FAILURE,
ERROR_INVALID_PROPOSAL,
ERROR_INVALID_SELECTOR,
ERROR_WRONG_NONCE,
ERROR_WRONG_ISSUER,
ERROR_RESPONSE_EXPIRED,
ERROR_CRL_EXPIRED,
ERROR_NO_MATCH,
ERROR_PARTIAL_MATCH
} cyc_error_t;
#ifndef error_t
#define error_t cyc_error_t
#endif
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,62 +0,0 @@
/**
* @file hash_algorithms.h
* @brief Collection of hash algorithms
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _HASH_ALGORITHMS_H
#define _HASH_ALGORITHMS_H
//Dependencies
#include "core/crypto.h"
#include "hash/sha256.h"
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_HASH_DIGEST_SIZE SHA256_DIGEST_SIZE
#define MAX_HASH_BLOCK_SIZE SHA256_BLOCK_SIZE
/**
* @brief Generic hash algorithm context
**/
typedef union
{
uint8_t digest[MAX_HASH_DIGEST_SIZE];
Sha256Context sha256Context;
} HashContext;
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,96 +0,0 @@
/**
* @file sha256.h
* @brief SHA-256 (Secure Hash Algorithm 256)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _SHA256_H
#define _SHA256_H
//Dependencies
#include "core/crypto.h"
//Application specific context
#ifndef SHA256_PRIVATE_CONTEXT
#define SHA256_PRIVATE_CONTEXT
#endif
//SHA-256 block size
#define SHA256_BLOCK_SIZE 64
//SHA-256 digest size
#define SHA256_DIGEST_SIZE 32
//Minimum length of the padding string
#define SHA256_MIN_PAD_SIZE 9
//Common interface for hash algorithms
#define SHA256_HASH_ALGO (&sha256HashAlgo)
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief SHA-256 algorithm context
**/
typedef struct
{
union
{
uint32_t h[8];
uint8_t digest[32];
};
union
{
uint32_t w[16];
uint8_t buffer[64];
};
size_t size;
uint64_t totalSize;
SHA256_PRIVATE_CONTEXT
} Sha256Context;
//SHA-256 related constants
extern const uint8_t SHA256_OID[9];
extern const HashAlgo sha256HashAlgo;
//SHA-256 related functions
error_t sha256Compute(const void *data, size_t length, uint8_t *digest);
void sha256Init(Sha256Context *context);
void sha256Update(Sha256Context *context, const void *data, size_t length);
void sha256Final(Sha256Context *context, uint8_t *digest);
void sha256FinalRaw(Sha256Context *context, uint8_t *digest);
void sha256ProcessBlock(Sha256Context *context);
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,58 +0,0 @@
/**
* @file hkdf.h
* @brief HKDF (HMAC-based Key Derivation Function)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _HKDF_H
#define _HKDF_H
//Dependencies
#include "core/crypto.h"
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
//HKDF related functions
error_t hkdf(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen,
const uint8_t *salt, size_t saltLen, const uint8_t *info, size_t infoLen,
uint8_t *okm, size_t okmLen);
error_t hkdfExtract(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen,
const uint8_t *salt, size_t saltLen, uint8_t *prk);
error_t hkdfExpand(const HashAlgo *hash, const uint8_t *prk, size_t prkLen,
const uint8_t *info, size_t infoLen, uint8_t *okm, size_t okmLen);
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,102 +0,0 @@
/**
* @file hmac.h
* @brief HMAC (Keyed-Hashing for Message Authentication)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
#ifndef _HMAC_H
#define _HMAC_H
//Dependencies
#include "core/crypto.h"
#include "hash/hash_algorithms.h"
//Application specific context
#ifndef HMAC_PRIVATE_CONTEXT
#define HMAC_PRIVATE_CONTEXT
#endif
//Inner padding (ipad)
#define HMAC_IPAD 0x36
//Outer padding (opad)
#define HMAC_OPAD 0x5C
//C++ guard
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief HMAC algorithm context
**/
typedef struct
{
const HashAlgo *hash;
HashContext hashContext;
uint8_t key[MAX_HASH_BLOCK_SIZE];
uint8_t digest[MAX_HASH_DIGEST_SIZE];
HMAC_PRIVATE_CONTEXT
} HmacContext;
//HMAC related constants
extern const uint8_t HMAC_WITH_MD5_OID[8];
extern const uint8_t HMAC_WITH_TIGER_OID[8];
extern const uint8_t HMAC_WITH_RIPEMD160_OID[8];
extern const uint8_t HMAC_WITH_SHA1_OID[8];
extern const uint8_t HMAC_WITH_SHA224_OID[8];
extern const uint8_t HMAC_WITH_SHA256_OID[8];
extern const uint8_t HMAC_WITH_SHA384_OID[8];
extern const uint8_t HMAC_WITH_SHA512_OID[8];
extern const uint8_t HMAC_WITH_SHA512_224_OID[8];
extern const uint8_t HMAC_WITH_SHA512_256_OID[8];
extern const uint8_t HMAC_WITH_SHA3_224_OID[9];
extern const uint8_t HMAC_WITH_SHA3_256_OID[9];
extern const uint8_t HMAC_WITH_SHA3_384_OID[9];
extern const uint8_t HMAC_WITH_SHA3_512_OID[9];
extern const uint8_t HMAC_WITH_SM3_OID[10];
//HMAC related functions
error_t hmacCompute(const HashAlgo *hash, const void *key, size_t keyLen,
const void *data, size_t dataLen, uint8_t *digest);
error_t hmacInit(HmacContext *context, const HashAlgo *hash,
const void *key, size_t keyLen);
void hmacUpdate(HmacContext *context, const void *data, size_t length);
void hmacFinal(HmacContext *context, uint8_t *digest);
void hmacFinalRaw(HmacContext *context, uint8_t *digest);
void hmacDeinit(HmacContext *context);
//C++ guard
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,110 +0,0 @@
/**
* @file os_port.h
* @brief RTOS abstraction layer
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
/**
* Rewrote for youtubeUnblock
*/
#ifndef _OS_PORT_H
#define _OS_PORT_H
//Dependencies
#include "types.h"
#include "compiler_port.h"
//Compilation flags used to enable/disable features
#define ENABLED 1
#define DISABLED 0
#define timeCompare(t1, t2) ((int32_t) ((t1) - (t2)))
//Miscellaneous macros
#if !defined(__AT32F403A_407_LIBRARY_VERSION) && \
!defined(__AT32F435_437_LIBRARY_VERSION)
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#endif
#ifndef LSB
#define LSB(x) ((x) & 0xFF)
#endif
#ifndef MSB
#define MSB(x) (((x) >> 8) & 0xFF)
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef arraysize
#define arraysize(a) (sizeof(a) / sizeof(a[0]))
#endif
//Memory management
#ifndef osAllocMem
#define osAllocMem malloc
#endif
#ifndef osFreeMem
#define osFreeMem free
#endif
//Fill block of memory
#ifndef osMemset
#define osMemset(p, value, length) (void) memset(p, value, length)
#endif
//Copy block of memory
#ifndef osMemcpy
#define osMemcpy(dest, src, length) (void) memcpy(dest, src, length)
#endif
//Move block of memory
#ifndef osMemmove
#define osMemmove(dest, src, length) (void) memmove(dest, src, length)
#endif
//Compare two blocks of memory
#ifndef osMemcmp
#define osMemcmp(p1, p2, length) memcmp(p1, p2, length)
#endif
//Search for the first occurrence of a given character
#ifndef osMemchr
#define osMemchr(p, c, length) memchr(p, c, length)
#endif
#endif

361
deps/cyclone/sha256.c vendored
View File

@@ -1,361 +0,0 @@
/**
* @file sha256.c
* @brief SHA-256 (Secure Hash Algorithm 256)
*
* @section License
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
*
* This file is part of CycloneCRYPTO Open.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @section Description
*
* SHA-256 is a secure hash algorithm for computing a condensed representation
* of an electronic message. Refer to FIPS 180-4 for more details
*
* @author Oryx Embedded SARL (www.oryx-embedded.com)
* @version 2.4.4
**/
//Switch to the appropriate trace level
#define TRACE_LEVEL CRYPTO_TRACE_LEVEL
//Dependencies
#include "core/crypto.h"
#include "hash/sha256.h"
//Check crypto library configuration
#if (SHA224_SUPPORT == ENABLED || SHA256_SUPPORT == ENABLED)
//Macro to access the workspace as a circular buffer
#define W(n) w[(n) & 0x0F]
//SHA-256 auxiliary functions
#define CH(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define MAJ(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
#define SIGMA1(x) (ROR32(x, 2) ^ ROR32(x, 13) ^ ROR32(x, 22))
#define SIGMA2(x) (ROR32(x, 6) ^ ROR32(x, 11) ^ ROR32(x, 25))
#define SIGMA3(x) (ROR32(x, 7) ^ ROR32(x, 18) ^ SHR32(x, 3))
#define SIGMA4(x) (ROR32(x, 17) ^ ROR32(x, 19) ^ SHR32(x, 10))
//SHA-256 padding
static const uint8_t padding[64] =
{
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//SHA-256 constants
static const uint32_t k[64] =
{
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
};
//SHA-256 object identifier (2.16.840.1.101.3.4.2.1)
const uint8_t SHA256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01};
//Common interface for hash algorithms
const HashAlgo sha256HashAlgo =
{
"SHA-256",
SHA256_OID,
sizeof(SHA256_OID),
sizeof(Sha256Context),
SHA256_BLOCK_SIZE,
SHA256_DIGEST_SIZE,
SHA256_MIN_PAD_SIZE,
TRUE,
(HashAlgoCompute) sha256Compute,
(HashAlgoInit) sha256Init,
(HashAlgoUpdate) sha256Update,
(HashAlgoFinal) sha256Final,
#if ((defined(MIMXRT1050_CRYPTO_HASH_SUPPORT) && MIMXRT1050_CRYPTO_HASH_SUPPORT == ENABLED) || \
(defined(MIMXRT1060_CRYPTO_HASH_SUPPORT) && MIMXRT1060_CRYPTO_HASH_SUPPORT == ENABLED) || \
(defined(MIMXRT1160_CRYPTO_HASH_SUPPORT) && MIMXRT1160_CRYPTO_HASH_SUPPORT == ENABLED) || \
(defined(MIMXRT1170_CRYPTO_HASH_SUPPORT) && MIMXRT1170_CRYPTO_HASH_SUPPORT == ENABLED))
NULL,
#else
(HashAlgoFinalRaw) sha256FinalRaw
#endif
};
/**
* @brief Digest a message using SHA-256
* @param[in] data Pointer to the message being hashed
* @param[in] length Length of the message
* @param[out] digest Pointer to the calculated digest
* @return Error code
**/
__weak_func error_t sha256Compute(const void *data, size_t length, uint8_t *digest)
{
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
Sha256Context *context;
#else
Sha256Context context[1];
#endif
//Check parameters
if(data == NULL && length != 0)
return ERROR_INVALID_PARAMETER;
if(digest == NULL)
return ERROR_INVALID_PARAMETER;
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
//Allocate a memory buffer to hold the SHA-256 context
context = cryptoAllocMem(sizeof(Sha256Context));
//Failed to allocate memory?
if(context == NULL)
return ERROR_OUT_OF_MEMORY;
#endif
//Initialize the SHA-256 context
sha256Init(context);
//Digest the message
sha256Update(context, data, length);
//Finalize the SHA-256 message digest
sha256Final(context, digest);
#if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
//Free previously allocated memory
cryptoFreeMem(context);
#endif
//Successful processing
return NO_ERROR;
}
/**
* @brief Initialize SHA-256 message digest context
* @param[in] context Pointer to the SHA-256 context to initialize
**/
__weak_func void sha256Init(Sha256Context *context)
{
//Set initial hash value
context->h[0] = 0x6A09E667;
context->h[1] = 0xBB67AE85;
context->h[2] = 0x3C6EF372;
context->h[3] = 0xA54FF53A;
context->h[4] = 0x510E527F;
context->h[5] = 0x9B05688C;
context->h[6] = 0x1F83D9AB;
context->h[7] = 0x5BE0CD19;
//Number of bytes in the buffer
context->size = 0;
//Total length of the message
context->totalSize = 0;
}
/**
* @brief Update the SHA-256 context with a portion of the message being hashed
* @param[in] context Pointer to the SHA-256 context
* @param[in] data Pointer to the buffer being hashed
* @param[in] length Length of the buffer
**/
__weak_func void sha256Update(Sha256Context *context, const void *data, size_t length)
{
size_t n;
//Process the incoming data
while(length > 0)
{
//The buffer can hold at most 64 bytes
n = MIN(length, 64 - context->size);
//Copy the data to the buffer
osMemcpy(context->buffer + context->size, data, n);
//Update the SHA-256 context
context->size += n;
context->totalSize += n;
//Advance the data pointer
data = (uint8_t *) data + n;
//Remaining bytes to process
length -= n;
//Process message in 16-word blocks
if(context->size == 64)
{
//Transform the 16-word block
sha256ProcessBlock(context);
//Empty the buffer
context->size = 0;
}
}
}
/**
* @brief Finish the SHA-256 message digest
* @param[in] context Pointer to the SHA-256 context
* @param[out] digest Calculated digest (optional parameter)
**/
__weak_func void sha256Final(Sha256Context *context, uint8_t *digest)
{
uint_t i;
size_t paddingSize;
uint64_t totalSize;
//Length of the original message (before padding)
totalSize = context->totalSize * 8;
//Pad the message so that its length is congruent to 56 modulo 64
if(context->size < 56)
{
paddingSize = 56 - context->size;
}
else
{
paddingSize = 64 + 56 - context->size;
}
//Append padding
sha256Update(context, padding, paddingSize);
//Append the length of the original message
context->w[14] = htobe32((uint32_t) (totalSize >> 32));
context->w[15] = htobe32((uint32_t) totalSize);
//Calculate the message digest
sha256ProcessBlock(context);
//Convert from host byte order to big-endian byte order
for(i = 0; i < 8; i++)
{
context->h[i] = htobe32(context->h[i]);
}
//Copy the resulting digest
if(digest != NULL)
{
osMemcpy(digest, context->digest, SHA256_DIGEST_SIZE);
}
}
/**
* @brief Finish the SHA-256 message digest (no padding added)
* @param[in] context Pointer to the SHA-256 context
* @param[out] digest Calculated digest
**/
__weak_func void sha256FinalRaw(Sha256Context *context, uint8_t *digest)
{
uint_t i;
//Convert from host byte order to big-endian byte order
for(i = 0; i < 8; i++)
{
context->h[i] = htobe32(context->h[i]);
}
//Copy the resulting digest
osMemcpy(digest, context->digest, SHA256_DIGEST_SIZE);
//Convert from big-endian byte order to host byte order
for(i = 0; i < 8; i++)
{
context->h[i] = betoh32(context->h[i]);
}
}
/**
* @brief Process message in 16-word blocks
* @param[in] context Pointer to the SHA-256 context
**/
__weak_func void sha256ProcessBlock(Sha256Context *context)
{
uint_t i;
uint32_t temp1;
uint32_t temp2;
//Initialize the 8 working registers
uint32_t a = context->h[0];
uint32_t b = context->h[1];
uint32_t c = context->h[2];
uint32_t d = context->h[3];
uint32_t e = context->h[4];
uint32_t f = context->h[5];
uint32_t g = context->h[6];
uint32_t h = context->h[7];
//Process message in 16-word blocks
uint32_t *w = context->w;
//Convert from big-endian byte order to host byte order
for(i = 0; i < 16; i++)
{
w[i] = betoh32(w[i]);
}
//SHA-256 hash computation (alternate method)
for(i = 0; i < 64; i++)
{
//Prepare the message schedule
if(i >= 16)
{
W(i) += SIGMA4(W(i + 14)) + W(i + 9) + SIGMA3(W(i + 1));
}
//Calculate T1 and T2
temp1 = h + SIGMA2(e) + CH(e, f, g) + k[i] + W(i);
temp2 = SIGMA1(a) + MAJ(a, b, c);
//Update working registers
h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
}
//Update the hash value
context->h[0] += a;
context->h[1] += b;
context->h[2] += c;
context->h[3] += d;
context->h[4] += e;
context->h[5] += f;
context->h[6] += g;
context->h[7] += h;
}
#endif

View File

@@ -1,20 +0,0 @@
*~
*.la
*.lo
*.o
.deps/
.libs/
Makefile
Makefile.in
/aclocal.m4
/autom4te.cache/
/build-aux/
/config.*
/configure
/libtool
/stamp-h1
/libmnl.pc
/libmnl-*.tar.bz2

502
deps/libmnl/COPYING vendored
View File

@@ -1,502 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library 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 library 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 library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -1,24 +0,0 @@
# This is _NOT_ the library release version, it's an API version.
# Extracted from Chapter 6 "Library interface versions" of the libtool docs.
#
# <snippet>
# Here are a set of rules to help you update your library version information:
#
# 1. Start with version information of `0:0:0' for each libtool library.
# 2. Update the version information only immediately before a public release
# of your software. More frequent updates are unnecessary, and only guarantee
# that the current interface number gets larger faster.
# 3. If the library source code has changed at all since the last update,
# then increment revision (`c:r:a' becomes `c:r+1:a').
# 4. If any interfaces have been added, removed, or changed since the last
# update, increment current, and set revision to 0.
# 5. If any interfaces have been added since the last public release, then
# increment age.
# 6. If any interfaces have been removed since the last public release, then
# set age to 0.
# </snippet>
#
LIBVERSION=2:0:2
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include
AM_CFLAGS = ${regular_CFLAGS} ${GCC_FVISIBILITY_HIDDEN}

View File

@@ -1,11 +0,0 @@
include $(top_srcdir)/Make_global.am
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src include examples doxygen
DIST_SUBDIRS = src include examples doxygen
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libmnl.pc
${pkgconfig_DATA}: ${top_builddir}/config.status

28
deps/libmnl/README vendored
View File

@@ -1,28 +0,0 @@
= What is libmnl? =
libmnl is a minimalistic user-space library oriented to Netlink developers.
There are a lot of common tasks in parsing, validating, constructing of
both the Netlink header and TLVs that are repetitive and easy to get wrong.
This library aims to provide simple helpers that allows you to re-use code
and to avoid re-inventing the wheel. The main features of this library are:
* Small: the shared library requires around 30KB for an x86-based computer.
* Simple: this library avoids complexity and elaborated abstractions that
tend to hide Netlink details.
* Easy to use: the library simplifies the work for Netlink-wise developers.
It provides functions to make socket handling, message building, validating,
parsing and sequence tracking, easier.
* Easy to re-use: you can use the library to build your own abstraction layer
on top of this library.
* Decoupling: the interdependency of the main bricks that compose the library
is reduced, i.e. the library provides many helpers, but the programmer is not
forced to use them.
= Example files =
You can find several example files under examples/ that you can compile by
invoking `make check'.
--
08/sep/2010
Pablo Neira Ayuso <pablo@netfilter.org>

View File

@@ -1,4 +0,0 @@
#!/bin/sh -e
autoreconf -fi
rm -Rf autom4te.cache

View File

@@ -1,70 +0,0 @@
dnl Process this file with autoconf to create configure.
AC_INIT([libmnl], [1.0.5])
AC_CONFIG_AUX_DIR([build-aux])
AC_CANONICAL_HOST
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign tar-pax no-dist-gzip dist-xz 1.6 subdir-objects])
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_PROG_CC
AM_PROG_CC_C_O
AC_EXEEXT
AC_DISABLE_STATIC
LT_INIT
CHECK_GCC_FVISIBILITY
case "$host" in
*-*-linux* | *-*-uclinux*) ;;
*) AC_MSG_ERROR([Linux only, dude!]);;
esac
regular_CPPFLAGS="-D_FILE_OFFSET_BITS=64 -D_REENTRANT"
regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
-Wmissing-prototypes -Wshadow -Wstrict-prototypes \
-Wformat=2 -pipe"
AC_SUBST([regular_CPPFLAGS])
AC_SUBST([regular_CFLAGS])
AC_CONFIG_FILES([Makefile
src/Makefile
include/Makefile
include/libmnl/Makefile
include/linux/Makefile
include/linux/can/Makefile
include/linux/netfilter/Makefile
examples/Makefile
examples/genl/Makefile
examples/kobject/Makefile
examples/netfilter/Makefile
examples/rtnl/Makefile
libmnl.pc
doxygen/doxygen.cfg
doxygen/Makefile])
AC_ARG_WITH([doxygen], [AS_HELP_STRING([--with-doxygen],
[create doxygen documentation])],
[with_doxygen="$withval"], [with_doxygen=yes])
AS_IF([test "x$with_doxygen" != xno], [
AC_CHECK_PROGS([DOXYGEN], [doxygen])
AC_CHECK_PROGS([DOT], [dot], [""])
AS_IF([test "x$DOT" != "x"],
[AC_SUBST(HAVE_DOT, YES)],
[AC_SUBST(HAVE_DOT, NO)])
])
AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])
AS_IF([test "x$DOXYGEN" = x], [
AS_IF([test "x$with_doxygen" != xno], [
dnl Only run doxygen Makefile if doxygen installed
AC_MSG_WARN([Doxygen not found - continuing without Doxygen support])
with_doxygen=no
])
])
AC_OUTPUT
echo "
libmnl configuration:
doxygen: ${with_doxygen}"

View File

@@ -1,4 +0,0 @@
doxyfile.stamp
doxygen.cfg
html/
man/

View File

@@ -1,25 +0,0 @@
if HAVE_DOXYGEN
doc_srcs = $(shell find $(top_srcdir)/src -name '*.c')
doxyfile.stamp: $(doc_srcs) Makefile.am
rm -rf html man
doxygen doxygen.cfg >/dev/null
$(SHELL) $(top_srcdir)/doxygen/finalize_manpages.sh
touch doxyfile.stamp
CLEANFILES = doxyfile.stamp
all-local: doxyfile.stamp
clean-local:
rm -rf $(top_srcdir)/doxygen/man $(top_srcdir)/doxygen/html
install-data-local:
mkdir -p $(DESTDIR)$(mandir)/man3
cp --no-dereference --preserve=links,mode,timestamps man/man3/*.3\
$(DESTDIR)$(mandir)/man3/
# make distcheck needs uninstall-local
uninstall-local:
rm -r $(DESTDIR)$(mandir) man html doxyfile.stamp
endif
EXTRA_DIST = finalize_manpages.sh

View File

@@ -1,23 +0,0 @@
# Difference with default Doxyfile 1.8.20
PROJECT_NAME = @PACKAGE@
PROJECT_NUMBER = @VERSION@
OUTPUT_DIRECTORY = .
ABBREVIATE_BRIEF =
FULL_PATH_NAMES = NO
TAB_SIZE = 8
OPTIMIZE_OUTPUT_FOR_C = YES
INPUT = @top_srcdir@
FILE_PATTERNS = */src/*.c
RECURSIVE = YES
EXCLUDE_SYMBOLS = EXPORT_SYMBOL mnl_nlmsg_batch mnl_socket
EXAMPLE_PATTERNS =
INPUT_FILTER = "sed 's/EXPORT_SYMBOL//g'"
SOURCE_BROWSER = YES
ALPHABETICAL_INDEX = NO
SEARCHENGINE = NO
GENERATE_LATEX = NO
LATEX_CMD_NAME = latex
GENERATE_MAN = YES
MAN_LINKS = YES
HAVE_DOT = @HAVE_DOT@
DOT_TRANSPARENT = YES

View File

@@ -1,40 +0,0 @@
#
# We need to use bash for its associative array facility
#
[ "$BASH" ] || exec bash $0
#
# (`bash -p` prevents import of functions from the environment).
#
set -p
declare -A renamed_page
main(){ set -e; cd man/man3; rm -f _*
count_real_pages
rename_real_pages
make_symlinks
}
count_real_pages(){ page_count=0
for i in $(ls -S)
do head -n1 $i | grep -E -q '^\.so' && break
page_count=$(($page_count + 1))
done
first_link=$(($page_count + 1))
}
rename_real_pages(){ for i in $(ls -S | head -n$page_count)
do for j in $(ls -S | tail -n+$first_link)
do grep -E -q $i$ $j && break
done
mv -f $i $j
renamed_page[$i]=$j
done
}
make_symlinks(){ for j in $(ls -S | tail -n+$first_link)
do ln -sf ${renamed_page[$(cat $j | cut -f2 -d/)]} $j
done
}
main

View File

@@ -1 +0,0 @@
SUBDIRS = genl kobject netfilter rtnl

View File

@@ -1,2 +0,0 @@
/genl-family-get
/genl-group-events

View File

@@ -1,10 +0,0 @@
include $(top_srcdir)/Make_global.am
check_PROGRAMS = genl-family-get \
genl-group-events
genl_family_get_SOURCES = genl-family-get.c
genl_family_get_LDADD = ../../src/libmnl.la
genl_group_events_SOURCES = genl-group-events.c
genl_group_events_LDADD = ../../src/libmnl.la

View File

@@ -1,241 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <libmnl/libmnl.h>
#include <linux/genetlink.h>
static int parse_mc_grps_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, CTRL_ATTR_MCAST_GRP_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTRL_ATTR_MCAST_GRP_ID:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTRL_ATTR_MCAST_GRP_NAME:
if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void parse_genl_mc_grps(struct nlattr *nested)
{
struct nlattr *pos;
mnl_attr_for_each_nested(pos, nested) {
struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1] = {};
mnl_attr_parse_nested(pos, parse_mc_grps_cb, tb);
if (tb[CTRL_ATTR_MCAST_GRP_ID]) {
printf("id-0x%x ",
mnl_attr_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID]));
}
if (tb[CTRL_ATTR_MCAST_GRP_NAME]) {
printf("name: %s ",
mnl_attr_get_str(tb[CTRL_ATTR_MCAST_GRP_NAME]));
}
printf("\n");
}
}
static int parse_family_ops_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTRL_ATTR_OP_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTRL_ATTR_OP_ID:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTRL_ATTR_OP_MAX:
break;
default:
return MNL_CB_OK;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void parse_genl_family_ops(struct nlattr *nested)
{
struct nlattr *pos;
mnl_attr_for_each_nested(pos, nested) {
struct nlattr *tb[CTRL_ATTR_OP_MAX+1] = {};
mnl_attr_parse_nested(pos, parse_family_ops_cb, tb);
if (tb[CTRL_ATTR_OP_ID]) {
printf("id-0x%x ",
mnl_attr_get_u32(tb[CTRL_ATTR_OP_ID]));
}
if (tb[CTRL_ATTR_OP_MAX]) {
printf("flags ");
}
printf("\n");
}
}
static int data_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTRL_ATTR_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTRL_ATTR_FAMILY_NAME:
if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTRL_ATTR_FAMILY_ID:
if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTRL_ATTR_VERSION:
case CTRL_ATTR_HDRSIZE:
case CTRL_ATTR_MAXATTR:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTRL_ATTR_OPS:
case CTRL_ATTR_MCAST_GROUPS:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[CTRL_ATTR_MAX+1] = {};
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
mnl_attr_parse(nlh, sizeof(*genl), data_attr_cb, tb);
if (tb[CTRL_ATTR_FAMILY_NAME]) {
printf("name=%s\t",
mnl_attr_get_str(tb[CTRL_ATTR_FAMILY_NAME]));
}
if (tb[CTRL_ATTR_FAMILY_ID]) {
printf("id=%u\t",
mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]));
}
if (tb[CTRL_ATTR_VERSION]) {
printf("version=%u\t",
mnl_attr_get_u32(tb[CTRL_ATTR_VERSION]));
}
if (tb[CTRL_ATTR_HDRSIZE]) {
printf("hdrsize=%u\t",
mnl_attr_get_u32(tb[CTRL_ATTR_HDRSIZE]));
}
if (tb[CTRL_ATTR_MAXATTR]) {
printf("maxattr=%u\t",
mnl_attr_get_u32(tb[CTRL_ATTR_MAXATTR]));
}
printf("\n");
if (tb[CTRL_ATTR_OPS]) {
printf("ops:\n");
parse_genl_family_ops(tb[CTRL_ATTR_OPS]);
}
if (tb[CTRL_ATTR_MCAST_GROUPS]) {
printf("grps:\n");
parse_genl_mc_grps(tb[CTRL_ATTR_MCAST_GROUPS]);
}
printf("\n");
return MNL_CB_OK;
}
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct genlmsghdr *genl;
int ret;
unsigned int seq, portid;
if (argc > 2) {
printf("%s [family name]\n", argv[0]);
exit(EXIT_FAILURE);
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = GENL_ID_CTRL;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));
genl->cmd = CTRL_CMD_GETFAMILY;
genl->version = 1;
mnl_attr_put_u32(nlh, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL);
if (argc >= 2)
mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, argv[1]);
else
nlh->nlmsg_flags |= NLM_F_DUMP;
nl = mnl_socket_open(NETLINK_GENERIC);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
if (ret <= 0)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,63 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <libmnl/libmnl.h>
#include <linux/genetlink.h>
static int group;
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
printf("received event type=%d from genetlink group %d\n",
nlh->nlmsg_type, group);
return MNL_CB_OK;
}
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
int ret;
if (argc != 2) {
printf("%s [group]\n", argv[0]);
exit(EXIT_FAILURE);
}
group = atoi(argv[1]);
nl = mnl_socket_open(NETLINK_GENERIC);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
if (mnl_socket_setsockopt(nl, NETLINK_ADD_MEMBERSHIP, &group,
sizeof(int)) < 0) {
perror("mnl_socket_setsockopt");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
if (ret <= 0)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1 +0,0 @@
/kobject-event

View File

@@ -1,6 +0,0 @@
include $(top_srcdir)/Make_global.am
check_PROGRAMS = kobject-event
kobject_event_SOURCES = kobject-event.c
kobject_event_LDADD = ../../src/libmnl.la

View File

@@ -1,49 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <libmnl/libmnl.h>
#include <linux/netlink.h>
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
int ret;
nl = mnl_socket_open(NETLINK_KOBJECT_UEVENT);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
/* There is one single group in kobject over netlink */
if (mnl_socket_bind(nl, (1<<0), MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
int i;
/* kobject uses a string based protocol, with no initial
* netlink header.
*/
for (i=0; i<ret; i++)
printf("%c", buf[i]);
printf("\n");
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,6 +0,0 @@
/nf-log
/nf-queue
/nfct-create-batch
/nfct-daemon
/nfct-dump
/nfct-event

View File

@@ -1,26 +0,0 @@
include $(top_srcdir)/Make_global.am
check_PROGRAMS = nf-queue \
nf-log \
nfct-dump \
nfct-event \
nfct-create-batch \
nfct-daemon
nf_queue_SOURCES = nf-queue.c
nf_queue_LDADD = ../../src/libmnl.la
nf_log_SOURCES = nf-log.c
nf_log_LDADD = ../../src/libmnl.la
nfct_dump_SOURCES = nfct-dump.c
nfct_dump_LDADD = ../../src/libmnl.la
nfct_daemon_SOURCES = nfct-daemon.c
nfct_daemon_LDADD = ../../src/libmnl.la
nfct_event_SOURCES = nfct-event.c
nfct_event_LDADD = ../../src/libmnl.la
nfct_create_batch_SOURCES = nfct-create-batch.c
nfct_create_batch_LDADD = ../../src/libmnl.la

View File

@@ -1,219 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_log.h>
static int parse_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, NFULA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case NFULA_MARK:
case NFULA_IFINDEX_INDEV:
case NFULA_IFINDEX_OUTDEV:
case NFULA_IFINDEX_PHYSINDEV:
case NFULA_IFINDEX_PHYSOUTDEV:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case NFULA_TIMESTAMP:
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
sizeof(struct nfulnl_msg_packet_timestamp)) < 0) {
perror("mnl_attr_validate2");
return MNL_CB_ERROR;
}
break;
case NFULA_HWADDR:
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
sizeof(struct nfulnl_msg_packet_hw)) < 0) {
perror("mnl_attr_validate2");
return MNL_CB_ERROR;
}
break;
case NFULA_PREFIX:
if (mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case NFULA_PAYLOAD:
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int log_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[NFULA_MAX+1] = {};
struct nfulnl_msg_packet_hdr *ph = NULL;
const char *prefix = NULL;
uint32_t mark = 0;
mnl_attr_parse(nlh, sizeof(struct nfgenmsg), parse_attr_cb, tb);
if (tb[NFULA_PACKET_HDR])
ph = mnl_attr_get_payload(tb[NFULA_PACKET_HDR]);
if (tb[NFULA_PREFIX])
prefix = mnl_attr_get_str(tb[NFULA_PREFIX]);
if (tb[NFULA_MARK])
mark = ntohl(mnl_attr_get_u32(tb[NFULA_MARK]));
printf("log received (prefix=\"%s\" hw=0x%04x hook=%u mark=%u)\n",
prefix ? prefix : "", ntohs(ph->hw_protocol), ph->hook,
mark);
return MNL_CB_OK;
}
static struct nlmsghdr *
nflog_build_cfg_pf_request(char *buf, uint8_t command)
{
struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG;
nlh->nlmsg_flags = NLM_F_REQUEST;
struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
nfg->nfgen_family = AF_INET;
nfg->version = NFNETLINK_V0;
struct nfulnl_msg_config_cmd cmd = {
.command = command,
};
mnl_attr_put(nlh, NFULA_CFG_CMD, sizeof(cmd), &cmd);
return nlh;
}
static struct nlmsghdr *
nflog_build_cfg_request(char *buf, uint8_t command, int qnum)
{
struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG;
nlh->nlmsg_flags = NLM_F_REQUEST;
struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
nfg->nfgen_family = AF_INET;
nfg->version = NFNETLINK_V0;
nfg->res_id = htons(qnum);
struct nfulnl_msg_config_cmd cmd = {
.command = command,
};
mnl_attr_put(nlh, NFULA_CFG_CMD, sizeof(cmd), &cmd);
return nlh;
}
static struct nlmsghdr *
nflog_build_cfg_params(char *buf, uint8_t mode, int range, int qnum)
{
struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG;
nlh->nlmsg_flags = NLM_F_REQUEST;
struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
nfg->nfgen_family = AF_UNSPEC;
nfg->version = NFNETLINK_V0;
nfg->res_id = htons(qnum);
struct nfulnl_msg_config_mode params = {
.copy_range = htonl(range),
.copy_mode = mode,
};
mnl_attr_put(nlh, NFULA_CFG_MODE, sizeof(params), &params);
return nlh;
}
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
int ret;
unsigned int portid, qnum;
if (argc != 2) {
printf("Usage: %s [queue_num]\n", argv[0]);
exit(EXIT_FAILURE);
}
qnum = atoi(argv[1]);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
nlh = nflog_build_cfg_pf_request(buf, NFULNL_CFG_CMD_PF_UNBIND);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
nlh = nflog_build_cfg_pf_request(buf, NFULNL_CFG_CMD_PF_BIND);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
nlh = nflog_build_cfg_request(buf, NFULNL_CFG_CMD_BIND, qnum);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
nlh = nflog_build_cfg_params(buf, NFULNL_COPY_PACKET, 0xFFFF, qnum);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
while (ret > 0) {
ret = mnl_cb_run(buf, ret, 0, portid, log_cb, NULL);
if (ret < 0){
perror("mnl_cb_run");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,243 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_queue.h>
static int parse_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, NFQA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case NFQA_MARK:
case NFQA_IFINDEX_INDEV:
case NFQA_IFINDEX_OUTDEV:
case NFQA_IFINDEX_PHYSINDEV:
case NFQA_IFINDEX_PHYSOUTDEV:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case NFQA_TIMESTAMP:
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
sizeof(struct nfqnl_msg_packet_timestamp)) < 0) {
perror("mnl_attr_validate2");
return MNL_CB_ERROR;
}
break;
case NFQA_HWADDR:
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
sizeof(struct nfqnl_msg_packet_hw)) < 0) {
perror("mnl_attr_validate2");
return MNL_CB_ERROR;
}
break;
case NFQA_PAYLOAD:
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int queue_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[NFQA_MAX+1] = {};
struct nfqnl_msg_packet_hdr *ph = NULL;
uint32_t id = 0;
mnl_attr_parse(nlh, sizeof(struct nfgenmsg), parse_attr_cb, tb);
if (tb[NFQA_PACKET_HDR]) {
ph = mnl_attr_get_payload(tb[NFQA_PACKET_HDR]);
id = ntohl(ph->packet_id);
printf("packet received (id=%u hw=0x%04x hook=%u)\n",
id, ntohs(ph->hw_protocol), ph->hook);
}
return MNL_CB_OK + id;
}
static struct nlmsghdr *
nfq_build_cfg_pf_request(char *buf, uint8_t command)
{
struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
nlh->nlmsg_flags = NLM_F_REQUEST;
struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
nfg->nfgen_family = AF_UNSPEC;
nfg->version = NFNETLINK_V0;
struct nfqnl_msg_config_cmd cmd = {
.command = command,
.pf = htons(AF_INET),
};
mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(cmd), &cmd);
return nlh;
}
static struct nlmsghdr *
nfq_build_cfg_request(char *buf, uint8_t command, int queue_num)
{
struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
nlh->nlmsg_flags = NLM_F_REQUEST;
struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
nfg->nfgen_family = AF_UNSPEC;
nfg->version = NFNETLINK_V0;
nfg->res_id = htons(queue_num);
struct nfqnl_msg_config_cmd cmd = {
.command = command,
.pf = htons(AF_INET),
};
mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(cmd), &cmd);
return nlh;
}
static struct nlmsghdr *
nfq_build_cfg_params(char *buf, uint8_t mode, int range, int queue_num)
{
struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
nlh->nlmsg_flags = NLM_F_REQUEST;
struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
nfg->nfgen_family = AF_UNSPEC;
nfg->version = NFNETLINK_V0;
nfg->res_id = htons(queue_num);
struct nfqnl_msg_config_params params = {
.copy_range = htonl(range),
.copy_mode = mode,
};
mnl_attr_put(nlh, NFQA_CFG_PARAMS, sizeof(params), &params);
return nlh;
}
static struct nlmsghdr *
nfq_build_verdict(char *buf, int id, int queue_num, int verd)
{
struct nlmsghdr *nlh;
struct nfgenmsg *nfg;
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_VERDICT;
nlh->nlmsg_flags = NLM_F_REQUEST;
nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
nfg->nfgen_family = AF_UNSPEC;
nfg->version = NFNETLINK_V0;
nfg->res_id = htons(queue_num);
struct nfqnl_msg_verdict_hdr vh = {
.verdict = htonl(verd),
.id = htonl(id),
};
mnl_attr_put(nlh, NFQA_VERDICT_HDR, sizeof(vh), &vh);
return nlh;
}
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
int ret;
unsigned int portid, queue_num;
if (argc != 2) {
printf("Usage: %s [queue_num]\n", argv[0]);
exit(EXIT_FAILURE);
}
queue_num = atoi(argv[1]);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_UNBIND);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_BIND);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
nlh = nfq_build_cfg_request(buf, NFQNL_CFG_CMD_BIND, queue_num);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
nlh = nfq_build_cfg_params(buf, NFQNL_COPY_PACKET, 0xFFFF, queue_num);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
while (ret > 0) {
uint32_t id;
ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);
if (ret < 0){
perror("mnl_cb_run");
exit(EXIT_FAILURE);
}
id = ret - MNL_CB_OK;
nlh = nfq_build_verdict(buf, id, queue_num, NF_ACCEPT);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,187 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/select.h>
#include <string.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_conntrack_tcp.h>
static void put_msg(char *buf, uint16_t i, int seq)
{
struct nlmsghdr *nlh;
struct nfgenmsg *nfh;
struct nlattr *nest1, *nest2;
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW;
nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
nlh->nlmsg_seq = seq;
nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
nfh->nfgen_family = AF_INET;
nfh->version = NFNETLINK_V0;
nfh->res_id = 0;
nest1 = mnl_attr_nest_start(nlh, CTA_TUPLE_ORIG);
nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_IP);
mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, inet_addr("1.1.1.1"));
mnl_attr_put_u32(nlh, CTA_IP_V4_DST, inet_addr("2.2.2.2"));
mnl_attr_nest_end(nlh, nest2);
nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO);
mnl_attr_put_u8(nlh, CTA_PROTO_NUM, IPPROTO_TCP);
mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(i));
mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(1025));
mnl_attr_nest_end(nlh, nest2);
mnl_attr_nest_end(nlh, nest1);
nest1 = mnl_attr_nest_start(nlh, CTA_TUPLE_REPLY);
nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_IP);
mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, inet_addr("2.2.2.2"));
mnl_attr_put_u32(nlh, CTA_IP_V4_DST, inet_addr("1.1.1.1"));
mnl_attr_nest_end(nlh, nest2);
nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO);
mnl_attr_put_u8(nlh, CTA_PROTO_NUM, IPPROTO_TCP);
mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(1025));
mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(i));
mnl_attr_nest_end(nlh, nest2);
mnl_attr_nest_end(nlh, nest1);
nest1 = mnl_attr_nest_start(nlh, CTA_PROTOINFO);
nest2 = mnl_attr_nest_start(nlh, CTA_PROTOINFO_TCP);
mnl_attr_put_u8(nlh, CTA_PROTOINFO_TCP_STATE, TCP_CONNTRACK_SYN_SENT);
mnl_attr_nest_end(nlh, nest2);
mnl_attr_nest_end(nlh, nest1);
mnl_attr_put_u32(nlh, CTA_STATUS, htonl(IPS_CONFIRMED));
mnl_attr_put_u32(nlh, CTA_TIMEOUT, htonl(1000));
}
static int cb_err(const struct nlmsghdr *nlh, void *data)
{
struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
if (err->error != 0)
printf("message with seq %u has failed: %s\n",
nlh->nlmsg_seq, strerror(-err->error));
return MNL_CB_OK;
}
static mnl_cb_t cb_ctl_array[NLMSG_MIN_TYPE] = {
[NLMSG_ERROR] = cb_err,
};
static void
send_batch(struct mnl_socket *nl, struct mnl_nlmsg_batch *b, int portid)
{
int ret, fd = mnl_socket_get_fd(nl);
size_t len = mnl_nlmsg_batch_size(b);
char rcv_buf[MNL_SOCKET_BUFFER_SIZE];
ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(b), len);
if (ret == -1) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
/* receive and digest all the acknowledgments from the kernel. */
struct timeval tv = {
.tv_sec = 0,
.tv_usec = 0
};
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
ret = select(fd+1, &readfds, NULL, NULL, &tv);
if (ret == -1) {
perror("select");
exit(EXIT_FAILURE);
}
while (ret > 0 && FD_ISSET(fd, &readfds)) {
ret = mnl_socket_recvfrom(nl, rcv_buf, sizeof(rcv_buf));
if (ret == -1) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
ret = mnl_cb_run2(rcv_buf, ret, 0, portid,
NULL, NULL, cb_ctl_array,
MNL_ARRAY_SIZE(cb_ctl_array));
if (ret == -1) {
perror("mnl_cb_run2");
exit(EXIT_FAILURE);
}
ret = select(fd+1, &readfds, NULL, NULL, &tv);
if (ret == -1) {
perror("select");
exit(EXIT_FAILURE);
}
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
}
}
int main(void)
{
struct mnl_socket *nl;
char snd_buf[MNL_SOCKET_BUFFER_SIZE*2];
struct mnl_nlmsg_batch *b;
int j;
unsigned int seq, portid;
uint16_t i;
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
/* The buffer that we use to batch messages is MNL_SOCKET_BUFFER_SIZE
* multiplied by 2 bytes long, but we limit the batch to half of it
* since the last message that does not fit the batch goes over the
* upper boundary, if you break this rule, expect memory corruptions. */
b = mnl_nlmsg_batch_start(snd_buf, MNL_SOCKET_BUFFER_SIZE);
if (b == NULL) {
perror("mnl_nlmsg_batch_start");
exit(EXIT_FAILURE);
}
seq = time(NULL);
for (i=1024, j=0; i<65535; i++, j++) {
put_msg(mnl_nlmsg_batch_current(b), i, seq+j);
/* is there room for more messages in this batch?
* if so, continue. */
if (mnl_nlmsg_batch_next(b))
continue;
send_batch(nl, b, portid);
/* this moves the last message that did not fit into the
* batch to the head of it. */
mnl_nlmsg_batch_reset(b);
}
/* check if there is any message in the batch not sent yet. */
if (!mnl_nlmsg_batch_is_empty(b))
send_batch(nl, b, portid);
mnl_nlmsg_batch_stop(b);
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,365 +0,0 @@
/* A very simple skeleton code that implements a daemon that collects
* conntrack statistics from ctnetlink.
*
* This example is placed in the public domain.
*/
#include <endian.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/select.h>
#include <libmnl/libmnl.h>
#include <linux/netlink.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
#include <sys/queue.h>
struct nstats {
LIST_ENTRY(nstats) list;
uint8_t family;
union {
struct in_addr ip;
struct in6_addr ip6;
};
uint64_t pkts, bytes;
};
static LIST_HEAD(nstats_head, nstats) nstats_head;
static int parse_counters_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_COUNTERS_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_COUNTERS_PACKETS:
case CTA_COUNTERS_BYTES:
if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void parse_counters(const struct nlattr *nest, struct nstats *ns)
{
struct nlattr *tb[CTA_COUNTERS_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_counters_cb, tb);
if (tb[CTA_COUNTERS_PACKETS])
ns->pkts += be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_PACKETS]));
if (tb[CTA_COUNTERS_BYTES])
ns->bytes += be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_BYTES]));
}
static int parse_ip_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_IP_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_IP_V4_SRC:
case CTA_IP_V4_DST:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTA_IP_V6_SRC:
case CTA_IP_V6_DST:
if (mnl_attr_validate2(attr, MNL_TYPE_BINARY,
sizeof(struct in6_addr)) < 0) {
perror("mnl_attr_validate2");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void parse_ip(const struct nlattr *nest, struct nstats *ns)
{
struct nlattr *tb[CTA_IP_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_ip_cb, tb);
if (tb[CTA_IP_V4_SRC]) {
struct in_addr *in = mnl_attr_get_payload(tb[CTA_IP_V4_SRC]);
ns->ip = *in;
ns->family = AF_INET;
}
if (tb[CTA_IP_V6_SRC]) {
struct in6_addr *in = mnl_attr_get_payload(tb[CTA_IP_V6_SRC]);
ns->ip6 = *in;
ns->family = AF_INET6;
}
}
static int parse_tuple_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_TUPLE_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_TUPLE_IP:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void parse_tuple(const struct nlattr *nest, struct nstats *ns)
{
struct nlattr *tb[CTA_TUPLE_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_tuple_cb, tb);
if (tb[CTA_TUPLE_IP])
parse_ip(tb[CTA_TUPLE_IP], ns);
}
static int data_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_TUPLE_ORIG:
case CTA_COUNTERS_ORIG:
case CTA_COUNTERS_REPLY:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[CTA_MAX+1] = {};
struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
struct nstats ns = {}, *cur, *new;
mnl_attr_parse(nlh, sizeof(*nfg), data_attr_cb, tb);
if (tb[CTA_TUPLE_ORIG])
parse_tuple(tb[CTA_TUPLE_ORIG], &ns);
if (tb[CTA_COUNTERS_ORIG])
parse_counters(tb[CTA_COUNTERS_ORIG], &ns);
if (tb[CTA_COUNTERS_REPLY])
parse_counters(tb[CTA_COUNTERS_REPLY], &ns);
/* Look up for existing statistics object ... */
LIST_FOREACH(cur, &nstats_head, list) {
if (memcmp(&ns.ip6, &cur->ip6, sizeof(struct in6_addr)) == 0) {
/* ... and sum counters */
cur->pkts += ns.pkts;
cur->bytes += ns.bytes;
return MNL_CB_OK;
}
}
/* ... if it does not exist, add new stats object */
new = calloc(1, sizeof(struct nstats));
if (!new)
return MNL_CB_OK;
new->family = ns.family;
new->ip6 = ns.ip6;
new->pkts = ns.pkts;
new->bytes = ns.bytes;
LIST_INSERT_HEAD(&nstats_head, new, list);
return MNL_CB_OK;
}
static int handle(struct mnl_socket *nl)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
int ret;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1) {
/* It only happens if NETLINK_NO_ENOBUFS is not set, it means
* we are leaking statistics.
*/
if (errno == ENOBUFS) {
fprintf(stderr, "The daemon has hit ENOBUFS, you can "
"increase the size of your receiver "
"buffer to mitigate this or enable "
"reliable delivery.\n");
} else {
perror("mnl_socket_recvfrom");
}
return -1;
}
ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
if (ret == -1) {
perror("mnl_cb_run");
return -1;
} else if (ret <= MNL_CB_STOP)
return 0;
return 0;
}
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct nfgenmsg *nfh;
struct nstats *cur;
struct timeval tv = {};
int ret, secs, on = 1, buffersize = (1 << 22);
if (argc != 2) {
printf("Usage: %s <poll-secs>\n", argv[0]);
exit(EXIT_FAILURE);
}
secs = atoi(argv[1]);
LIST_INIT(&nstats_head);
printf("Polling every %d seconds from kernel...\n", secs);
/* Set high priority for this process, less chances to overrun
* the netlink receiver buffer since the scheduler gives this process
* more chances to run.
*/
nice(-20);
/* Open netlink socket to operate with netfilter */
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
/* Subscribe to destroy events to avoid leaking counters. The same
* socket is used to periodically atomically dump and reset counters.
*/
if (mnl_socket_bind(nl, NF_NETLINK_CONNTRACK_DESTROY,
MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
/* Set netlink receiver buffer to 16 MBytes, to avoid packet drops */
setsockopt(mnl_socket_get_fd(nl), SOL_SOCKET, SO_RCVBUFFORCE,
&buffersize, sizeof(socklen_t));
/* The two tweaks below enable reliable event delivery, packets may
* be dropped if the netlink receiver buffer overruns. This happens ...
*
* a) if the kernel spams this user-space process until the receiver
* is filled.
*
* or:
*
* b) if the user-space process does not pull messages from the
* receiver buffer so often.
*/
mnl_socket_setsockopt(nl, NETLINK_BROADCAST_ERROR, &on, sizeof(int));
mnl_socket_setsockopt(nl, NETLINK_NO_ENOBUFS, &on, sizeof(int));
nlh = mnl_nlmsg_put_header(buf);
/* Counters are atomically zeroed in each dump */
nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) |
IPCTNL_MSG_CT_GET_CTRZERO;
nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
nfh->nfgen_family = AF_INET;
nfh->version = NFNETLINK_V0;
nfh->res_id = 0;
/* Filter by mark: We only want to dump entries whose mark is zero */
mnl_attr_put_u32(nlh, CTA_MARK, htonl(0));
mnl_attr_put_u32(nlh, CTA_MARK_MASK, htonl(0xffffffff));
while (1) {
int fd_max = mnl_socket_get_fd(nl);
fd_set readfds;
/* Every N seconds ... */
if (tv.tv_sec == 0 && tv.tv_usec == 0) {
/* ... request a fresh dump of the table from kernel */
ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);
if (ret == -1) {
perror("mnl_socket_sendto");
return -1;
}
tv.tv_sec = secs;
tv.tv_usec = 0;
/* print the content of the list */
LIST_FOREACH(cur, &nstats_head, list) {
char out[INET6_ADDRSTRLEN];
if (inet_ntop(cur->family, &cur->ip, out, sizeof(out)))
printf("src=%s ", out);
printf("counters %"PRIu64" %"PRIu64"\n",
cur->pkts, cur->bytes);
}
}
FD_ZERO(&readfds);
FD_SET(mnl_socket_get_fd(nl), &readfds);
ret = select(fd_max+1, &readfds, NULL, NULL, &tv);
if (ret < 0) {
if (errno == EINTR)
continue;
perror("select");
exit(EXIT_FAILURE);
}
/* Handled event and periodic atomic-dump-and-reset messages */
if (FD_ISSET(mnl_socket_get_fd(nl), &readfds)) {
if (handle(nl) < 0)
return EXIT_FAILURE;
}
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,319 +0,0 @@
/* This example is placed in the public domain. */
#include <endian.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <inttypes.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
static int parse_counters_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_COUNTERS_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_COUNTERS_PACKETS:
case CTA_COUNTERS_BYTES:
if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void print_counters(const struct nlattr *nest)
{
struct nlattr *tb[CTA_COUNTERS_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_counters_cb, tb);
if (tb[CTA_COUNTERS_PACKETS]) {
printf("packets=%"PRIu64" ",
be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_PACKETS])));
}
if (tb[CTA_COUNTERS_BYTES]) {
printf("bytes=%"PRIu64" ",
be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_BYTES])));
}
}
static int parse_ip_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_IP_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_IP_V4_SRC:
case CTA_IP_V4_DST:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTA_IP_V6_SRC:
case CTA_IP_V6_DST:
if (mnl_attr_validate2(attr, MNL_TYPE_BINARY,
sizeof(struct in6_addr)) < 0) {
perror("mnl_attr_validate2");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void print_ip(const struct nlattr *nest)
{
struct nlattr *tb[CTA_IP_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_ip_cb, tb);
if (tb[CTA_IP_V4_SRC]) {
struct in_addr *in = mnl_attr_get_payload(tb[CTA_IP_V4_SRC]);
printf("src=%s ", inet_ntoa(*in));
}
if (tb[CTA_IP_V4_DST]) {
struct in_addr *in = mnl_attr_get_payload(tb[CTA_IP_V4_DST]);
printf("dst=%s ", inet_ntoa(*in));
}
if (tb[CTA_IP_V6_SRC]) {
struct in6_addr *in = mnl_attr_get_payload(tb[CTA_IP_V6_SRC]);
char out[INET6_ADDRSTRLEN];
if (!inet_ntop(AF_INET6, in, out, sizeof(out)))
printf("src=%s ", out);
}
if (tb[CTA_IP_V6_DST]) {
struct in6_addr *in = mnl_attr_get_payload(tb[CTA_IP_V6_DST]);
char out[INET6_ADDRSTRLEN];
if (!inet_ntop(AF_INET6, in, out, sizeof(out)))
printf("dst=%s ", out);
}
}
static int parse_proto_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_PROTO_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_PROTO_NUM:
case CTA_PROTO_ICMP_TYPE:
case CTA_PROTO_ICMP_CODE:
if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTA_PROTO_SRC_PORT:
case CTA_PROTO_DST_PORT:
case CTA_PROTO_ICMP_ID:
if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void print_proto(const struct nlattr *nest)
{
struct nlattr *tb[CTA_PROTO_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_proto_cb, tb);
if (tb[CTA_PROTO_NUM]) {
printf("proto=%u ", mnl_attr_get_u8(tb[CTA_PROTO_NUM]));
}
if (tb[CTA_PROTO_SRC_PORT]) {
printf("sport=%u ",
ntohs(mnl_attr_get_u16(tb[CTA_PROTO_SRC_PORT])));
}
if (tb[CTA_PROTO_DST_PORT]) {
printf("dport=%u ",
ntohs(mnl_attr_get_u16(tb[CTA_PROTO_DST_PORT])));
}
if (tb[CTA_PROTO_ICMP_ID]) {
printf("id=%u ",
ntohs(mnl_attr_get_u16(tb[CTA_PROTO_ICMP_ID])));
}
if (tb[CTA_PROTO_ICMP_TYPE]) {
printf("type=%u ", mnl_attr_get_u8(tb[CTA_PROTO_ICMP_TYPE]));
}
if (tb[CTA_PROTO_ICMP_CODE]) {
printf("code=%u ", mnl_attr_get_u8(tb[CTA_PROTO_ICMP_CODE]));
}
}
static int parse_tuple_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_TUPLE_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_TUPLE_IP:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTA_TUPLE_PROTO:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void print_tuple(const struct nlattr *nest)
{
struct nlattr *tb[CTA_TUPLE_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_tuple_cb, tb);
if (tb[CTA_TUPLE_IP]) {
print_ip(tb[CTA_TUPLE_IP]);
}
if (tb[CTA_TUPLE_PROTO]) {
print_proto(tb[CTA_TUPLE_PROTO]);
}
}
static int data_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_TUPLE_ORIG:
case CTA_COUNTERS_ORIG:
case CTA_COUNTERS_REPLY:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTA_TIMEOUT:
case CTA_MARK:
case CTA_SECMARK:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[CTA_MAX+1] = {};
struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
mnl_attr_parse(nlh, sizeof(*nfg), data_attr_cb, tb);
if (tb[CTA_TUPLE_ORIG])
print_tuple(tb[CTA_TUPLE_ORIG]);
if (tb[CTA_MARK])
printf("mark=%u ", ntohl(mnl_attr_get_u32(tb[CTA_MARK])));
if (tb[CTA_SECMARK])
printf("secmark=%u ", ntohl(mnl_attr_get_u32(tb[CTA_SECMARK])));
if (tb[CTA_COUNTERS_ORIG]) {
printf("original ");
print_counters(tb[CTA_COUNTERS_ORIG]);
}
if (tb[CTA_COUNTERS_REPLY]) {
printf("reply ");
print_counters(tb[CTA_COUNTERS_REPLY]);
}
printf("\n");
return MNL_CB_OK;
}
int main(void)
{
char buf[MNL_SOCKET_DUMP_SIZE];
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct nfgenmsg *nfh;
uint32_t seq, portid;
int ret;
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET;
nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
nlh->nlmsg_seq = seq = time(NULL);
nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
nfh->nfgen_family = AF_INET;
nfh->version = NFNETLINK_V0;
nfh->res_id = 0;
ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);
if (ret == -1) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
while (1) {
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
if (ret == -1) {
perror("mnl_cb_run");
exit(EXIT_FAILURE);
} else if (ret <= MNL_CB_STOP)
break;
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,240 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
static int parse_ip_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_IP_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_IP_V4_SRC:
case CTA_IP_V4_DST:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void print_ip(const struct nlattr *nest)
{
struct nlattr *tb[CTA_IP_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_ip_cb, tb);
if (tb[CTA_IP_V4_SRC]) {
struct in_addr *in = mnl_attr_get_payload(tb[CTA_IP_V4_SRC]);
printf("src=%s ", inet_ntoa(*in));
}
if (tb[CTA_IP_V4_DST]) {
struct in_addr *in = mnl_attr_get_payload(tb[CTA_IP_V4_DST]);
printf("dst=%s ", inet_ntoa(*in));
}
}
static int parse_proto_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_PROTO_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_PROTO_NUM:
case CTA_PROTO_ICMP_TYPE:
case CTA_PROTO_ICMP_CODE:
if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTA_PROTO_SRC_PORT:
case CTA_PROTO_DST_PORT:
case CTA_PROTO_ICMP_ID:
if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void print_proto(const struct nlattr *nest)
{
struct nlattr *tb[CTA_PROTO_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_proto_cb, tb);
if (tb[CTA_PROTO_NUM]) {
printf("proto=%u ", mnl_attr_get_u8(tb[CTA_PROTO_NUM]));
}
if (tb[CTA_PROTO_SRC_PORT]) {
printf("sport=%u ",
ntohs(mnl_attr_get_u16(tb[CTA_PROTO_SRC_PORT])));
}
if (tb[CTA_PROTO_DST_PORT]) {
printf("dport=%u ",
ntohs(mnl_attr_get_u16(tb[CTA_PROTO_DST_PORT])));
}
if (tb[CTA_PROTO_ICMP_ID]) {
printf("id=%u ",
ntohs(mnl_attr_get_u16(tb[CTA_PROTO_ICMP_ID])));
}
if (tb[CTA_PROTO_ICMP_TYPE]) {
printf("type=%u ", mnl_attr_get_u8(tb[CTA_PROTO_ICMP_TYPE]));
}
if (tb[CTA_PROTO_ICMP_CODE]) {
printf("code=%u ", mnl_attr_get_u8(tb[CTA_PROTO_ICMP_CODE]));
}
}
static int parse_tuple_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_TUPLE_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_TUPLE_IP:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTA_TUPLE_PROTO:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static void print_tuple(const struct nlattr *nest)
{
struct nlattr *tb[CTA_TUPLE_MAX+1] = {};
mnl_attr_parse_nested(nest, parse_tuple_cb, tb);
if (tb[CTA_TUPLE_IP]) {
print_ip(tb[CTA_TUPLE_IP]);
}
if (tb[CTA_TUPLE_PROTO]) {
print_proto(tb[CTA_TUPLE_PROTO]);
}
}
static int data_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
if (mnl_attr_type_valid(attr, CTA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case CTA_TUPLE_ORIG:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case CTA_TIMEOUT:
case CTA_MARK:
case CTA_SECMARK:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[CTA_MAX+1] = {};
struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
switch(nlh->nlmsg_type & 0xFF) {
case IPCTNL_MSG_CT_NEW:
if (nlh->nlmsg_flags & (NLM_F_CREATE|NLM_F_EXCL))
printf("%9s ", "[NEW] ");
else
printf("%9s ", "[UPDATE] ");
break;
case IPCTNL_MSG_CT_DELETE:
printf("%9s ", "[DESTROY] ");
break;
}
mnl_attr_parse(nlh, sizeof(*nfg), data_attr_cb, tb);
if (tb[CTA_TUPLE_ORIG]) {
print_tuple(tb[CTA_TUPLE_ORIG]);
}
if (tb[CTA_MARK]) {
printf("mark=%u ", ntohl(mnl_attr_get_u32(tb[CTA_MARK])));
}
if (tb[CTA_SECMARK]) {
printf("secmark=%u ", ntohl(mnl_attr_get_u32(tb[CTA_SECMARK])));
}
printf("\n");
return MNL_CB_OK;
}
int main(void)
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
int ret;
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, NF_NETLINK_CONNTRACK_NEW |
NF_NETLINK_CONNTRACK_UPDATE |
NF_NETLINK_CONNTRACK_DESTROY,
MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
while (1) {
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
if (ret == -1) {
perror("mnl_cb_run");
exit(EXIT_FAILURE);
}
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,12 +0,0 @@
/rtnl-addr-add
/rtnl-addr-dump
/rtnl-link-can
/rtnl-link-dump
/rtnl-link-dump2
/rtnl-link-dump3
/rtnl-link-event
/rtnl-link-set
/rtnl-neigh-dump
/rtnl-route-event
/rtnl-route-add
/rtnl-route-dump

View File

@@ -1,48 +0,0 @@
include $(top_srcdir)/Make_global.am
check_PROGRAMS = rtnl-addr-add \
rtnl-addr-dump \
rtnl-link-can \
rtnl-link-dump rtnl-link-dump2 rtnl-link-dump3 \
rtnl-link-event \
rtnl-link-set \
rtnl-route-add \
rtnl-route-dump \
rtnl-route-event \
rtnl-neigh-dump
rtnl_addr_add_SOURCES = rtnl-addr-add.c
rtnl_addr_add_LDADD = ../../src/libmnl.la
rtnl_link_can_SOURCES = rtnl-link-can.c
rtnl_link_can_LDADD = ../../src/libmnl.la
rtnl_addr_dump_SOURCES = rtnl-addr-dump.c
rtnl_addr_dump_LDADD = ../../src/libmnl.la
rtnl_link_dump_SOURCES = rtnl-link-dump.c
rtnl_link_dump_LDADD = ../../src/libmnl.la
rtnl_link_dump2_SOURCES = rtnl-link-dump2.c
rtnl_link_dump2_LDADD = ../../src/libmnl.la
rtnl_link_dump3_SOURCES = rtnl-link-dump3.c
rtnl_link_dump3_LDADD = ../../src/libmnl.la
rtnl_route_add_SOURCES = rtnl-route-add.c
rtnl_route_add_LDADD = ../../src/libmnl.la
rtnl_link_event_SOURCES = rtnl-link-event.c
rtnl_link_event_LDADD = ../../src/libmnl.la
rtnl_link_set_SOURCES = rtnl-link-set.c
rtnl_link_set_LDADD = ../../src/libmnl.la
rtnl_route_dump_SOURCES = rtnl-route-dump.c
rtnl_route_dump_LDADD = ../../src/libmnl.la
rtnl_route_event_SOURCES = rtnl-route-event.c
rtnl_route_event_LDADD = ../../src/libmnl.la
rtnl_neigh_dump_SOURCES = rtnl-neigh-dump.c
rtnl_neigh_dump_LDADD = ../../src/libmnl.la

View File

@@ -1,119 +0,0 @@
/* This example is placed in the public domain. */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <net/if.h>
#include <libmnl/libmnl.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct ifaddrmsg *ifm;
uint32_t seq, portid;
union {
in_addr_t ip;
struct in6_addr ip6;
} addr;
int ret, family = AF_INET;
uint32_t prefix;
int iface;
if (argc <= 3) {
printf("Usage: %s iface destination cidr\n", argv[0]);
printf("Example: %s eth0 10.0.1.12 32\n", argv[0]);
printf(" %s eth0 ffff::10.0.1.12 128\n", argv[0]);
exit(EXIT_FAILURE);
}
iface = if_nametoindex(argv[1]);
if (iface == 0) {
perror("if_nametoindex");
exit(EXIT_FAILURE);
}
if (!inet_pton(AF_INET, argv[2], &addr)) {
if (!inet_pton(AF_INET6, argv[2], &addr)) {
perror("inet_pton");
exit(EXIT_FAILURE);
}
family = AF_INET6;
}
if (sscanf(argv[3], "%u", &prefix) == 0) {
perror("sscanf");
exit(EXIT_FAILURE);
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_NEWADDR;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE | NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifaddrmsg));
ifm->ifa_family = family;
ifm->ifa_prefixlen = prefix;
ifm->ifa_flags = IFA_F_PERMANENT;
ifm->ifa_scope = RT_SCOPE_UNIVERSE;
ifm->ifa_index = iface;
/*
* The exact meaning of IFA_LOCAL and IFA_ADDRESS depend
* on the address family being used and the device type.
* For broadcast devices (like the interfaces we use),
* for IPv4 we specify both and they are used interchangeably.
* For IPv6, only IFA_ADDRESS needs to be set.
*/
if (family == AF_INET) {
mnl_attr_put_u32(nlh, IFA_LOCAL, addr.ip);
mnl_attr_put_u32(nlh, IFA_ADDRESS, addr.ip);
} else {
mnl_attr_put(nlh, IFA_ADDRESS, sizeof(struct in6_addr), &addr);
}
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret < 0) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
if (ret < 0) {
perror("mnl_cb_run");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,133 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <libmnl/libmnl.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
static int data_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, IFA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case IFA_ADDRESS:
if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[IFA_MAX + 1] = {};
struct ifaddrmsg *ifa = mnl_nlmsg_get_payload(nlh);
printf("index=%d family=%d ", ifa->ifa_index, ifa->ifa_family);
mnl_attr_parse(nlh, sizeof(*ifa), data_attr_cb, tb);
printf("addr=");
if (tb[IFA_ADDRESS]) {
void *addr = mnl_attr_get_payload(tb[IFA_ADDRESS]);
char out[INET6_ADDRSTRLEN];
if (inet_ntop(ifa->ifa_family, addr, out, sizeof(out)))
printf("%s ", out);
}
printf("scope=");
switch(ifa->ifa_scope) {
case 0:
printf("global ");
break;
case 200:
printf("site ");
break;
case 253:
printf("link ");
break;
case 254:
printf("host ");
break;
case 255:
printf("nowhere ");
break;
default:
printf("%d ", ifa->ifa_scope);
break;
}
printf("\n");
return MNL_CB_OK;
}
int main(int argc, char *argv[])
{
char buf[MNL_SOCKET_DUMP_SIZE];
unsigned int seq, portid;
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct rtgenmsg *rt;
int ret;
if (argc != 2) {
fprintf(stderr, "Usage: %s <inet|inet6>\n", argv[0]);
exit(EXIT_FAILURE);
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_GETADDR;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
nlh->nlmsg_seq = seq = time(NULL);
rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
if (strcmp(argv[1], "inet") == 0)
rt->rtgen_family = AF_INET;
else if (strcmp(argv[1], "inet6") == 0)
rt->rtgen_family = AF_INET6;
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
if (ret <= MNL_CB_STOP)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,452 +0,0 @@
/* This example is placed in the public domain. */
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <libmnl/libmnl.h>
#include <linux/can/netlink.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
static void incomplete_command(void) __attribute__((noreturn));
#define NEXT_ARG() \
do { \
if (argc <= 0) incomplete_command(); \
argv++; \
argc--; \
} while (0)
static void duparg2(const char *key, const char *arg)
{
fprintf(stderr,
"Error: either \"%s\" is duplicate, or \"%s\" is a garbage.\n",
key, arg);
exit(-1);
}
static void incomplete_command(void)
{
fprintf(stderr, "Command line is not complete. Try option \"help\"\n");
exit(EXIT_FAILURE);
}
/* Returns false if 'prefix' is a not empty prefix of 'string'.
*/
static bool matches(const char *prefix, const char *string)
{
if (!*prefix)
return true;
while (*string && *prefix == *string) {
prefix++;
string++;
}
return !!*prefix;
}
static int get_u16(__u16 *val, const char *arg, int base)
{
unsigned long res;
char *ptr;
if (!arg || !*arg)
return -1;
res = strtoul(arg, &ptr, base);
/* empty string or trailing non-digits */
if (!ptr || ptr == arg || *ptr)
return -1;
/* overflow */
if (res == ULONG_MAX && errno == ERANGE)
return -1;
if (res > 0xFFFFUL)
return -1;
*val = res;
return 0;
}
static int get_u32(__u32 *val, const char *arg, int base)
{
unsigned long res;
char *ptr;
if (!arg || !*arg)
return -1;
res = strtoul(arg, &ptr, base);
/* empty string or trailing non-digits */
if (!ptr || ptr == arg || *ptr)
return -1;
/* overflow */
if (res == ULONG_MAX && errno == ERANGE)
return -1;
/* in case UL > 32 bits */
if (res > 0xFFFFFFFFUL)
return -1;
*val = res;
return 0;
}
static int get_float(float *val, const char *arg)
{
float res;
char *ptr;
if (!arg || !*arg)
return -1;
res = strtof(arg, &ptr);
if (!ptr || ptr == arg || *ptr)
return -1;
*val = res;
return 0;
}
static void set_ctrlmode(char *name, char *arg,
struct can_ctrlmode *cm, __u32 flags)
{
if (strcmp(arg, "on") == 0) {
cm->flags |= flags;
} else if (strcmp(arg, "off") != 0) {
fprintf(stderr,
"Error: argument of \"%s\" must be \"on\" or \"off\", not \"%s\"\n",
name, arg);
exit(EXIT_FAILURE);
}
cm->mask |= flags;
}
static void invarg(const char *msg, const char *arg)
{
fprintf(stderr, "Error: argument \"%s\" is wrong: %s\n", arg, msg);
exit(-1);
}
static void print_usage(FILE *f)
{
fprintf(f,
"Usage: ip link set DEVICE type can\n"
"\t[ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |\n"
"\t[ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1\n \t phase-seg2 PHASE-SEG2 [ sjw SJW ] ]\n"
"\n"
"\t[ dbitrate BITRATE [ dsample-point SAMPLE-POINT] ] |\n"
"\t[ dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1\n \t dphase-seg2 PHASE-SEG2 [ dsjw SJW ] ]\n"
"\n"
"\t[ loopback { on | off } ]\n"
"\t[ listen-only { on | off } ]\n"
"\t[ triple-sampling { on | off } ]\n"
"\t[ one-shot { on | off } ]\n"
"\t[ berr-reporting { on | off } ]\n"
"\t[ fd { on | off } ]\n"
"\t[ fd-non-iso { on | off } ]\n"
"\t[ presume-ack { on | off } ]\n"
"\t[ cc-len8-dlc { on | off } ]\n"
"\n"
"\t[ restart-ms TIME-MS ]\n"
"\t[ restart ]\n"
"\n"
"\t[ termination { 0..65535 } ]\n"
"\n"
"\tWhere: BITRATE := { 1..1000000 }\n"
"\t SAMPLE-POINT := { 0.000..0.999 }\n"
"\t TQ := { NUMBER }\n"
"\t PROP-SEG := { 1..8 }\n"
"\t PHASE-SEG1 := { 1..8 }\n"
"\t PHASE-SEG2 := { 1..8 }\n"
"\t SJW := { 1..4 }\n"
"\t RESTART-MS := { 0 | NUMBER }\n"
);
}
static void usage(void)
{
print_usage(stderr);
}
static int iplink_set_can_parse(int argc, char **argv, struct nlmsghdr *nlh)
{
struct can_bittiming bt = {}, dbt = {};
struct can_ctrlmode cm = {};
while (argc > 0) {
if (matches(*argv, "bitrate") == 0) {
NEXT_ARG();
if (get_u32(&bt.bitrate, *argv, 0))
invarg("invalid \"bitrate\" value\n", *argv);
} else if (matches(*argv, "sample-point") == 0) {
float sp;
NEXT_ARG();
if (get_float(&sp, *argv))
invarg("invalid \"sample-point\" value\n",
*argv);
bt.sample_point = (__u32)(sp * 1000);
} else if (matches(*argv, "tq") == 0) {
NEXT_ARG();
if (get_u32(&bt.tq, *argv, 0))
invarg("invalid \"tq\" value\n", *argv);
} else if (matches(*argv, "prop-seg") == 0) {
NEXT_ARG();
if (get_u32(&bt.prop_seg, *argv, 0))
invarg("invalid \"prop-seg\" value\n", *argv);
} else if (matches(*argv, "phase-seg1") == 0) {
NEXT_ARG();
if (get_u32(&bt.phase_seg1, *argv, 0))
invarg("invalid \"phase-seg1\" value\n", *argv);
} else if (matches(*argv, "phase-seg2") == 0) {
NEXT_ARG();
if (get_u32(&bt.phase_seg2, *argv, 0))
invarg("invalid \"phase-seg2\" value\n", *argv);
} else if (matches(*argv, "sjw") == 0) {
NEXT_ARG();
if (get_u32(&bt.sjw, *argv, 0))
invarg("invalid \"sjw\" value\n", *argv);
} else if (matches(*argv, "dbitrate") == 0) {
NEXT_ARG();
if (get_u32(&dbt.bitrate, *argv, 0))
invarg("invalid \"dbitrate\" value\n", *argv);
} else if (matches(*argv, "dsample-point") == 0) {
float sp;
NEXT_ARG();
if (get_float(&sp, *argv))
invarg("invalid \"dsample-point\" value\n", *argv);
dbt.sample_point = (__u32)(sp * 1000);
} else if (matches(*argv, "dtq") == 0) {
NEXT_ARG();
if (get_u32(&dbt.tq, *argv, 0))
invarg("invalid \"dtq\" value\n", *argv);
} else if (matches(*argv, "dprop-seg") == 0) {
NEXT_ARG();
if (get_u32(&dbt.prop_seg, *argv, 0))
invarg("invalid \"dprop-seg\" value\n", *argv);
} else if (matches(*argv, "dphase-seg1") == 0) {
NEXT_ARG();
if (get_u32(&dbt.phase_seg1, *argv, 0))
invarg("invalid \"dphase-seg1\" value\n", *argv);
} else if (matches(*argv, "dphase-seg2") == 0) {
NEXT_ARG();
if (get_u32(&dbt.phase_seg2, *argv, 0))
invarg("invalid \"dphase-seg2\" value\n", *argv);
} else if (matches(*argv, "dsjw") == 0) {
NEXT_ARG();
if (get_u32(&dbt.sjw, *argv, 0))
invarg("invalid \"dsjw\" value\n", *argv);
} else if (matches(*argv, "loopback") == 0) {
NEXT_ARG();
set_ctrlmode("loopback", *argv, &cm,
CAN_CTRLMODE_LOOPBACK);
} else if (matches(*argv, "listen-only") == 0) {
NEXT_ARG();
set_ctrlmode("listen-only", *argv, &cm,
CAN_CTRLMODE_LISTENONLY);
} else if (matches(*argv, "triple-sampling") == 0) {
NEXT_ARG();
set_ctrlmode("triple-sampling", *argv, &cm,
CAN_CTRLMODE_3_SAMPLES);
} else if (matches(*argv, "one-shot") == 0) {
NEXT_ARG();
set_ctrlmode("one-shot", *argv, &cm,
CAN_CTRLMODE_ONE_SHOT);
} else if (matches(*argv, "berr-reporting") == 0) {
NEXT_ARG();
set_ctrlmode("berr-reporting", *argv, &cm,
CAN_CTRLMODE_BERR_REPORTING);
} else if (matches(*argv, "fd") == 0) {
NEXT_ARG();
set_ctrlmode("fd", *argv, &cm,
CAN_CTRLMODE_FD);
} else if (matches(*argv, "fd-non-iso") == 0) {
NEXT_ARG();
set_ctrlmode("fd-non-iso", *argv, &cm,
CAN_CTRLMODE_FD_NON_ISO);
} else if (matches(*argv, "presume-ack") == 0) {
NEXT_ARG();
set_ctrlmode("presume-ack", *argv, &cm,
CAN_CTRLMODE_PRESUME_ACK);
#if defined(CAN_CTRLMODE_CC_LEN8_DLC)
} else if (matches(*argv, "cc-len8-dlc") == 0) {
NEXT_ARG();
set_ctrlmode("cc-len8-dlc", *argv, &cm,
CAN_CTRLMODE_CC_LEN8_DLC);
#endif
} else if (matches(*argv, "restart") == 0) {
__u32 val = 1;
mnl_attr_put(nlh, IFLA_CAN_RESTART, sizeof(val), &val);
} else if (matches(*argv, "restart-ms") == 0) {
__u32 val;
NEXT_ARG();
if (get_u32(&val, *argv, 0))
invarg("invalid \"restart-ms\" value\n", *argv);
mnl_attr_put(nlh, IFLA_CAN_RESTART_MS, sizeof(val), &val);
} else if (matches(*argv, "termination") == 0) {
__u16 val;
NEXT_ARG();
if (get_u16(&val, *argv, 0))
invarg("invalid \"termination\" value\n",
*argv);
mnl_attr_put(nlh, IFLA_CAN_TERMINATION, sizeof(val), &val);
} else {
fprintf(stderr, "unknown option \"%s\"\n", *argv);
usage();
return -1;
}
NEXT_ARG();
}
if (bt.bitrate || bt.tq)
mnl_attr_put(nlh, IFLA_CAN_BITTIMING, sizeof(bt), &bt);
if (cm.mask)
mnl_attr_put(nlh, IFLA_CAN_CTRLMODE, sizeof(cm), &cm);
return 0;
}
int main(int argc, char *argv[])
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct ifinfomsg *ifm;
int ret;
unsigned int seq, portid;
struct nlattr *linkinfo, *data;
const char *signatures[] = {
"ip", "link", "set", ""
};
char *type = NULL;
char *dev = NULL;
int i;
NEXT_ARG();
for (i = 0; argc > 0 && signatures[i][0];) {
if (matches(*argv, signatures[i]))
incomplete_command();
NEXT_ARG();
i++;
}
if (argc == 0)
incomplete_command();
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_NEWLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
ifm->ifi_family = AF_UNSPEC;
ifm->ifi_change = 0;
ifm->ifi_flags = 0;
while (argc > 0) {
if (matches(*argv, "up") == 0) {
ifm->ifi_change |= IFF_UP;
ifm->ifi_flags |= IFF_UP;
} else if (matches(*argv, "down") == 0) {
ifm->ifi_change |= IFF_UP;
ifm->ifi_flags &= ~IFF_UP;
} else if (matches(*argv, "type") == 0) {
NEXT_ARG();
type = *argv;
NEXT_ARG();
break;
} else if (matches(*argv, "help") == 0) {
usage();
exit(EXIT_FAILURE);
} else {
if (matches(*argv, "dev") == 0)
NEXT_ARG();
if (dev)
duparg2("dev", *argv);
dev = *argv;
}
NEXT_ARG();
}
if (dev)
mnl_attr_put_str(nlh, IFLA_IFNAME, dev);
if (type) {
if (matches(type, "can")) {
fprintf(stderr, "unknown type \"%s\"\n", type);
usage();
exit(EXIT_FAILURE);
}
linkinfo = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
mnl_attr_put_str(nlh, IFLA_INFO_KIND, "can");
data = mnl_attr_nest_start(nlh, IFLA_INFO_DATA);
if (iplink_set_can_parse(argc, argv, nlh))
return -1;
mnl_attr_nest_end(nlh, data);
mnl_attr_nest_end(nlh, linkinfo);
}
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len,
sizeof(struct ifinfomsg));
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
if (ret == -1) {
perror("mnl_cb_run");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,130 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <libmnl/libmnl.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
static int data_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, IFLA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case IFLA_ADDRESS:
if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case IFLA_MTU:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case IFLA_IFNAME:
if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[IFLA_MAX+1] = {};
struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);
printf("index=%d type=%d flags=%d family=%d ",
ifm->ifi_index, ifm->ifi_type,
ifm->ifi_flags, ifm->ifi_family);
if (ifm->ifi_flags & IFF_RUNNING)
printf("[RUNNING] ");
else
printf("[NOT RUNNING] ");
mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb);
if (tb[IFLA_MTU]) {
printf("mtu=%d ", mnl_attr_get_u32(tb[IFLA_MTU]));
}
if (tb[IFLA_IFNAME]) {
printf("name=%s ", mnl_attr_get_str(tb[IFLA_IFNAME]));
}
if (tb[IFLA_ADDRESS]) {
uint8_t *hwaddr = mnl_attr_get_payload(tb[IFLA_ADDRESS]);
int i;
printf("hwaddr=");
for (i=0; i<mnl_attr_get_payload_len(tb[IFLA_ADDRESS]); i++) {
printf("%.2x", hwaddr[i] & 0xff);
if (i+1 != mnl_attr_get_payload_len(tb[IFLA_ADDRESS]))
printf(":");
}
}
printf("\n");
return MNL_CB_OK;
}
int main(void)
{
char buf[MNL_SOCKET_DUMP_SIZE];
unsigned int seq, portid;
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct rtgenmsg *rt;
int ret;
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_GETLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
nlh->nlmsg_seq = seq = time(NULL);
rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
rt->rtgen_family = AF_PACKET;
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
if (ret <= MNL_CB_STOP)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,103 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <libmnl/libmnl.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
static int data_attr_cb(const struct nlattr *attr, void *data)
{
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, IFLA_MAX) < 0)
return MNL_CB_OK;
switch(mnl_attr_get_type(attr)) {
case IFLA_MTU:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
printf("mtu=%d ", mnl_attr_get_u32(attr));
break;
case IFLA_IFNAME:
if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
printf("name=%s ", mnl_attr_get_str(attr));
break;
}
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);
printf("index=%d type=%d flags=%d family=%d ",
ifm->ifi_index, ifm->ifi_type,
ifm->ifi_flags, ifm->ifi_family);
if (ifm->ifi_flags & IFF_RUNNING)
printf("[RUNNING] ");
else
printf("[NOT RUNNING] ");
mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, NULL);
printf("\n");
return MNL_CB_OK;
}
int main(void)
{
char buf[MNL_SOCKET_DUMP_SIZE];
unsigned int seq, portid;
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct rtgenmsg *rt;
int ret;
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_GETLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
nlh->nlmsg_seq = seq = time(NULL);
rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
rt->rtgen_family = AF_PACKET;
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
if (ret <= MNL_CB_STOP)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,103 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <libmnl/libmnl.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);
struct nlattr *attr;
printf("index=%d type=%d flags=%d family=%d ",
ifm->ifi_index, ifm->ifi_type,
ifm->ifi_flags, ifm->ifi_family);
if (ifm->ifi_flags & IFF_RUNNING)
printf("[RUNNING] ");
else
printf("[NOT RUNNING] ");
mnl_attr_for_each(attr, nlh, sizeof(*ifm)) {
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, IFLA_MAX) < 0)
continue;
switch(type) {
case IFLA_MTU:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
printf("mtu=%d ", mnl_attr_get_u32(attr));
break;
case IFLA_IFNAME:
if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
printf("name=%s ", mnl_attr_get_str(attr));
break;
}
}
printf("\n");
return MNL_CB_OK;
}
int main(void)
{
char buf[MNL_SOCKET_DUMP_SIZE];
unsigned int seq, portid;
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct rtgenmsg *rt;
int ret;
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_GETLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
nlh->nlmsg_seq = seq = time(NULL);
rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
rt->rtgen_family = AF_PACKET;
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
if (ret <= MNL_CB_STOP)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,95 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libmnl/libmnl.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
static int data_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, IFLA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case IFLA_MTU:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case IFLA_IFNAME:
if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[IFLA_MAX+1] = {};
struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);
printf("index=%d type=%d flags=%d family=%d ",
ifm->ifi_index, ifm->ifi_type,
ifm->ifi_flags, ifm->ifi_family);
if (ifm->ifi_flags & IFF_RUNNING)
printf("[RUNNING] ");
else
printf("[NOT RUNNING] ");
mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb);
if (tb[IFLA_MTU]) {
printf("mtu=%d ", mnl_attr_get_u32(tb[IFLA_MTU]));
}
if (tb[IFLA_IFNAME]) {
printf("name=%s", mnl_attr_get_str(tb[IFLA_IFNAME]));
}
printf("\n");
return MNL_CB_OK;
}
int main(void)
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
int ret;
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, RTMGRP_LINK, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
if (ret <= 0)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,84 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <libmnl/libmnl.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct ifinfomsg *ifm;
int ret;
unsigned int seq, portid, change = 0, flags = 0;
if (argc != 3) {
printf("Usage: %s [ifname] [up|down]\n", argv[0]);
exit(EXIT_FAILURE);
}
if (strncasecmp(argv[2], "up", strlen("up")) == 0) {
change |= IFF_UP;
flags |= IFF_UP;
} else if (strncasecmp(argv[2], "down", strlen("down")) == 0) {
change |= IFF_UP;
flags &= ~IFF_UP;
} else {
fprintf(stderr, "%s is not `up' nor `down'\n", argv[2]);
exit(EXIT_FAILURE);
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_NEWLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
ifm->ifi_family = AF_UNSPEC;
ifm->ifi_change = change;
ifm->ifi_flags = flags;
mnl_attr_put_str(nlh, IFLA_IFNAME, argv[1]);
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len,
sizeof(struct ifinfomsg));
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
if (ret == -1){
perror("mnl_cb_run");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,158 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <libmnl/libmnl.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
static int data_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, NDA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case NDA_DST:
case NDA_LLADDR:
if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[NDA_MAX + 1] = {};
struct ndmsg *ndm = mnl_nlmsg_get_payload(nlh);
printf("index=%d family=%d ", ndm->ndm_ifindex, ndm->ndm_family);
mnl_attr_parse(nlh, sizeof(*ndm), data_attr_cb, tb);
printf("dst=");
if (tb[NDA_DST]) {
void *addr = mnl_attr_get_payload(tb[NDA_DST]);
char out[INET6_ADDRSTRLEN];
if (inet_ntop(ndm->ndm_family, addr, out, sizeof(out)))
printf("%s ", out);
}
mnl_attr_parse(nlh, sizeof(*ndm), data_attr_cb, tb);
printf("lladdr=");
if (tb[NDA_LLADDR]) {
void *addr = mnl_attr_get_payload(tb[NDA_LLADDR]);
unsigned char lladdr[6] = {0};
if (memcpy(&lladdr, addr, 6))
printf("%02x:%02x:%02x:%02x:%02x:%02x ",
lladdr[0], lladdr[1], lladdr[2],
lladdr[3], lladdr[4], lladdr[5]);
}
printf("state=");
switch(ndm->ndm_state) {
case NUD_INCOMPLETE:
printf("incomplete ");
break;
case NUD_REACHABLE:
printf("reachable ");
break;
case NUD_STALE:
printf("stale ");
break;
case NUD_DELAY:
printf("delay ");
break;
case NUD_PROBE:
printf("probe ");
break;
case NUD_FAILED:
printf("failed ");
break;
case NUD_NOARP:
printf("noarp ");
break;
case NUD_PERMANENT:
printf("permanent ");
break;
default:
printf("%d ", ndm->ndm_state);
break;
}
printf("\n");
return MNL_CB_OK;
}
int main(int argc, char *argv[])
{
char buf[MNL_SOCKET_DUMP_SIZE];
unsigned int seq, portid;
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct ndmsg *nd;
int ret;
if (argc != 2) {
fprintf(stderr, "Usage: %s <inet|inet6>\n", argv[0]);
exit(EXIT_FAILURE);
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_GETNEIGH;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
nlh->nlmsg_seq = seq = time(NULL);
nd = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ndmsg));
if (strcmp(argv[1], "inet") == 0)
nd->ndm_family = AF_INET;
else if (strcmp(argv[1], "inet6") == 0)
nd->ndm_family = AF_INET6;
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
if (ret <= MNL_CB_STOP)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,127 +0,0 @@
/* This example is placed in the public domain. */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <net/if.h>
#include <libmnl/libmnl.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct rtmsg *rtm;
uint32_t prefix, seq, portid;
union {
in_addr_t ip;
struct in6_addr ip6;
} dst;
union {
in_addr_t ip;
struct in6_addr ip6;
} gw;
int iface, ret, family = AF_INET;
if (argc <= 3) {
printf("Usage: %s iface destination cidr [gateway]\n", argv[0]);
printf("Example: %s eth0 10.0.1.12 32 10.0.1.11\n", argv[0]);
printf(" %s eth0 ffff::10.0.1.12 128 fdff::1\n", argv[0]);
exit(EXIT_FAILURE);
}
iface = if_nametoindex(argv[1]);
if (iface == 0) {
perror("if_nametoindex");
exit(EXIT_FAILURE);
}
if (!inet_pton(AF_INET, argv[2], &dst)) {
if (!inet_pton(AF_INET6, argv[2], &dst)) {
perror("inet_pton");
exit(EXIT_FAILURE);
}
family = AF_INET6;
}
if (sscanf(argv[3], "%u", &prefix) == 0) {
perror("sscanf");
exit(EXIT_FAILURE);
}
if (argc == 5 && !inet_pton(family, argv[4], &gw)) {
perror("inet_pton");
exit(EXIT_FAILURE);
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_NEWROUTE;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));
rtm->rtm_family = family;
rtm->rtm_dst_len = prefix;
rtm->rtm_src_len = 0;
rtm->rtm_tos = 0;
rtm->rtm_protocol = RTPROT_STATIC;
rtm->rtm_table = RT_TABLE_MAIN;
rtm->rtm_type = RTN_UNICAST;
/* is there any gateway? */
rtm->rtm_scope = (argc == 4) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE;
rtm->rtm_flags = 0;
if (family == AF_INET)
mnl_attr_put_u32(nlh, RTA_DST, dst.ip);
else
mnl_attr_put(nlh, RTA_DST, sizeof(struct in6_addr), &dst);
mnl_attr_put_u32(nlh, RTA_OIF, iface);
if (argc == 5) {
if (family == AF_INET)
mnl_attr_put_u32(nlh, RTA_GATEWAY, gw.ip);
else {
mnl_attr_put(nlh, RTA_GATEWAY, sizeof(struct in6_addr),
&gw.ip6);
}
}
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret < 0) {
perror("mnl_socket_recvfrom");
exit(EXIT_FAILURE);
}
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
if (ret < 0) {
perror("mnl_cb_run");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,356 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <libmnl/libmnl.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
static int data_attr_cb2(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, RTAX_MAX) < 0)
return MNL_CB_OK;
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
tb[mnl_attr_get_type(attr)] = attr;
return MNL_CB_OK;
}
static void attributes_show_ipv4(struct nlattr *tb[])
{
if (tb[RTA_TABLE]) {
printf("table=%u ", mnl_attr_get_u32(tb[RTA_TABLE]));
}
if (tb[RTA_DST]) {
struct in_addr *addr = mnl_attr_get_payload(tb[RTA_DST]);
printf("dst=%s ", inet_ntoa(*addr));
}
if (tb[RTA_SRC]) {
struct in_addr *addr = mnl_attr_get_payload(tb[RTA_SRC]);
printf("src=%s ", inet_ntoa(*addr));
}
if (tb[RTA_OIF]) {
printf("oif=%u ", mnl_attr_get_u32(tb[RTA_OIF]));
}
if (tb[RTA_FLOW]) {
printf("flow=%u ", mnl_attr_get_u32(tb[RTA_FLOW]));
}
if (tb[RTA_PREFSRC]) {
struct in_addr *addr = mnl_attr_get_payload(tb[RTA_PREFSRC]);
printf("prefsrc=%s ", inet_ntoa(*addr));
}
if (tb[RTA_GATEWAY]) {
struct in_addr *addr = mnl_attr_get_payload(tb[RTA_GATEWAY]);
printf("gw=%s ", inet_ntoa(*addr));
}
if (tb[RTA_PRIORITY]) {
printf("prio=%u ", mnl_attr_get_u32(tb[RTA_PRIORITY]));
}
if (tb[RTA_METRICS]) {
int i;
struct nlattr *tbx[RTAX_MAX+1] = {};
mnl_attr_parse_nested(tb[RTA_METRICS], data_attr_cb2, tbx);
for (i=0; i<RTAX_MAX; i++) {
if (tbx[i]) {
printf("metrics[%d]=%u ",
i, mnl_attr_get_u32(tbx[i]));
}
}
}
}
/* like inet_ntoa(), not reentrant */
static const char *inet6_ntoa(struct in6_addr in6)
{
static char buf[INET6_ADDRSTRLEN];
return inet_ntop(AF_INET6, &in6.s6_addr, buf, sizeof(buf));
}
static void attributes_show_ipv6(struct nlattr *tb[])
{
if (tb[RTA_TABLE]) {
printf("table=%u ", mnl_attr_get_u32(tb[RTA_TABLE]));
}
if (tb[RTA_DST]) {
struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_DST]);
printf("dst=%s ", inet6_ntoa(*addr));
}
if (tb[RTA_SRC]) {
struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_SRC]);
printf("src=%s ", inet6_ntoa(*addr));
}
if (tb[RTA_OIF]) {
printf("oif=%u ", mnl_attr_get_u32(tb[RTA_OIF]));
}
if (tb[RTA_FLOW]) {
printf("flow=%u ", mnl_attr_get_u32(tb[RTA_FLOW]));
}
if (tb[RTA_PREFSRC]) {
struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_PREFSRC]);
printf("prefsrc=%s ", inet6_ntoa(*addr));
}
if (tb[RTA_GATEWAY]) {
struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_GATEWAY]);
printf("gw=%s ", inet6_ntoa(*addr));
}
if (tb[RTA_PRIORITY]) {
printf("prio=%u ", mnl_attr_get_u32(tb[RTA_PRIORITY]));
}
if (tb[RTA_METRICS]) {
int i;
struct nlattr *tbx[RTAX_MAX+1] = {};
mnl_attr_parse_nested(tb[RTA_METRICS], data_attr_cb2, tbx);
for (i=0; i<RTAX_MAX; i++) {
if (tbx[i]) {
printf("metrics[%d]=%u ",
i, mnl_attr_get_u32(tbx[i]));
}
}
}
}
static int data_ipv4_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, RTA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case RTA_TABLE:
case RTA_DST:
case RTA_SRC:
case RTA_OIF:
case RTA_FLOW:
case RTA_PREFSRC:
case RTA_GATEWAY:
case RTA_PRIORITY:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case RTA_METRICS:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_ipv6_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, RTA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case RTA_TABLE:
case RTA_OIF:
case RTA_FLOW:
case RTA_PRIORITY:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case RTA_DST:
case RTA_SRC:
case RTA_PREFSRC:
case RTA_GATEWAY:
if (mnl_attr_validate2(attr, MNL_TYPE_BINARY,
sizeof(struct in6_addr)) < 0) {
perror("mnl_attr_validate2");
return MNL_CB_ERROR;
}
break;
case RTA_METRICS:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[RTA_MAX+1] = {};
struct rtmsg *rm = mnl_nlmsg_get_payload(nlh);
/* protocol family = AF_INET | AF_INET6 */
printf("family=%u ", rm->rtm_family);
/* destination CIDR, eg. 24 or 32 for IPv4 */
printf("dst_len=%u ", rm->rtm_dst_len);
/* source CIDR */
printf("src_len=%u ", rm->rtm_src_len);
/* type of service (TOS), eg. 0 */
printf("tos=%u ", rm->rtm_tos);
/* table id:
* RT_TABLE_UNSPEC = 0
*
* ... user defined values ...
*
* RT_TABLE_COMPAT = 252
* RT_TABLE_DEFAULT = 253
* RT_TABLE_MAIN = 254
* RT_TABLE_LOCAL = 255
* RT_TABLE_MAX = 0xFFFFFFFF
*
* Synonimous attribute: RTA_TABLE.
*/
printf("table=%u ", rm->rtm_table);
/* type:
* RTN_UNSPEC = 0
* RTN_UNICAST = 1
* RTN_LOCAL = 2
* RTN_BROADCAST = 3
* RTN_ANYCAST = 4
* RTN_MULTICAST = 5
* RTN_BLACKHOLE = 6
* RTN_UNREACHABLE = 7
* RTN_PROHIBIT = 8
* RTN_THROW = 9
* RTN_NAT = 10
* RTN_XRESOLVE = 11
* __RTN_MAX = 12
*/
printf("type=%u ", rm->rtm_type);
/* scope:
* RT_SCOPE_UNIVERSE = 0 : everywhere in the universe
*
* ... user defined values ...
*
* RT_SCOPE_SITE = 200
* RT_SCOPE_LINK = 253 : destination attached to link
* RT_SCOPE_HOST = 254 : local address
* RT_SCOPE_NOWHERE = 255 : not existing destination
*/
printf("scope=%u ", rm->rtm_scope);
/* protocol:
* RTPROT_UNSPEC = 0
* RTPROT_REDIRECT = 1
* RTPROT_KERNEL = 2 : route installed by kernel
* RTPROT_BOOT = 3 : route installed during boot
* RTPROT_STATIC = 4 : route installed by administrator
*
* Values >= RTPROT_STATIC are not interpreted by kernel, they are
* just user-defined.
*/
printf("proto=%u ", rm->rtm_protocol);
/* flags:
* RTM_F_NOTIFY = 0x100: notify user of route change
* RTM_F_CLONED = 0x200: this route is cloned
* RTM_F_EQUALIZE = 0x400: Multipath equalizer: NI
* RTM_F_PREFIX = 0x800: Prefix addresses
*/
printf("flags=%x ", rm->rtm_flags);
switch(rm->rtm_family) {
case AF_INET:
mnl_attr_parse(nlh, sizeof(*rm), data_ipv4_attr_cb, tb);
attributes_show_ipv4(tb);
break;
case AF_INET6:
mnl_attr_parse(nlh, sizeof(*rm), data_ipv6_attr_cb, tb);
attributes_show_ipv6(tb);
break;
}
printf("\n");
return MNL_CB_OK;
}
int main(int argc, char *argv[])
{
char buf[MNL_SOCKET_DUMP_SIZE];
unsigned int seq, portid;
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct rtmsg *rtm;
int ret;
if (argc != 2) {
fprintf(stderr, "Usage: %s <inet|inet6>\n", argv[0]);
exit(EXIT_FAILURE);
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_GETROUTE;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
nlh->nlmsg_seq = seq = time(NULL);
rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));
if (strcmp(argv[1], "inet") == 0)
rtm->rtm_family = AF_INET;
else if (strcmp(argv[1], "inet6") == 0)
rtm->rtm_family = AF_INET6;
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_sendto");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
if (ret <= MNL_CB_STOP)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1,341 +0,0 @@
/* This example is placed in the public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <libmnl/libmnl.h>
#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
static int data_attr_cb2(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, RTAX_MAX) < 0)
return MNL_CB_OK;
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
tb[mnl_attr_get_type(attr)] = attr;
return MNL_CB_OK;
}
static void attributes_show_ipv4(struct nlattr *tb[])
{
if (tb[RTA_TABLE]) {
printf("table=%u ", mnl_attr_get_u32(tb[RTA_TABLE]));
}
if (tb[RTA_DST]) {
struct in_addr *addr = mnl_attr_get_payload(tb[RTA_DST]);
printf("dst=%s ", inet_ntoa(*addr));
}
if (tb[RTA_SRC]) {
struct in_addr *addr = mnl_attr_get_payload(tb[RTA_SRC]);
printf("src=%s ", inet_ntoa(*addr));
}
if (tb[RTA_OIF]) {
printf("oif=%u ", mnl_attr_get_u32(tb[RTA_OIF]));
}
if (tb[RTA_FLOW]) {
printf("flow=%u ", mnl_attr_get_u32(tb[RTA_FLOW]));
}
if (tb[RTA_PREFSRC]) {
struct in_addr *addr = mnl_attr_get_payload(tb[RTA_PREFSRC]);
printf("prefsrc=%s ", inet_ntoa(*addr));
}
if (tb[RTA_GATEWAY]) {
struct in_addr *addr = mnl_attr_get_payload(tb[RTA_GATEWAY]);
printf("gw=%s ", inet_ntoa(*addr));
}
if (tb[RTA_PRIORITY]) {
printf("prio=%u ", mnl_attr_get_u32(tb[RTA_PRIORITY]));
}
if (tb[RTA_METRICS]) {
int i;
struct nlattr *tbx[RTAX_MAX+1] = {};
mnl_attr_parse_nested(tb[RTA_METRICS], data_attr_cb2, tbx);
for (i=0; i<RTAX_MAX; i++) {
if (tbx[i]) {
printf("metrics[%d]=%u ",
i, mnl_attr_get_u32(tbx[i]));
}
}
}
}
/* like inet_ntoa(), not reentrant */
static const char *inet6_ntoa(struct in6_addr in6)
{
static char buf[INET6_ADDRSTRLEN];
return inet_ntop(AF_INET6, &in6.s6_addr, buf, sizeof(buf));
}
static void attributes_show_ipv6(struct nlattr *tb[])
{
if (tb[RTA_TABLE]) {
printf("table=%u ", mnl_attr_get_u32(tb[RTA_TABLE]));
}
if (tb[RTA_DST]) {
struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_DST]);
printf("dst=%s ", inet6_ntoa(*addr));
}
if (tb[RTA_SRC]) {
struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_SRC]);
printf("src=%s ", inet6_ntoa(*addr));
}
if (tb[RTA_OIF]) {
printf("oif=%u ", mnl_attr_get_u32(tb[RTA_OIF]));
}
if (tb[RTA_FLOW]) {
printf("flow=%u ", mnl_attr_get_u32(tb[RTA_FLOW]));
}
if (tb[RTA_PREFSRC]) {
struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_PREFSRC]);
printf("prefsrc=%s ", inet6_ntoa(*addr));
}
if (tb[RTA_GATEWAY]) {
struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_GATEWAY]);
printf("gw=%s ", inet6_ntoa(*addr));
}
if (tb[RTA_PRIORITY]) {
printf("prio=%u ", mnl_attr_get_u32(tb[RTA_PRIORITY]));
}
if (tb[RTA_METRICS]) {
int i;
struct nlattr *tbx[RTAX_MAX+1] = {};
mnl_attr_parse_nested(tb[RTA_METRICS], data_attr_cb2, tbx);
for (i=0; i<RTAX_MAX; i++) {
if (tbx[i]) {
printf("metrics[%d]=%u ",
i, mnl_attr_get_u32(tbx[i]));
}
}
}
}
static int data_ipv4_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, RTA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case RTA_TABLE:
case RTA_DST:
case RTA_SRC:
case RTA_OIF:
case RTA_FLOW:
case RTA_PREFSRC:
case RTA_GATEWAY:
case RTA_PRIORITY:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case RTA_METRICS:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_ipv6_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, RTA_MAX) < 0)
return MNL_CB_OK;
switch(type) {
case RTA_TABLE:
case RTA_OIF:
case RTA_FLOW:
case RTA_PRIORITY:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
case RTA_DST:
case RTA_SRC:
case RTA_PREFSRC:
case RTA_GATEWAY:
if (mnl_attr_validate2(attr, MNL_TYPE_BINARY,
sizeof(struct in6_addr)) < 0) {
perror("mnl_attr_validate2");
return MNL_CB_ERROR;
}
break;
case RTA_METRICS:
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
perror("mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[RTA_MAX+1] = {};
struct rtmsg *rm = mnl_nlmsg_get_payload(nlh);
switch(nlh->nlmsg_type) {
case RTM_NEWROUTE:
printf("[NEW] ");
break;
case RTM_DELROUTE:
printf("[DEL] ");
break;
}
/* protocol family = AF_INET | AF_INET6 */
printf("family=%u ", rm->rtm_family);
/* destination CIDR, eg. 24 or 32 for IPv4 */
printf("dst_len=%u ", rm->rtm_dst_len);
/* source CIDR */
printf("src_len=%u ", rm->rtm_src_len);
/* type of service (TOS), eg. 0 */
printf("tos=%u ", rm->rtm_tos);
/* table id:
* RT_TABLE_UNSPEC = 0
*
* ... user defined values ...
*
* RT_TABLE_COMPAT = 252
* RT_TABLE_DEFAULT = 253
* RT_TABLE_MAIN = 254
* RT_TABLE_LOCAL = 255
* RT_TABLE_MAX = 0xFFFFFFFF
*
* Synonimous attribute: RTA_TABLE.
*/
printf("table=%u ", rm->rtm_table);
/* type:
* RTN_UNSPEC = 0
* RTN_UNICAST = 1
* RTN_LOCAL = 2
* RTN_BROADCAST = 3
* RTN_ANYCAST = 4
* RTN_MULTICAST = 5
* RTN_BLACKHOLE = 6
* RTN_UNREACHABLE = 7
* RTN_PROHIBIT = 8
* RTN_THROW = 9
* RTN_NAT = 10
* RTN_XRESOLVE = 11
* __RTN_MAX = 12
*/
printf("type=%u ", rm->rtm_type);
/* scope:
* RT_SCOPE_UNIVERSE = 0 : everywhere in the universe
*
* ... user defined values ...
*
* RT_SCOPE_SITE = 200
* RT_SCOPE_LINK = 253 : destination attached to link
* RT_SCOPE_HOST = 254 : local address
* RT_SCOPE_NOWHERE = 255 : not existing destination
*/
printf("scope=%u ", rm->rtm_scope);
/* protocol:
* RTPROT_UNSPEC = 0
* RTPROT_REDIRECT = 1
* RTPROT_KERNEL = 2 : route installed by kernel
* RTPROT_BOOT = 3 : route installed during boot
* RTPROT_STATIC = 4 : route installed by administrator
*
* Values >= RTPROT_STATIC are not interpreted by kernel, they are
* just user-defined.
*/
printf("proto=%u ", rm->rtm_protocol);
/* flags:
* RTM_F_NOTIFY = 0x100: notify user of route change
* RTM_F_CLONED = 0x200: this route is cloned
* RTM_F_EQUALIZE = 0x400: Multipath equalizer: NI
* RTM_F_PREFIX = 0x800: Prefix addresses
*/
printf("flags=%x ", rm->rtm_flags);
switch(rm->rtm_family) {
case AF_INET:
mnl_attr_parse(nlh, sizeof(*rm), data_ipv4_attr_cb, tb);
attributes_show_ipv4(tb);
break;
case AF_INET6:
mnl_attr_parse(nlh, sizeof(*rm), data_ipv6_attr_cb, tb);
attributes_show_ipv6(tb);
break;
}
printf("\n");
return MNL_CB_OK;
}
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
int ret;
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
perror("mnl_socket_open");
exit(EXIT_FAILURE);
}
if (mnl_socket_bind(nl, RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE,
MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0) {
ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
if (ret <= MNL_CB_STOP)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1) {
perror("error");
exit(EXIT_FAILURE);
}
mnl_socket_close(nl);
return 0;
}

View File

@@ -1 +0,0 @@
SUBDIRS = libmnl linux

View File

@@ -1 +0,0 @@
pkginclude_HEADERS = libmnl.h

View File

@@ -1,202 +0,0 @@
#ifndef _LIBMNL_H_
#define _LIBMNL_H_
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/socket.h> /* for sa_family_t */
#include <linux/netlink.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Netlink socket API
*/
#define MNL_SOCKET_AUTOPID 0
#define MNL_SOCKET_BUFFER_SIZE (sysconf(_SC_PAGESIZE) < 8192L ? sysconf(_SC_PAGESIZE) : 8192L)
#define MNL_SOCKET_DUMP_SIZE 32768
struct mnl_socket;
extern struct mnl_socket *mnl_socket_open(int bus);
extern struct mnl_socket *mnl_socket_open2(int bus, int flags);
extern struct mnl_socket *mnl_socket_fdopen(int fd);
extern int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid);
extern int mnl_socket_close(struct mnl_socket *nl);
extern int mnl_socket_get_fd(const struct mnl_socket *nl);
extern unsigned int mnl_socket_get_portid(const struct mnl_socket *nl);
extern ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz);
extern ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz);
extern int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len);
extern int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len);
/*
* Netlink message API
*/
#define MNL_ALIGNTO 4
#define MNL_ALIGN(len) (((len)+MNL_ALIGNTO-1) & ~(MNL_ALIGNTO-1))
#define MNL_NLMSG_HDRLEN MNL_ALIGN(sizeof(struct nlmsghdr))
extern size_t mnl_nlmsg_size(size_t len);
extern size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh);
/* Netlink message header builder */
extern struct nlmsghdr *mnl_nlmsg_put_header(void *buf);
extern void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size);
/* Netlink message iterators */
extern bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len);
extern struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len);
/* Netlink sequence tracking */
extern bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq);
/* Netlink portID checking */
extern bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid);
/* Netlink message getters */
extern void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh);
extern void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset);
extern void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh);
/* Netlink message printer */
extern void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen, size_t extra_header_size);
/* Message batch helpers */
struct mnl_nlmsg_batch;
extern struct mnl_nlmsg_batch *mnl_nlmsg_batch_start(void *buf, size_t bufsiz);
extern bool mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b);
extern void mnl_nlmsg_batch_stop(struct mnl_nlmsg_batch *b);
extern size_t mnl_nlmsg_batch_size(struct mnl_nlmsg_batch *b);
extern void mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b);
extern void *mnl_nlmsg_batch_head(struct mnl_nlmsg_batch *b);
extern void *mnl_nlmsg_batch_current(struct mnl_nlmsg_batch *b);
extern bool mnl_nlmsg_batch_is_empty(struct mnl_nlmsg_batch *b);
/*
* Netlink attributes API
*/
#define MNL_ATTR_HDRLEN MNL_ALIGN(sizeof(struct nlattr))
/* TLV attribute getters */
extern uint16_t mnl_attr_get_type(const struct nlattr *attr);
extern uint16_t mnl_attr_get_len(const struct nlattr *attr);
extern uint16_t mnl_attr_get_payload_len(const struct nlattr *attr);
extern void *mnl_attr_get_payload(const struct nlattr *attr);
extern uint8_t mnl_attr_get_u8(const struct nlattr *attr);
extern uint16_t mnl_attr_get_u16(const struct nlattr *attr);
extern uint32_t mnl_attr_get_u32(const struct nlattr *attr);
extern uint64_t mnl_attr_get_u64(const struct nlattr *attr);
extern const char *mnl_attr_get_str(const struct nlattr *attr);
/* TLV attribute putters */
extern void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data);
extern void mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type, uint8_t data);
extern void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data);
extern void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data);
extern void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data);
extern void mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data);
extern void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data);
/* TLV attribute putters with buffer boundary checkings */
extern bool mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, size_t len, const void *data);
extern bool mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint8_t data);
extern bool mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint16_t data);
extern bool mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint32_t data);
extern bool mnl_attr_put_u64_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint64_t data);
extern bool mnl_attr_put_str_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data);
extern bool mnl_attr_put_strz_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data);
/* TLV attribute nesting */
extern struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type);
extern struct nlattr *mnl_attr_nest_start_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type);
extern void mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start);
extern void mnl_attr_nest_cancel(struct nlmsghdr *nlh, struct nlattr *start);
/* TLV validation */
extern int mnl_attr_type_valid(const struct nlattr *attr, uint16_t maxtype);
enum mnl_attr_data_type {
MNL_TYPE_UNSPEC,
MNL_TYPE_U8,
MNL_TYPE_U16,
MNL_TYPE_U32,
MNL_TYPE_U64,
MNL_TYPE_STRING,
MNL_TYPE_FLAG,
MNL_TYPE_MSECS,
MNL_TYPE_NESTED,
MNL_TYPE_NESTED_COMPAT,
MNL_TYPE_NUL_STRING,
MNL_TYPE_BINARY,
MNL_TYPE_MAX,
};
extern int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type);
extern int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t len);
/* TLV iterators */
extern bool mnl_attr_ok(const struct nlattr *attr, int len);
extern struct nlattr *mnl_attr_next(const struct nlattr *attr);
#define mnl_attr_for_each(attr, nlh, offset) \
for ((attr) = mnl_nlmsg_get_payload_offset((nlh), (offset)); \
mnl_attr_ok((attr), (char *)mnl_nlmsg_get_payload_tail(nlh) - (char *)(attr)); \
(attr) = mnl_attr_next(attr))
#define mnl_attr_for_each_nested(attr, nest) \
for ((attr) = mnl_attr_get_payload(nest); \
mnl_attr_ok((attr), (char *)mnl_attr_get_payload(nest) + mnl_attr_get_payload_len(nest) - (char *)(attr)); \
(attr) = mnl_attr_next(attr))
#define mnl_attr_for_each_payload(payload, payload_size) \
for ((attr) = (payload); \
mnl_attr_ok((attr), (char *)(payload) + payload_size - (char *)(attr)); \
(attr) = mnl_attr_next(attr))
/* TLV callback-based attribute parsers */
typedef int (*mnl_attr_cb_t)(const struct nlattr *attr, void *data);
extern int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data);
extern int mnl_attr_parse_nested(const struct nlattr *attr, mnl_attr_cb_t cb, void *data);
extern int mnl_attr_parse_payload(const void *payload, size_t payload_len, mnl_attr_cb_t cb, void *data);
/*
* callback API
*/
#define MNL_CB_ERROR -1
#define MNL_CB_STOP 0
#define MNL_CB_OK 1
typedef int (*mnl_cb_t)(const struct nlmsghdr *nlh, void *data);
extern int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq,
unsigned int portid, mnl_cb_t cb_data, void *data);
extern int mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq,
unsigned int portid, mnl_cb_t cb_data, void *data,
const mnl_cb_t *cb_ctl_array,
unsigned int cb_ctl_array_len);
/*
* other declarations
*/
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
#ifndef MNL_ARRAY_SIZE
#define MNL_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@@ -1,2 +0,0 @@
SUBDIRS = can netfilter
noinst_HEADERS = can.h netlink.h socket.h

View File

@@ -1,298 +0,0 @@
/* SPDX-License-Identifier: ((GPL-2.0-only WITH Linux-syscall-note) OR BSD-3-Clause) */
/*
* linux/can.h
*
* Definitions for CAN network layer (socket addr / CAN frame / CAN filter)
*
* Authors: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
* Urs Thuermann <urs.thuermann@volkswagen.de>
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Volkswagen nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* Alternatively, provided that this notice is retained in full, this
* software may be distributed under the terms of the GNU General
* Public License ("GPL") version 2, in which case the provisions of the
* GPL apply INSTEAD OF those given above.
*
* The provided data structures and external interfaces from this code
* are not restricted to be used by modules with a GPL compatible license.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#ifndef _UAPI_CAN_H
#define _UAPI_CAN_H
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/stddef.h> /* for offsetof */
/* controller area network (CAN) kernel definitions */
/* special address description flags for the CAN_ID */
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
#define CAN_ERR_FLAG 0x20000000U /* error message frame */
/* valid bits in CAN ID for frame formats */
#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
#define CANXL_PRIO_MASK CAN_SFF_MASK /* 11 bit priority mask */
/*
* Controller Area Network Identifier structure
*
* bit 0-28 : CAN identifier (11/29 bit)
* bit 29 : error message frame flag (0 = data frame, 1 = error message)
* bit 30 : remote transmission request flag (1 = rtr frame)
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
*/
typedef __u32 canid_t;
#define CAN_SFF_ID_BITS 11
#define CAN_EFF_ID_BITS 29
#define CANXL_PRIO_BITS CAN_SFF_ID_BITS
/*
* Controller Area Network Error Message Frame Mask structure
*
* bit 0-28 : error class mask (see include/uapi/linux/can/error.h)
* bit 29-31 : set to zero
*/
typedef __u32 can_err_mask_t;
/* CAN payload length and DLC definitions according to ISO 11898-1 */
#define CAN_MAX_DLC 8
#define CAN_MAX_RAW_DLC 15
#define CAN_MAX_DLEN 8
/* CAN FD payload length and DLC definitions according to ISO 11898-7 */
#define CANFD_MAX_DLC 15
#define CANFD_MAX_DLEN 64
/*
* CAN XL payload length and DLC definitions according to ISO 11898-1
* CAN XL DLC ranges from 0 .. 2047 => data length from 1 .. 2048 byte
*/
#define CANXL_MIN_DLC 0
#define CANXL_MAX_DLC 2047
#define CANXL_MAX_DLC_MASK 0x07FF
#define CANXL_MIN_DLEN 1
#define CANXL_MAX_DLEN 2048
/**
* struct can_frame - Classical CAN frame structure (aka CAN 2.0B)
* @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
* @len: CAN frame payload length in byte (0 .. 8)
* @can_dlc: deprecated name for CAN frame payload length in byte (0 .. 8)
* @__pad: padding
* @__res0: reserved / padding
* @len8_dlc: optional DLC value (9 .. 15) at 8 byte payload length
* len8_dlc contains values from 9 .. 15 when the payload length is
* 8 bytes but the DLC value (see ISO 11898-1) is greater then 8.
* CAN_CTRLMODE_CC_LEN8_DLC flag has to be enabled in CAN driver.
* @data: CAN frame payload (up to 8 byte)
*/
struct can_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
union {
/* CAN frame payload length in byte (0 .. CAN_MAX_DLEN)
* was previously named can_dlc so we need to carry that
* name for legacy support
*/
__u8 len;
__u8 can_dlc; /* deprecated */
} __attribute__((packed)); /* disable padding added in some ABIs */
__u8 __pad; /* padding */
__u8 __res0; /* reserved / padding */
__u8 len8_dlc; /* optional DLC for 8 byte payload length (9 .. 15) */
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};
/*
* defined bits for canfd_frame.flags
*
* The use of struct canfd_frame implies the FD Frame (FDF) bit to
* be set in the CAN frame bitstream on the wire. The FDF bit switch turns
* the CAN controllers bitstream processor into the CAN FD mode which creates
* two new options within the CAN FD frame specification:
*
* Bit Rate Switch - to indicate a second bitrate is/was used for the payload
* Error State Indicator - represents the error state of the transmitting node
*
* As the CANFD_ESI bit is internally generated by the transmitting CAN
* controller only the CANFD_BRS bit is relevant for real CAN controllers when
* building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make
* sense for virtual CAN interfaces to test applications with echoed frames.
*
* The struct can_frame and struct canfd_frame intentionally share the same
* layout to be able to write CAN frame content into a CAN FD frame structure.
* When this is done the former differentiation via CAN_MTU / CANFD_MTU gets
* lost. CANFD_FDF allows programmers to mark CAN FD frames in the case of
* using struct canfd_frame for mixed CAN / CAN FD content (dual use).
* Since the introduction of CAN XL the CANFD_FDF flag is set in all CAN FD
* frame structures provided by the CAN subsystem of the Linux kernel.
*/
#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
#define CANFD_FDF 0x04 /* mark CAN FD for dual use of struct canfd_frame */
/**
* struct canfd_frame - CAN flexible data rate frame structure
* @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
* @len: frame payload length in byte (0 .. CANFD_MAX_DLEN)
* @flags: additional flags for CAN FD
* @__res0: reserved / padding
* @__res1: reserved / padding
* @data: CAN FD frame payload (up to CANFD_MAX_DLEN byte)
*/
struct canfd_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 len; /* frame payload length in byte */
__u8 flags; /* additional flags for CAN FD */
__u8 __res0; /* reserved / padding */
__u8 __res1; /* reserved / padding */
__u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
};
/*
* defined bits for canxl_frame.flags
*
* The canxl_frame.flags element contains two bits CANXL_XLF and CANXL_SEC
* and shares the relative position of the struct can[fd]_frame.len element.
* The CANXL_XLF bit ALWAYS needs to be set to indicate a valid CAN XL frame.
* As a side effect setting this bit intentionally breaks the length checks
* for Classical CAN and CAN FD frames.
*
* Undefined bits in canxl_frame.flags are reserved and shall be set to zero.
*/
#define CANXL_XLF 0x80 /* mandatory CAN XL frame flag (must always be set!) */
#define CANXL_SEC 0x01 /* Simple Extended Content (security/segmentation) */
/**
* struct canxl_frame - CAN with e'X'tended frame 'L'ength frame structure
* @prio: 11 bit arbitration priority with zero'ed CAN_*_FLAG flags
* @flags: additional flags for CAN XL
* @sdt: SDU (service data unit) type
* @len: frame payload length in byte (CANXL_MIN_DLEN .. CANXL_MAX_DLEN)
* @af: acceptance field
* @data: CAN XL frame payload (CANXL_MIN_DLEN .. CANXL_MAX_DLEN byte)
*
* @prio shares the same position as @can_id from struct can[fd]_frame.
*/
struct canxl_frame {
canid_t prio; /* 11 bit priority for arbitration (canid_t) */
__u8 flags; /* additional flags for CAN XL */
__u8 sdt; /* SDU (service data unit) type */
__u16 len; /* frame payload length in byte */
__u32 af; /* acceptance field */
__u8 data[CANXL_MAX_DLEN];
};
#define CAN_MTU (sizeof(struct can_frame))
#define CANFD_MTU (sizeof(struct canfd_frame))
#define CANXL_MTU (sizeof(struct canxl_frame))
#define CANXL_HDR_SIZE (offsetof(struct canxl_frame, data))
#define CANXL_MIN_MTU (CANXL_HDR_SIZE + 64)
#define CANXL_MAX_MTU CANXL_MTU
/* particular protocols of the protocol family PF_CAN */
#define CAN_RAW 1 /* RAW sockets */
#define CAN_BCM 2 /* Broadcast Manager */
#define CAN_TP16 3 /* VAG Transport Protocol v1.6 */
#define CAN_TP20 4 /* VAG Transport Protocol v2.0 */
#define CAN_MCNET 5 /* Bosch MCNet */
#define CAN_ISOTP 6 /* ISO 15765-2 Transport Protocol */
#define CAN_J1939 7 /* SAE J1939 */
#define CAN_NPROTO 8
#define SOL_CAN_BASE 100
/*
* This typedef was introduced in Linux v3.1-rc2
* (commit 6602a4b net: Make userland include of netlink.h more sane)
* in <linux/socket.h>. It must be duplicated here to make the CAN
* headers self-contained.
*/
typedef unsigned short __kernel_sa_family_t;
/**
* struct sockaddr_can - the sockaddr structure for CAN sockets
* @can_family: address family number AF_CAN.
* @can_ifindex: CAN network interface index.
* @can_addr: protocol specific address information
*/
struct sockaddr_can {
__kernel_sa_family_t can_family;
int can_ifindex;
union {
/* transport protocol class address information (e.g. ISOTP) */
struct { canid_t rx_id, tx_id; } tp;
/* J1939 address information */
struct {
/* 8 byte name when using dynamic addressing */
__u64 name;
/* pgn:
* 8 bit: PS in PDU2 case, else 0
* 8 bit: PF
* 1 bit: DP
* 1 bit: reserved
*/
__u32 pgn;
/* 1 byte address */
__u8 addr;
} j1939;
/* reserved for future CAN protocols address information */
} can_addr;
};
/**
* struct can_filter - CAN ID based filter in can_register().
* @can_id: relevant bits of CAN ID which are not masked out.
* @can_mask: CAN mask (see description)
*
* Description:
* A filter matches, when
*
* <received_can_id> & mask == can_id & mask
*
* The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
* filter for error message frames (CAN_ERR_FLAG bit set in mask).
*/
struct can_filter {
canid_t can_id;
canid_t can_mask;
};
#define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */
#endif /* !_UAPI_CAN_H */

View File

@@ -1 +0,0 @@
noinst_HEADERS = netlink.h

View File

@@ -1,185 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
* linux/can/netlink.h
*
* Definitions for the CAN netlink interface
*
* Copyright (c) 2009 Wolfgang Grandegger <wg@grandegger.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the version 2 of the GNU General Public License
* 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.
*/
#ifndef _UAPI_CAN_NETLINK_H
#define _UAPI_CAN_NETLINK_H
#include <linux/types.h>
/*
* CAN bit-timing parameters
*
* For further information, please read chapter "8 BIT TIMING
* REQUIREMENTS" of the "Bosch CAN Specification version 2.0"
* at http://www.semiconductors.bosch.de/pdf/can2spec.pdf.
*/
struct can_bittiming {
__u32 bitrate; /* Bit-rate in bits/second */
__u32 sample_point; /* Sample point in one-tenth of a percent */
__u32 tq; /* Time quanta (TQ) in nanoseconds */
__u32 prop_seg; /* Propagation segment in TQs */
__u32 phase_seg1; /* Phase buffer segment 1 in TQs */
__u32 phase_seg2; /* Phase buffer segment 2 in TQs */
__u32 sjw; /* Synchronisation jump width in TQs */
__u32 brp; /* Bit-rate prescaler */
};
/*
* CAN hardware-dependent bit-timing constant
*
* Used for calculating and checking bit-timing parameters
*/
struct can_bittiming_const {
char name[16]; /* Name of the CAN controller hardware */
__u32 tseg1_min; /* Time segment 1 = prop_seg + phase_seg1 */
__u32 tseg1_max;
__u32 tseg2_min; /* Time segment 2 = phase_seg2 */
__u32 tseg2_max;
__u32 sjw_max; /* Synchronisation jump width */
__u32 brp_min; /* Bit-rate prescaler */
__u32 brp_max;
__u32 brp_inc;
};
/*
* CAN clock parameters
*/
struct can_clock {
__u32 freq; /* CAN system clock frequency in Hz */
};
/*
* CAN operational and error states
*/
enum can_state {
CAN_STATE_ERROR_ACTIVE = 0, /* RX/TX error count < 96 */
CAN_STATE_ERROR_WARNING, /* RX/TX error count < 128 */
CAN_STATE_ERROR_PASSIVE, /* RX/TX error count < 256 */
CAN_STATE_BUS_OFF, /* RX/TX error count >= 256 */
CAN_STATE_STOPPED, /* Device is stopped */
CAN_STATE_SLEEPING, /* Device is sleeping */
CAN_STATE_MAX
};
/*
* CAN bus error counters
*/
struct can_berr_counter {
__u16 txerr;
__u16 rxerr;
};
/*
* CAN controller mode
*/
struct can_ctrlmode {
__u32 mask;
__u32 flags;
};
#define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */
#define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */
#define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */
#define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */
#define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */
#define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */
#define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */
#define CAN_CTRLMODE_FD_NON_ISO 0x80 /* CAN FD in non-ISO mode */
#define CAN_CTRLMODE_CC_LEN8_DLC 0x100 /* Classic CAN DLC option */
#define CAN_CTRLMODE_TDC_AUTO 0x200 /* CAN transiver automatically calculates TDCV */
#define CAN_CTRLMODE_TDC_MANUAL 0x400 /* TDCV is manually set up by user */
/*
* CAN device statistics
*/
struct can_device_stats {
__u32 bus_error; /* Bus errors */
__u32 error_warning; /* Changes to error warning state */
__u32 error_passive; /* Changes to error passive state */
__u32 bus_off; /* Changes to bus off state */
__u32 arbitration_lost; /* Arbitration lost errors */
__u32 restarts; /* CAN controller re-starts */
};
/*
* CAN netlink interface
*/
enum {
IFLA_CAN_UNSPEC,
IFLA_CAN_BITTIMING,
IFLA_CAN_BITTIMING_CONST,
IFLA_CAN_CLOCK,
IFLA_CAN_STATE,
IFLA_CAN_CTRLMODE,
IFLA_CAN_RESTART_MS,
IFLA_CAN_RESTART,
IFLA_CAN_BERR_COUNTER,
IFLA_CAN_DATA_BITTIMING,
IFLA_CAN_DATA_BITTIMING_CONST,
IFLA_CAN_TERMINATION,
IFLA_CAN_TERMINATION_CONST,
IFLA_CAN_BITRATE_CONST,
IFLA_CAN_DATA_BITRATE_CONST,
IFLA_CAN_BITRATE_MAX,
IFLA_CAN_TDC,
IFLA_CAN_CTRLMODE_EXT,
/* add new constants above here */
__IFLA_CAN_MAX,
IFLA_CAN_MAX = __IFLA_CAN_MAX - 1
};
/*
* CAN FD Transmitter Delay Compensation (TDC)
*
* Please refer to struct can_tdc_const and can_tdc in
* include/linux/can/bittiming.h for further details.
*/
enum {
IFLA_CAN_TDC_UNSPEC,
IFLA_CAN_TDC_TDCV_MIN, /* u32 */
IFLA_CAN_TDC_TDCV_MAX, /* u32 */
IFLA_CAN_TDC_TDCO_MIN, /* u32 */
IFLA_CAN_TDC_TDCO_MAX, /* u32 */
IFLA_CAN_TDC_TDCF_MIN, /* u32 */
IFLA_CAN_TDC_TDCF_MAX, /* u32 */
IFLA_CAN_TDC_TDCV, /* u32 */
IFLA_CAN_TDC_TDCO, /* u32 */
IFLA_CAN_TDC_TDCF, /* u32 */
/* add new constants above here */
__IFLA_CAN_TDC,
IFLA_CAN_TDC_MAX = __IFLA_CAN_TDC - 1
};
/*
* IFLA_CAN_CTRLMODE_EXT nest: controller mode extended parameters
*/
enum {
IFLA_CAN_CTRLMODE_UNSPEC,
IFLA_CAN_CTRLMODE_SUPPORTED, /* u32 */
/* add new constants above here */
__IFLA_CAN_CTRLMODE,
IFLA_CAN_CTRLMODE_MAX = __IFLA_CAN_CTRLMODE - 1
};
/* u16 termination range: 1..65535 Ohms */
#define CAN_TERMINATION_DISABLED 0
#endif /* !_UAPI_CAN_NETLINK_H */

View File

@@ -1 +0,0 @@
noinst_HEADERS = nfnetlink_conntrack.h

View File

@@ -1,252 +0,0 @@
#ifndef _IPCONNTRACK_NETLINK_H
#define _IPCONNTRACK_NETLINK_H
#include <linux/netfilter/nfnetlink.h>
enum cntl_msg_types {
IPCTNL_MSG_CT_NEW,
IPCTNL_MSG_CT_GET,
IPCTNL_MSG_CT_DELETE,
IPCTNL_MSG_CT_GET_CTRZERO,
IPCTNL_MSG_CT_GET_STATS_CPU,
IPCTNL_MSG_CT_GET_STATS,
IPCTNL_MSG_CT_GET_DYING,
IPCTNL_MSG_CT_GET_UNCONFIRMED,
IPCTNL_MSG_MAX
};
enum ctnl_exp_msg_types {
IPCTNL_MSG_EXP_NEW,
IPCTNL_MSG_EXP_GET,
IPCTNL_MSG_EXP_DELETE,
IPCTNL_MSG_EXP_GET_STATS_CPU,
IPCTNL_MSG_EXP_MAX
};
enum ctattr_type {
CTA_UNSPEC,
CTA_TUPLE_ORIG,
CTA_TUPLE_REPLY,
CTA_STATUS,
CTA_PROTOINFO,
CTA_HELP,
CTA_NAT_SRC,
#define CTA_NAT CTA_NAT_SRC /* backwards compatibility */
CTA_TIMEOUT,
CTA_MARK,
CTA_COUNTERS_ORIG,
CTA_COUNTERS_REPLY,
CTA_USE,
CTA_ID,
CTA_NAT_DST,
CTA_TUPLE_MASTER,
CTA_NAT_SEQ_ADJ_ORIG,
CTA_NAT_SEQ_ADJ_REPLY,
CTA_SECMARK, /* obsolete */
CTA_ZONE,
CTA_SECCTX,
CTA_TIMESTAMP,
CTA_MARK_MASK,
CTA_LABELS,
CTA_LABELS_MASK,
__CTA_MAX
};
#define CTA_MAX (__CTA_MAX - 1)
enum ctattr_tuple {
CTA_TUPLE_UNSPEC,
CTA_TUPLE_IP,
CTA_TUPLE_PROTO,
__CTA_TUPLE_MAX
};
#define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1)
enum ctattr_ip {
CTA_IP_UNSPEC,
CTA_IP_V4_SRC,
CTA_IP_V4_DST,
CTA_IP_V6_SRC,
CTA_IP_V6_DST,
__CTA_IP_MAX
};
#define CTA_IP_MAX (__CTA_IP_MAX - 1)
enum ctattr_l4proto {
CTA_PROTO_UNSPEC,
CTA_PROTO_NUM,
CTA_PROTO_SRC_PORT,
CTA_PROTO_DST_PORT,
CTA_PROTO_ICMP_ID,
CTA_PROTO_ICMP_TYPE,
CTA_PROTO_ICMP_CODE,
CTA_PROTO_ICMPV6_ID,
CTA_PROTO_ICMPV6_TYPE,
CTA_PROTO_ICMPV6_CODE,
__CTA_PROTO_MAX
};
#define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)
enum ctattr_protoinfo {
CTA_PROTOINFO_UNSPEC,
CTA_PROTOINFO_TCP,
CTA_PROTOINFO_DCCP,
CTA_PROTOINFO_SCTP,
__CTA_PROTOINFO_MAX
};
#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
enum ctattr_protoinfo_tcp {
CTA_PROTOINFO_TCP_UNSPEC,
CTA_PROTOINFO_TCP_STATE,
CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
CTA_PROTOINFO_TCP_WSCALE_REPLY,
CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
CTA_PROTOINFO_TCP_FLAGS_REPLY,
__CTA_PROTOINFO_TCP_MAX
};
#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
enum ctattr_protoinfo_dccp {
CTA_PROTOINFO_DCCP_UNSPEC,
CTA_PROTOINFO_DCCP_STATE,
CTA_PROTOINFO_DCCP_ROLE,
CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
__CTA_PROTOINFO_DCCP_MAX,
};
#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1)
enum ctattr_protoinfo_sctp {
CTA_PROTOINFO_SCTP_UNSPEC,
CTA_PROTOINFO_SCTP_STATE,
CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
CTA_PROTOINFO_SCTP_VTAG_REPLY,
__CTA_PROTOINFO_SCTP_MAX
};
#define CTA_PROTOINFO_SCTP_MAX (__CTA_PROTOINFO_SCTP_MAX - 1)
enum ctattr_counters {
CTA_COUNTERS_UNSPEC,
CTA_COUNTERS_PACKETS, /* 64bit counters */
CTA_COUNTERS_BYTES, /* 64bit counters */
CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */
CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */
__CTA_COUNTERS_MAX
};
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
enum ctattr_tstamp {
CTA_TIMESTAMP_UNSPEC,
CTA_TIMESTAMP_START,
CTA_TIMESTAMP_STOP,
__CTA_TIMESTAMP_MAX
};
#define CTA_TIMESTAMP_MAX (__CTA_TIMESTAMP_MAX - 1)
enum ctattr_nat {
CTA_NAT_UNSPEC,
CTA_NAT_V4_MINIP,
#define CTA_NAT_MINIP CTA_NAT_V4_MINIP
CTA_NAT_V4_MAXIP,
#define CTA_NAT_MAXIP CTA_NAT_V4_MAXIP
CTA_NAT_PROTO,
CTA_NAT_V6_MINIP,
CTA_NAT_V6_MAXIP,
__CTA_NAT_MAX
};
#define CTA_NAT_MAX (__CTA_NAT_MAX - 1)
enum ctattr_protonat {
CTA_PROTONAT_UNSPEC,
CTA_PROTONAT_PORT_MIN,
CTA_PROTONAT_PORT_MAX,
__CTA_PROTONAT_MAX
};
#define CTA_PROTONAT_MAX (__CTA_PROTONAT_MAX - 1)
enum ctattr_natseq {
CTA_NAT_SEQ_UNSPEC,
CTA_NAT_SEQ_CORRECTION_POS,
CTA_NAT_SEQ_OFFSET_BEFORE,
CTA_NAT_SEQ_OFFSET_AFTER,
__CTA_NAT_SEQ_MAX
};
#define CTA_NAT_SEQ_MAX (__CTA_NAT_SEQ_MAX - 1)
enum ctattr_expect {
CTA_EXPECT_UNSPEC,
CTA_EXPECT_MASTER,
CTA_EXPECT_TUPLE,
CTA_EXPECT_MASK,
CTA_EXPECT_TIMEOUT,
CTA_EXPECT_ID,
CTA_EXPECT_HELP_NAME,
CTA_EXPECT_ZONE,
CTA_EXPECT_FLAGS,
CTA_EXPECT_CLASS,
CTA_EXPECT_NAT,
CTA_EXPECT_FN,
__CTA_EXPECT_MAX
};
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
enum ctattr_expect_nat {
CTA_EXPECT_NAT_UNSPEC,
CTA_EXPECT_NAT_DIR,
CTA_EXPECT_NAT_TUPLE,
__CTA_EXPECT_NAT_MAX
};
#define CTA_EXPECT_NAT_MAX (__CTA_EXPECT_NAT_MAX - 1)
enum ctattr_help {
CTA_HELP_UNSPEC,
CTA_HELP_NAME,
CTA_HELP_INFO,
__CTA_HELP_MAX
};
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
enum ctattr_secctx {
CTA_SECCTX_UNSPEC,
CTA_SECCTX_NAME,
__CTA_SECCTX_MAX
};
#define CTA_SECCTX_MAX (__CTA_SECCTX_MAX - 1)
enum ctattr_stats_cpu {
CTA_STATS_UNSPEC,
CTA_STATS_SEARCHED,
CTA_STATS_FOUND,
CTA_STATS_NEW,
CTA_STATS_INVALID,
CTA_STATS_IGNORE,
CTA_STATS_DELETE,
CTA_STATS_DELETE_LIST,
CTA_STATS_INSERT,
CTA_STATS_INSERT_FAILED,
CTA_STATS_DROP,
CTA_STATS_EARLY_DROP,
CTA_STATS_ERROR,
CTA_STATS_SEARCH_RESTART,
__CTA_STATS_MAX,
};
#define CTA_STATS_MAX (__CTA_STATS_MAX - 1)
enum ctattr_stats_global {
CTA_STATS_GLOBAL_UNSPEC,
CTA_STATS_GLOBAL_ENTRIES,
__CTA_STATS_GLOBAL_MAX,
};
#define CTA_STATS_GLOBAL_MAX (__CTA_STATS_GLOBAL_MAX - 1)
enum ctattr_expect_stats {
CTA_STATS_EXP_UNSPEC,
CTA_STATS_EXP_NEW,
CTA_STATS_EXP_CREATE,
CTA_STATS_EXP_DELETE,
__CTA_STATS_EXP_MAX,
};
#define CTA_STATS_EXP_MAX (__CTA_STATS_EXP_MAX - 1)
#endif /* _IPCONNTRACK_NETLINK_H */

View File

@@ -1,153 +0,0 @@
#ifndef __LINUX_NETLINK_H
#define __LINUX_NETLINK_H
#include <linux/socket.h> /* for __kernel_sa_family_t */
#include <linux/types.h>
#define NETLINK_ROUTE 0 /* Routing/device hook */
#define NETLINK_UNUSED 1 /* Unused number */
#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
#define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */
#define NETLINK_SOCK_DIAG 4 /* socket monitoring */
#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */
#define NETLINK_XFRM 6 /* ipsec */
#define NETLINK_SELINUX 7 /* SELinux event notifications */
#define NETLINK_ISCSI 8 /* Open-iSCSI */
#define NETLINK_AUDIT 9 /* auditing */
#define NETLINK_FIB_LOOKUP 10
#define NETLINK_CONNECTOR 11
#define NETLINK_NETFILTER 12 /* netfilter subsystem */
#define NETLINK_IP6_FW 13
#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
#define NETLINK_GENERIC 16
/* leave room for NETLINK_DM (DM Events) */
#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */
#define NETLINK_ECRYPTFS 19
#define NETLINK_RDMA 20
#define NETLINK_CRYPTO 21 /* Crypto layer */
#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG
#define MAX_LINKS 32
struct sockaddr_nl {
__kernel_sa_family_t nl_family; /* AF_NETLINK */
unsigned short nl_pad; /* zero */
__u32 nl_pid; /* port ID */
__u32 nl_groups; /* multicast groups mask */
};
struct nlmsghdr {
__u32 nlmsg_len; /* Length of message including header */
__u16 nlmsg_type; /* Message content */
__u16 nlmsg_flags; /* Additional flags */
__u32 nlmsg_seq; /* Sequence number */
__u32 nlmsg_pid; /* Sending process port ID */
};
/* Flags values */
#define NLM_F_REQUEST 1 /* It is request message. */
#define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */
#define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
#define NLM_F_ECHO 8 /* Echo this request */
#define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */
/* Modifiers to GET request */
#define NLM_F_ROOT 0x100 /* specify tree root */
#define NLM_F_MATCH 0x200 /* return all matching */
#define NLM_F_ATOMIC 0x400 /* atomic GET */
#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
/* Modifiers to NEW request */
#define NLM_F_REPLACE 0x100 /* Override existing */
#define NLM_F_EXCL 0x200 /* Do not touch, if it exists */
#define NLM_F_CREATE 0x400 /* Create, if it does not exist */
#define NLM_F_APPEND 0x800 /* Add to end of list */
/*
4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL
4.4BSD CHANGE NLM_F_REPLACE
True CHANGE NLM_F_CREATE|NLM_F_REPLACE
Append NLM_F_CREATE
Check NLM_F_EXCL
*/
#define NLMSG_ALIGNTO 4U
#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
(struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
(nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
(nlh)->nlmsg_len <= (len))
#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
#define NLMSG_NOOP 0x1 /* Nothing. */
#define NLMSG_ERROR 0x2 /* Error */
#define NLMSG_DONE 0x3 /* End of a dump */
#define NLMSG_OVERRUN 0x4 /* Data lost */
#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
struct nlmsgerr {
int error;
struct nlmsghdr msg;
};
#define NETLINK_ADD_MEMBERSHIP 1
#define NETLINK_DROP_MEMBERSHIP 2
#define NETLINK_PKTINFO 3
#define NETLINK_BROADCAST_ERROR 4
#define NETLINK_NO_ENOBUFS 5
struct nl_pktinfo {
__u32 group;
};
#define NET_MAJOR 36 /* Major 36 is reserved for networking */
enum {
NETLINK_UNCONNECTED = 0,
NETLINK_CONNECTED,
};
/*
* <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
* +---------------------+- - -+- - - - - - - - - -+- - -+
* | Header | Pad | Payload | Pad |
* | (struct nlattr) | ing | | ing |
* +---------------------+- - -+- - - - - - - - - -+- - -+
* <-------------- nlattr->nla_len -------------->
*/
struct nlattr {
__u16 nla_len;
__u16 nla_type;
};
/*
* nla_type (16 bits)
* +---+---+-------------------------------+
* | N | O | Attribute Type |
* +---+---+-------------------------------+
* N := Carries nested attributes
* O := Payload stored in network byte order
*
* Note: The N and O flag are mutually exclusive.
*/
#define NLA_F_NESTED (1 << 15)
#define NLA_F_NET_BYTEORDER (1 << 14)
#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
#define NLA_ALIGNTO 4
#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
#endif /* __LINUX_NETLINK_H */

Some files were not shown because too many files have changed in this diff Show More