network: Add virtio-net dependencies

The newly added virtio-net implementation needs to interact with TAP
interfaces and MAC addresses, which is the reason why it is easier
to rely on existing packages net_util and net_gen.

One more thing, both net_util and net_gen could be trimmed down,
based on using only the things we need from cloud-hypervisor.

Both net_util, net_gen and sys_util are based on Firecracker
commit d4a89cdc0bd2867f821e3678328dabad6dd8b767.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2019-05-07 22:28:02 -07:00 committed by Samuel Ortiz
parent 6d27cfb3b6
commit 53f5295454
11 changed files with 5776 additions and 43 deletions

118
Cargo.lock generated
View File

@ -11,7 +11,7 @@ dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kvm-bindings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kvm-ioctls 0.1.0 (git+https://github.com/rust-vmm/kvm-ioctls)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"vm-memory 0.1.0 (git+https://github.com/rust-vmm/vm-memory)",
]
@ -24,9 +24,9 @@ name = "atty"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -90,7 +90,7 @@ version = "0.1.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"epoll 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"vm-memory 0.1.0 (git+https://github.com/rust-vmm/vm-memory)",
"vmm-sys-util 0.1.0 (git+https://github.com/sameo/vmm-sys-util)",
]
@ -101,7 +101,7 @@ version = "4.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -120,12 +120,12 @@ version = "0.1.0"
source = "git+https://github.com/rust-vmm/kvm-ioctls#e0d6aefd28097446ee8fcd66160c583f165b5116"
dependencies = [
"kvm-bindings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.2.48"
version = "0.2.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -144,6 +144,28 @@ dependencies = [
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "net_gen"
version = "0.1.0"
dependencies = [
"vmm-sys-util 0.1.0 (git+https://github.com/sameo/vmm-sys-util)",
]
[[package]]
name = "net_util"
version = "0.1.0"
dependencies = [
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"net_gen 0.1.0",
"serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
"vmm-sys-util 0.1.0 (git+https://github.com/sameo/vmm-sys-util)",
]
[[package]]
name = "numtoa"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pci"
version = "0.1.0"
@ -152,7 +174,7 @@ dependencies = [
"devices 0.1.0",
"kvm-bindings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kvm-ioctls 0.1.0 (git+https://github.com/rust-vmm/kvm-ioctls)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"vm-allocator 0.1.0",
"vm-memory 0.1.0 (git+https://github.com/rust-vmm/vm-memory)",
@ -161,7 +183,7 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "0.4.29"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -172,7 +194,7 @@ name = "qcow"
version = "0.1.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"remain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"vmm-sys-util 0.1.0 (git+https://github.com/sameo/vmm-sys-util)",
@ -183,7 +205,7 @@ name = "quote"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -192,7 +214,7 @@ version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -201,7 +223,7 @@ dependencies = [
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -247,9 +269,9 @@ name = "rand_jitter"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -259,10 +281,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -292,7 +314,7 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.1.51"
version = "0.1.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -300,7 +322,7 @@ name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -308,9 +330,9 @@ name = "remain"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -318,9 +340,14 @@ name = "remove_dir_all"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strsim"
version = "0.6.0"
@ -328,10 +355,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.15.33"
version = "0.15.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -342,20 +369,21 @@ version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "termion"
version = "1.5.1"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -390,7 +418,7 @@ version = "0.1.0"
name = "vm-allocator"
version = "0.1.0"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"vm-memory 0.1.0 (git+https://github.com/rust-vmm/vm-memory)",
]
@ -399,7 +427,7 @@ name = "vm-memory"
version = "0.1.0"
source = "git+https://github.com/rust-vmm/vm-memory#08b24bf6245459f14226f52f19f91ad9648ad8e6"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -409,8 +437,10 @@ dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"devices 0.1.0",
"epoll 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"net_gen 0.1.0",
"net_util 0.1.0",
"pci 0.1.0",
"tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"virtio-bindings 0.1.0",
@ -428,7 +458,7 @@ dependencies = [
"epoll 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kvm-bindings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kvm-ioctls 0.1.0 (git+https://github.com/rust-vmm/kvm-ioctls)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"linux-loader 0.1.0 (git+https://github.com/sameo/linux-loader)",
"pci 0.1.0",
"qcow 0.1.0",
@ -443,12 +473,12 @@ name = "vmm-sys-util"
version = "0.1.0"
source = "git+https://github.com/sameo/vmm-sys-util#766db444eb9ac315ce7139dff9f56e6e9fd2471f"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -479,10 +509,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum kvm-bindings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c223e8703d2eb76d990c5f58e29c85b0f6f50e24b823babde927948e7c71fc03"
"checksum kvm-ioctls 0.1.0 (git+https://github.com/rust-vmm/kvm-ioctls)" = "<none>"
"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047"
"checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6"
"checksum linux-loader 0.1.0 (git+https://github.com/sameo/linux-loader)" = "<none>"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)" = "64c827cea7a7ab30ce4593e5e04d7a11617ad6ece2fa230605a78b00ff965316"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
@ -495,20 +526,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum remain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3bec2543b50be4539fdc27fde082e218cf4c3895358ca77f5c52fe930589e209"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "a72e9b96fa45ce22a4bc23da3858dfccfd60acd28a25bcd328a98fdd6bea43fd"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)" = "ec52cd796e5f01d0067225a5392e70084acc4c0013fa71d55166d38a8b307836"
"checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe"
"checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum vm-memory 0.1.0 (git+https://github.com/rust-vmm/vm-memory)" = "<none>"
"checksum vmm-sys-util 0.1.0 (git+https://github.com/sameo/vmm-sys-util)" = "<none>"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

7
net_gen/Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "net_gen"
version = "0.1.0"
authors = ["The Chromium OS Authors"]
[dependencies]
vmm-sys-util = { git = "https://github.com/sameo/vmm-sys-util" }

599
net_gen/src/if_tun.rs Normal file
View File

@ -0,0 +1,599 @@
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
/* automatically generated by rust-bindgen */
#[repr(C)]
#[derive(Default)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
impl<T> __IncompleteArrayField<T> {
#[inline]
pub fn new() -> Self {
__IncompleteArrayField(::std::marker::PhantomData)
}
#[inline]
pub unsafe fn as_ptr(&self) -> *const T {
::std::mem::transmute(self)
}
#[inline]
pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
::std::mem::transmute(self)
}
#[inline]
pub unsafe fn as_slice(&self, len: usize) -> &[T] {
::std::slice::from_raw_parts(self.as_ptr(), len)
}
#[inline]
pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
}
}
impl<T> ::std::fmt::Debug for __IncompleteArrayField<T> {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
fmt.write_str("__IncompleteArrayField")
}
}
impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
#[inline]
fn clone(&self) -> Self {
Self::new()
}
}
impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
pub const __BITS_PER_LONG: ::std::os::raw::c_uint = 64;
pub const __FD_SETSIZE: ::std::os::raw::c_uint = 1024;
pub const ETH_ALEN: ::std::os::raw::c_uint = 6;
pub const ETH_HLEN: ::std::os::raw::c_uint = 14;
pub const ETH_ZLEN: ::std::os::raw::c_uint = 60;
pub const ETH_DATA_LEN: ::std::os::raw::c_uint = 1500;
pub const ETH_FRAME_LEN: ::std::os::raw::c_uint = 1514;
pub const ETH_FCS_LEN: ::std::os::raw::c_uint = 4;
pub const ETH_P_LOOP: ::std::os::raw::c_uint = 96;
pub const ETH_P_PUP: ::std::os::raw::c_uint = 512;
pub const ETH_P_PUPAT: ::std::os::raw::c_uint = 513;
pub const ETH_P_TSN: ::std::os::raw::c_uint = 8944;
pub const ETH_P_IP: ::std::os::raw::c_uint = 2048;
pub const ETH_P_X25: ::std::os::raw::c_uint = 2053;
pub const ETH_P_ARP: ::std::os::raw::c_uint = 2054;
pub const ETH_P_BPQ: ::std::os::raw::c_uint = 2303;
pub const ETH_P_IEEEPUP: ::std::os::raw::c_uint = 2560;
pub const ETH_P_IEEEPUPAT: ::std::os::raw::c_uint = 2561;
pub const ETH_P_BATMAN: ::std::os::raw::c_uint = 17157;
pub const ETH_P_DEC: ::std::os::raw::c_uint = 24576;
pub const ETH_P_DNA_DL: ::std::os::raw::c_uint = 24577;
pub const ETH_P_DNA_RC: ::std::os::raw::c_uint = 24578;
pub const ETH_P_DNA_RT: ::std::os::raw::c_uint = 24579;
pub const ETH_P_LAT: ::std::os::raw::c_uint = 24580;
pub const ETH_P_DIAG: ::std::os::raw::c_uint = 24581;
pub const ETH_P_CUST: ::std::os::raw::c_uint = 24582;
pub const ETH_P_SCA: ::std::os::raw::c_uint = 24583;
pub const ETH_P_TEB: ::std::os::raw::c_uint = 25944;
pub const ETH_P_RARP: ::std::os::raw::c_uint = 32821;
pub const ETH_P_ATALK: ::std::os::raw::c_uint = 32923;
pub const ETH_P_AARP: ::std::os::raw::c_uint = 33011;
pub const ETH_P_8021Q: ::std::os::raw::c_uint = 33024;
pub const ETH_P_IPX: ::std::os::raw::c_uint = 33079;
pub const ETH_P_IPV6: ::std::os::raw::c_uint = 34525;
pub const ETH_P_PAUSE: ::std::os::raw::c_uint = 34824;
pub const ETH_P_SLOW: ::std::os::raw::c_uint = 34825;
pub const ETH_P_WCCP: ::std::os::raw::c_uint = 34878;
pub const ETH_P_MPLS_UC: ::std::os::raw::c_uint = 34887;
pub const ETH_P_MPLS_MC: ::std::os::raw::c_uint = 34888;
pub const ETH_P_ATMMPOA: ::std::os::raw::c_uint = 34892;
pub const ETH_P_PPP_DISC: ::std::os::raw::c_uint = 34915;
pub const ETH_P_PPP_SES: ::std::os::raw::c_uint = 34916;
pub const ETH_P_LINK_CTL: ::std::os::raw::c_uint = 34924;
pub const ETH_P_ATMFATE: ::std::os::raw::c_uint = 34948;
pub const ETH_P_PAE: ::std::os::raw::c_uint = 34958;
pub const ETH_P_AOE: ::std::os::raw::c_uint = 34978;
pub const ETH_P_8021AD: ::std::os::raw::c_uint = 34984;
pub const ETH_P_802_EX1: ::std::os::raw::c_uint = 34997;
pub const ETH_P_TIPC: ::std::os::raw::c_uint = 35018;
pub const ETH_P_8021AH: ::std::os::raw::c_uint = 35047;
pub const ETH_P_MVRP: ::std::os::raw::c_uint = 35061;
pub const ETH_P_1588: ::std::os::raw::c_uint = 35063;
pub const ETH_P_PRP: ::std::os::raw::c_uint = 35067;
pub const ETH_P_FCOE: ::std::os::raw::c_uint = 35078;
pub const ETH_P_TDLS: ::std::os::raw::c_uint = 35085;
pub const ETH_P_FIP: ::std::os::raw::c_uint = 35092;
pub const ETH_P_80221: ::std::os::raw::c_uint = 35095;
pub const ETH_P_LOOPBACK: ::std::os::raw::c_uint = 36864;
pub const ETH_P_QINQ1: ::std::os::raw::c_uint = 37120;
pub const ETH_P_QINQ2: ::std::os::raw::c_uint = 37376;
pub const ETH_P_QINQ3: ::std::os::raw::c_uint = 37632;
pub const ETH_P_EDSA: ::std::os::raw::c_uint = 56026;
pub const ETH_P_AF_IUCV: ::std::os::raw::c_uint = 64507;
pub const ETH_P_802_3_MIN: ::std::os::raw::c_uint = 1536;
pub const ETH_P_802_3: ::std::os::raw::c_uint = 1;
pub const ETH_P_AX25: ::std::os::raw::c_uint = 2;
pub const ETH_P_ALL: ::std::os::raw::c_uint = 3;
pub const ETH_P_802_2: ::std::os::raw::c_uint = 4;
pub const ETH_P_SNAP: ::std::os::raw::c_uint = 5;
pub const ETH_P_DDCMP: ::std::os::raw::c_uint = 6;
pub const ETH_P_WAN_PPP: ::std::os::raw::c_uint = 7;
pub const ETH_P_PPP_MP: ::std::os::raw::c_uint = 8;
pub const ETH_P_LOCALTALK: ::std::os::raw::c_uint = 9;
pub const ETH_P_CAN: ::std::os::raw::c_uint = 12;
pub const ETH_P_CANFD: ::std::os::raw::c_uint = 13;
pub const ETH_P_PPPTALK: ::std::os::raw::c_uint = 16;
pub const ETH_P_TR_802_2: ::std::os::raw::c_uint = 17;
pub const ETH_P_MOBITEX: ::std::os::raw::c_uint = 21;
pub const ETH_P_CONTROL: ::std::os::raw::c_uint = 22;
pub const ETH_P_IRDA: ::std::os::raw::c_uint = 23;
pub const ETH_P_ECONET: ::std::os::raw::c_uint = 24;
pub const ETH_P_HDLC: ::std::os::raw::c_uint = 25;
pub const ETH_P_ARCNET: ::std::os::raw::c_uint = 26;
pub const ETH_P_DSA: ::std::os::raw::c_uint = 27;
pub const ETH_P_TRAILER: ::std::os::raw::c_uint = 28;
pub const ETH_P_PHONET: ::std::os::raw::c_uint = 245;
pub const ETH_P_IEEE802154: ::std::os::raw::c_uint = 246;
pub const ETH_P_CAIF: ::std::os::raw::c_uint = 247;
pub const ETH_P_XDSA: ::std::os::raw::c_uint = 248;
pub const BPF_LD: ::std::os::raw::c_uint = 0;
pub const BPF_LDX: ::std::os::raw::c_uint = 1;
pub const BPF_ST: ::std::os::raw::c_uint = 2;
pub const BPF_STX: ::std::os::raw::c_uint = 3;
pub const BPF_ALU: ::std::os::raw::c_uint = 4;
pub const BPF_JMP: ::std::os::raw::c_uint = 5;
pub const BPF_RET: ::std::os::raw::c_uint = 6;
pub const BPF_MISC: ::std::os::raw::c_uint = 7;
pub const BPF_W: ::std::os::raw::c_uint = 0;
pub const BPF_H: ::std::os::raw::c_uint = 8;
pub const BPF_B: ::std::os::raw::c_uint = 16;
pub const BPF_IMM: ::std::os::raw::c_uint = 0;
pub const BPF_ABS: ::std::os::raw::c_uint = 32;
pub const BPF_IND: ::std::os::raw::c_uint = 64;
pub const BPF_MEM: ::std::os::raw::c_uint = 96;
pub const BPF_LEN: ::std::os::raw::c_uint = 128;
pub const BPF_MSH: ::std::os::raw::c_uint = 160;
pub const BPF_ADD: ::std::os::raw::c_uint = 0;
pub const BPF_SUB: ::std::os::raw::c_uint = 16;
pub const BPF_MUL: ::std::os::raw::c_uint = 32;
pub const BPF_DIV: ::std::os::raw::c_uint = 48;
pub const BPF_OR: ::std::os::raw::c_uint = 64;
pub const BPF_AND: ::std::os::raw::c_uint = 80;
pub const BPF_LSH: ::std::os::raw::c_uint = 96;
pub const BPF_RSH: ::std::os::raw::c_uint = 112;
pub const BPF_NEG: ::std::os::raw::c_uint = 128;
pub const BPF_MOD: ::std::os::raw::c_uint = 144;
pub const BPF_XOR: ::std::os::raw::c_uint = 160;
pub const BPF_JA: ::std::os::raw::c_uint = 0;
pub const BPF_JEQ: ::std::os::raw::c_uint = 16;
pub const BPF_JGT: ::std::os::raw::c_uint = 32;
pub const BPF_JGE: ::std::os::raw::c_uint = 48;
pub const BPF_JSET: ::std::os::raw::c_uint = 64;
pub const BPF_K: ::std::os::raw::c_uint = 0;
pub const BPF_X: ::std::os::raw::c_uint = 8;
pub const BPF_MAXINSNS: ::std::os::raw::c_uint = 4096;
pub const BPF_MAJOR_VERSION: ::std::os::raw::c_uint = 1;
pub const BPF_MINOR_VERSION: ::std::os::raw::c_uint = 1;
pub const BPF_A: ::std::os::raw::c_uint = 16;
pub const BPF_TAX: ::std::os::raw::c_uint = 0;
pub const BPF_TXA: ::std::os::raw::c_uint = 128;
pub const BPF_MEMWORDS: ::std::os::raw::c_uint = 16;
pub const SKF_AD_OFF: ::std::os::raw::c_int = -4096;
pub const SKF_AD_PROTOCOL: ::std::os::raw::c_uint = 0;
pub const SKF_AD_PKTTYPE: ::std::os::raw::c_uint = 4;
pub const SKF_AD_IFINDEX: ::std::os::raw::c_uint = 8;
pub const SKF_AD_NLATTR: ::std::os::raw::c_uint = 12;
pub const SKF_AD_NLATTR_NEST: ::std::os::raw::c_uint = 16;
pub const SKF_AD_MARK: ::std::os::raw::c_uint = 20;
pub const SKF_AD_QUEUE: ::std::os::raw::c_uint = 24;
pub const SKF_AD_HATYPE: ::std::os::raw::c_uint = 28;
pub const SKF_AD_RXHASH: ::std::os::raw::c_uint = 32;
pub const SKF_AD_CPU: ::std::os::raw::c_uint = 36;
pub const SKF_AD_ALU_XOR_X: ::std::os::raw::c_uint = 40;
pub const SKF_AD_VLAN_TAG: ::std::os::raw::c_uint = 44;
pub const SKF_AD_VLAN_TAG_PRESENT: ::std::os::raw::c_uint = 48;
pub const SKF_AD_PAY_OFFSET: ::std::os::raw::c_uint = 52;
pub const SKF_AD_RANDOM: ::std::os::raw::c_uint = 56;
pub const SKF_AD_VLAN_TPID: ::std::os::raw::c_uint = 60;
pub const SKF_AD_MAX: ::std::os::raw::c_uint = 64;
pub const SKF_NET_OFF: ::std::os::raw::c_int = -1048576;
pub const SKF_LL_OFF: ::std::os::raw::c_int = -2097152;
pub const BPF_NET_OFF: ::std::os::raw::c_int = -1048576;
pub const BPF_LL_OFF: ::std::os::raw::c_int = -2097152;
pub const TUN_READQ_SIZE: ::std::os::raw::c_uint = 500;
pub const TUN_TYPE_MASK: ::std::os::raw::c_uint = 15;
pub const IFF_TUN: ::std::os::raw::c_uint = 1;
pub const IFF_TAP: ::std::os::raw::c_uint = 2;
pub const IFF_NO_PI: ::std::os::raw::c_uint = 4096;
pub const IFF_ONE_QUEUE: ::std::os::raw::c_uint = 8192;
pub const IFF_VNET_HDR: ::std::os::raw::c_uint = 16384;
pub const IFF_TUN_EXCL: ::std::os::raw::c_uint = 32768;
pub const IFF_MULTI_QUEUE: ::std::os::raw::c_uint = 256;
pub const IFF_ATTACH_QUEUE: ::std::os::raw::c_uint = 512;
pub const IFF_DETACH_QUEUE: ::std::os::raw::c_uint = 1024;
pub const IFF_PERSIST: ::std::os::raw::c_uint = 2048;
pub const IFF_NOFILTER: ::std::os::raw::c_uint = 4096;
pub const TUN_TX_TIMESTAMP: ::std::os::raw::c_uint = 1;
pub const TUN_F_CSUM: ::std::os::raw::c_uint = 1;
pub const TUN_F_TSO4: ::std::os::raw::c_uint = 2;
pub const TUN_F_TSO6: ::std::os::raw::c_uint = 4;
pub const TUN_F_TSO_ECN: ::std::os::raw::c_uint = 8;
pub const TUN_F_UFO: ::std::os::raw::c_uint = 16;
pub const TUN_PKT_STRIP: ::std::os::raw::c_uint = 1;
pub const TUN_FLT_ALLMULTI: ::std::os::raw::c_uint = 1;
pub type __s8 = ::std::os::raw::c_schar;
pub type __u8 = ::std::os::raw::c_uchar;
pub type __s16 = ::std::os::raw::c_short;
pub type __u16 = ::std::os::raw::c_ushort;
pub type __s32 = ::std::os::raw::c_int;
pub type __u32 = ::std::os::raw::c_uint;
pub type __s64 = ::std::os::raw::c_longlong;
pub type __u64 = ::std::os::raw::c_ulonglong;
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct __kernel_fd_set {
pub fds_bits: [::std::os::raw::c_ulong; 16usize],
}
#[test]
fn bindgen_test_layout___kernel_fd_set() {
assert_eq!(
::std::mem::size_of::<__kernel_fd_set>(),
128usize,
concat!("Size of: ", stringify!(__kernel_fd_set))
);
assert_eq!(
::std::mem::align_of::<__kernel_fd_set>(),
8usize,
concat!("Alignment of ", stringify!(__kernel_fd_set))
);
assert_eq!(
unsafe { &(*(0 as *const __kernel_fd_set)).fds_bits as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(__kernel_fd_set),
"::",
stringify!(fds_bits)
)
);
}
impl Clone for __kernel_fd_set {
fn clone(&self) -> Self {
*self
}
}
pub type __kernel_sighandler_t =
::std::option::Option<unsafe extern "C" fn(arg1: ::std::os::raw::c_int)>;
pub type __kernel_key_t = ::std::os::raw::c_int;
pub type __kernel_mqd_t = ::std::os::raw::c_int;
pub type __kernel_old_uid_t = ::std::os::raw::c_ushort;
pub type __kernel_old_gid_t = ::std::os::raw::c_ushort;
pub type __kernel_old_dev_t = ::std::os::raw::c_ulong;
pub type __kernel_long_t = ::std::os::raw::c_long;
pub type __kernel_ulong_t = ::std::os::raw::c_ulong;
pub type __kernel_ino_t = __kernel_ulong_t;
pub type __kernel_mode_t = ::std::os::raw::c_uint;
pub type __kernel_pid_t = ::std::os::raw::c_int;
pub type __kernel_ipc_pid_t = ::std::os::raw::c_int;
pub type __kernel_uid_t = ::std::os::raw::c_uint;
pub type __kernel_gid_t = ::std::os::raw::c_uint;
pub type __kernel_suseconds_t = __kernel_long_t;
pub type __kernel_daddr_t = ::std::os::raw::c_int;
pub type __kernel_uid32_t = ::std::os::raw::c_uint;
pub type __kernel_gid32_t = ::std::os::raw::c_uint;
pub type __kernel_size_t = __kernel_ulong_t;
pub type __kernel_ssize_t = __kernel_long_t;
pub type __kernel_ptrdiff_t = __kernel_long_t;
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct __kernel_fsid_t {
pub val: [::std::os::raw::c_int; 2usize],
}
#[test]
fn bindgen_test_layout___kernel_fsid_t() {
assert_eq!(
::std::mem::size_of::<__kernel_fsid_t>(),
8usize,
concat!("Size of: ", stringify!(__kernel_fsid_t))
);
assert_eq!(
::std::mem::align_of::<__kernel_fsid_t>(),
4usize,
concat!("Alignment of ", stringify!(__kernel_fsid_t))
);
assert_eq!(
unsafe { &(*(0 as *const __kernel_fsid_t)).val as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(__kernel_fsid_t),
"::",
stringify!(val)
)
);
}
impl Clone for __kernel_fsid_t {
fn clone(&self) -> Self {
*self
}
}
pub type __kernel_off_t = __kernel_long_t;
pub type __kernel_loff_t = ::std::os::raw::c_longlong;
pub type __kernel_time_t = __kernel_long_t;
pub type __kernel_clock_t = __kernel_long_t;
pub type __kernel_timer_t = ::std::os::raw::c_int;
pub type __kernel_clockid_t = ::std::os::raw::c_int;
pub type __kernel_caddr_t = *mut ::std::os::raw::c_char;
pub type __kernel_uid16_t = ::std::os::raw::c_ushort;
pub type __kernel_gid16_t = ::std::os::raw::c_ushort;
pub type __le16 = __u16;
pub type __be16 = __u16;
pub type __le32 = __u32;
pub type __be32 = __u32;
pub type __le64 = __u64;
pub type __be64 = __u64;
pub type __sum16 = __u16;
pub type __wsum = __u32;
#[repr(C, packed)]
#[derive(Debug, Default, Copy)]
pub struct ethhdr {
pub h_dest: [::std::os::raw::c_uchar; 6usize],
pub h_source: [::std::os::raw::c_uchar; 6usize],
pub h_proto: __be16,
}
#[test]
fn bindgen_test_layout_ethhdr() {
assert_eq!(
::std::mem::size_of::<ethhdr>(),
14usize,
concat!("Size of: ", stringify!(ethhdr))
);
assert_eq!(
::std::mem::align_of::<ethhdr>(),
1usize,
concat!("Alignment of ", stringify!(ethhdr))
);
assert_eq!(
unsafe { &(*(0 as *const ethhdr)).h_dest as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(ethhdr),
"::",
stringify!(h_dest)
)
);
assert_eq!(
unsafe { &(*(0 as *const ethhdr)).h_source as *const _ as usize },
6usize,
concat!(
"Alignment of field: ",
stringify!(ethhdr),
"::",
stringify!(h_source)
)
);
assert_eq!(
unsafe { &(*(0 as *const ethhdr)).h_proto as *const _ as usize },
12usize,
concat!(
"Alignment of field: ",
stringify!(ethhdr),
"::",
stringify!(h_proto)
)
);
}
impl Clone for ethhdr {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct sock_filter {
pub code: __u16,
pub jt: __u8,
pub jf: __u8,
pub k: __u32,
}
#[test]
fn bindgen_test_layout_sock_filter() {
assert_eq!(
::std::mem::size_of::<sock_filter>(),
8usize,
concat!("Size of: ", stringify!(sock_filter))
);
assert_eq!(
::std::mem::align_of::<sock_filter>(),
4usize,
concat!("Alignment of ", stringify!(sock_filter))
);
assert_eq!(
unsafe { &(*(0 as *const sock_filter)).code as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(sock_filter),
"::",
stringify!(code)
)
);
assert_eq!(
unsafe { &(*(0 as *const sock_filter)).jt as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(sock_filter),
"::",
stringify!(jt)
)
);
assert_eq!(
unsafe { &(*(0 as *const sock_filter)).jf as *const _ as usize },
3usize,
concat!(
"Alignment of field: ",
stringify!(sock_filter),
"::",
stringify!(jf)
)
);
assert_eq!(
unsafe { &(*(0 as *const sock_filter)).k as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(sock_filter),
"::",
stringify!(k)
)
);
}
impl Clone for sock_filter {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct sock_fprog {
pub len: ::std::os::raw::c_ushort,
pub filter: *mut sock_filter,
}
#[test]
fn bindgen_test_layout_sock_fprog() {
assert_eq!(
::std::mem::size_of::<sock_fprog>(),
16usize,
concat!("Size of: ", stringify!(sock_fprog))
);
assert_eq!(
::std::mem::align_of::<sock_fprog>(),
8usize,
concat!("Alignment of ", stringify!(sock_fprog))
);
assert_eq!(
unsafe { &(*(0 as *const sock_fprog)).len as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(sock_fprog),
"::",
stringify!(len)
)
);
assert_eq!(
unsafe { &(*(0 as *const sock_fprog)).filter as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(sock_fprog),
"::",
stringify!(filter)
)
);
}
impl Clone for sock_fprog {
fn clone(&self) -> Self {
*self
}
}
impl Default for sock_fprog {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct tun_pi {
pub flags: __u16,
pub proto: __be16,
}
#[test]
fn bindgen_test_layout_tun_pi() {
assert_eq!(
::std::mem::size_of::<tun_pi>(),
4usize,
concat!("Size of: ", stringify!(tun_pi))
);
assert_eq!(
::std::mem::align_of::<tun_pi>(),
2usize,
concat!("Alignment of ", stringify!(tun_pi))
);
assert_eq!(
unsafe { &(*(0 as *const tun_pi)).flags as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(tun_pi),
"::",
stringify!(flags)
)
);
assert_eq!(
unsafe { &(*(0 as *const tun_pi)).proto as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(tun_pi),
"::",
stringify!(proto)
)
);
}
impl Clone for tun_pi {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct tun_filter {
pub flags: __u16,
pub count: __u16,
pub addr: __IncompleteArrayField<[__u8; 6usize]>,
}
#[test]
fn bindgen_test_layout_tun_filter() {
assert_eq!(
::std::mem::size_of::<tun_filter>(),
4usize,
concat!("Size of: ", stringify!(tun_filter))
);
assert_eq!(
::std::mem::align_of::<tun_filter>(),
2usize,
concat!("Alignment of ", stringify!(tun_filter))
);
assert_eq!(
unsafe { &(*(0 as *const tun_filter)).flags as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(tun_filter),
"::",
stringify!(flags)
)
);
assert_eq!(
unsafe { &(*(0 as *const tun_filter)).count as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(tun_filter),
"::",
stringify!(count)
)
);
assert_eq!(
unsafe { &(*(0 as *const tun_filter)).addr as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(tun_filter),
"::",
stringify!(addr)
)
);
}
impl Clone for tun_filter {
fn clone(&self) -> Self {
*self
}
}

3264
net_gen/src/iff.rs Normal file

File diff suppressed because it is too large Load Diff

843
net_gen/src/inn.rs Normal file
View File

@ -0,0 +1,843 @@
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
/* automatically generated by rust-bindgen */
pub const __BITS_PER_LONG: ::std::os::raw::c_uint = 64;
pub const __FD_SETSIZE: ::std::os::raw::c_uint = 1024;
pub const __UAPI_DEF_IN_ADDR: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IN_IPPROTO: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IN_PKTINFO: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IP_MREQ: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_SOCKADDR_IN: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IN_CLASS: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IN6_ADDR: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IN6_ADDR_ALT: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_SOCKADDR_IN6: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IPV6_MREQ: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IPPROTO_V6: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IPV6_OPTIONS: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IN6_PKTINFO: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_IP6_MTUINFO: ::std::os::raw::c_uint = 1;
pub const __UAPI_DEF_XATTR: ::std::os::raw::c_uint = 1;
pub const _K_SS_MAXSIZE: ::std::os::raw::c_uint = 128;
pub const IP_TOS: ::std::os::raw::c_uint = 1;
pub const IP_TTL: ::std::os::raw::c_uint = 2;
pub const IP_HDRINCL: ::std::os::raw::c_uint = 3;
pub const IP_OPTIONS: ::std::os::raw::c_uint = 4;
pub const IP_ROUTER_ALERT: ::std::os::raw::c_uint = 5;
pub const IP_RECVOPTS: ::std::os::raw::c_uint = 6;
pub const IP_RETOPTS: ::std::os::raw::c_uint = 7;
pub const IP_PKTINFO: ::std::os::raw::c_uint = 8;
pub const IP_PKTOPTIONS: ::std::os::raw::c_uint = 9;
pub const IP_MTU_DISCOVER: ::std::os::raw::c_uint = 10;
pub const IP_RECVERR: ::std::os::raw::c_uint = 11;
pub const IP_RECVTTL: ::std::os::raw::c_uint = 12;
pub const IP_RECVTOS: ::std::os::raw::c_uint = 13;
pub const IP_MTU: ::std::os::raw::c_uint = 14;
pub const IP_FREEBIND: ::std::os::raw::c_uint = 15;
pub const IP_IPSEC_POLICY: ::std::os::raw::c_uint = 16;
pub const IP_XFRM_POLICY: ::std::os::raw::c_uint = 17;
pub const IP_PASSSEC: ::std::os::raw::c_uint = 18;
pub const IP_TRANSPARENT: ::std::os::raw::c_uint = 19;
pub const IP_RECVRETOPTS: ::std::os::raw::c_uint = 7;
pub const IP_ORIGDSTADDR: ::std::os::raw::c_uint = 20;
pub const IP_RECVORIGDSTADDR: ::std::os::raw::c_uint = 20;
pub const IP_MINTTL: ::std::os::raw::c_uint = 21;
pub const IP_NODEFRAG: ::std::os::raw::c_uint = 22;
pub const IP_CHECKSUM: ::std::os::raw::c_uint = 23;
pub const IP_BIND_ADDRESS_NO_PORT: ::std::os::raw::c_uint = 24;
pub const IP_RECVFRAGSIZE: ::std::os::raw::c_uint = 25;
pub const IP_PMTUDISC_DONT: ::std::os::raw::c_uint = 0;
pub const IP_PMTUDISC_WANT: ::std::os::raw::c_uint = 1;
pub const IP_PMTUDISC_DO: ::std::os::raw::c_uint = 2;
pub const IP_PMTUDISC_PROBE: ::std::os::raw::c_uint = 3;
pub const IP_PMTUDISC_INTERFACE: ::std::os::raw::c_uint = 4;
pub const IP_PMTUDISC_OMIT: ::std::os::raw::c_uint = 5;
pub const IP_MULTICAST_IF: ::std::os::raw::c_uint = 32;
pub const IP_MULTICAST_TTL: ::std::os::raw::c_uint = 33;
pub const IP_MULTICAST_LOOP: ::std::os::raw::c_uint = 34;
pub const IP_ADD_MEMBERSHIP: ::std::os::raw::c_uint = 35;
pub const IP_DROP_MEMBERSHIP: ::std::os::raw::c_uint = 36;
pub const IP_UNBLOCK_SOURCE: ::std::os::raw::c_uint = 37;
pub const IP_BLOCK_SOURCE: ::std::os::raw::c_uint = 38;
pub const IP_ADD_SOURCE_MEMBERSHIP: ::std::os::raw::c_uint = 39;
pub const IP_DROP_SOURCE_MEMBERSHIP: ::std::os::raw::c_uint = 40;
pub const IP_MSFILTER: ::std::os::raw::c_uint = 41;
pub const MCAST_JOIN_GROUP: ::std::os::raw::c_uint = 42;
pub const MCAST_BLOCK_SOURCE: ::std::os::raw::c_uint = 43;
pub const MCAST_UNBLOCK_SOURCE: ::std::os::raw::c_uint = 44;
pub const MCAST_LEAVE_GROUP: ::std::os::raw::c_uint = 45;
pub const MCAST_JOIN_SOURCE_GROUP: ::std::os::raw::c_uint = 46;
pub const MCAST_LEAVE_SOURCE_GROUP: ::std::os::raw::c_uint = 47;
pub const MCAST_MSFILTER: ::std::os::raw::c_uint = 48;
pub const IP_MULTICAST_ALL: ::std::os::raw::c_uint = 49;
pub const IP_UNICAST_IF: ::std::os::raw::c_uint = 50;
pub const MCAST_EXCLUDE: ::std::os::raw::c_uint = 0;
pub const MCAST_INCLUDE: ::std::os::raw::c_uint = 1;
pub const IP_DEFAULT_MULTICAST_TTL: ::std::os::raw::c_uint = 1;
pub const IP_DEFAULT_MULTICAST_LOOP: ::std::os::raw::c_uint = 1;
pub const __SOCK_SIZE__: ::std::os::raw::c_uint = 16;
pub const IN_CLASSA_NET: ::std::os::raw::c_uint = 4278190080;
pub const IN_CLASSA_NSHIFT: ::std::os::raw::c_uint = 24;
pub const IN_CLASSA_HOST: ::std::os::raw::c_uint = 16777215;
pub const IN_CLASSA_MAX: ::std::os::raw::c_uint = 128;
pub const IN_CLASSB_NET: ::std::os::raw::c_uint = 4294901760;
pub const IN_CLASSB_NSHIFT: ::std::os::raw::c_uint = 16;
pub const IN_CLASSB_HOST: ::std::os::raw::c_uint = 65535;
pub const IN_CLASSB_MAX: ::std::os::raw::c_uint = 65536;
pub const IN_CLASSC_NET: ::std::os::raw::c_uint = 4294967040;
pub const IN_CLASSC_NSHIFT: ::std::os::raw::c_uint = 8;
pub const IN_CLASSC_HOST: ::std::os::raw::c_uint = 255;
pub const IN_MULTICAST_NET: ::std::os::raw::c_uint = 4026531840;
pub const IN_LOOPBACKNET: ::std::os::raw::c_uint = 127;
pub const INADDR_LOOPBACK: ::std::os::raw::c_uint = 2130706433;
pub const INADDR_UNSPEC_GROUP: ::std::os::raw::c_uint = 3758096384;
pub const INADDR_ALLHOSTS_GROUP: ::std::os::raw::c_uint = 3758096385;
pub const INADDR_ALLRTRS_GROUP: ::std::os::raw::c_uint = 3758096386;
pub const INADDR_MAX_LOCAL_GROUP: ::std::os::raw::c_uint = 3758096639;
pub const __LITTLE_ENDIAN: ::std::os::raw::c_uint = 1234;
pub type __s8 = ::std::os::raw::c_schar;
pub type __u8 = ::std::os::raw::c_uchar;
pub type __s16 = ::std::os::raw::c_short;
pub type __u16 = ::std::os::raw::c_ushort;
pub type __s32 = ::std::os::raw::c_int;
pub type __u32 = ::std::os::raw::c_uint;
pub type __s64 = ::std::os::raw::c_longlong;
pub type __u64 = ::std::os::raw::c_ulonglong;
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct __kernel_fd_set {
pub fds_bits: [::std::os::raw::c_ulong; 16usize],
}
#[test]
fn bindgen_test_layout___kernel_fd_set() {
assert_eq!(
::std::mem::size_of::<__kernel_fd_set>(),
128usize,
concat!("Size of: ", stringify!(__kernel_fd_set))
);
assert_eq!(
::std::mem::align_of::<__kernel_fd_set>(),
8usize,
concat!("Alignment of ", stringify!(__kernel_fd_set))
);
assert_eq!(
unsafe { &(*(0 as *const __kernel_fd_set)).fds_bits as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(__kernel_fd_set),
"::",
stringify!(fds_bits)
)
);
}
impl Clone for __kernel_fd_set {
fn clone(&self) -> Self {
*self
}
}
pub type __kernel_sighandler_t =
::std::option::Option<unsafe extern "C" fn(arg1: ::std::os::raw::c_int)>;
pub type __kernel_key_t = ::std::os::raw::c_int;
pub type __kernel_mqd_t = ::std::os::raw::c_int;
pub type __kernel_old_uid_t = ::std::os::raw::c_ushort;
pub type __kernel_old_gid_t = ::std::os::raw::c_ushort;
pub type __kernel_old_dev_t = ::std::os::raw::c_ulong;
pub type __kernel_long_t = ::std::os::raw::c_long;
pub type __kernel_ulong_t = ::std::os::raw::c_ulong;
pub type __kernel_ino_t = __kernel_ulong_t;
pub type __kernel_mode_t = ::std::os::raw::c_uint;
pub type __kernel_pid_t = ::std::os::raw::c_int;
pub type __kernel_ipc_pid_t = ::std::os::raw::c_int;
pub type __kernel_uid_t = ::std::os::raw::c_uint;
pub type __kernel_gid_t = ::std::os::raw::c_uint;
pub type __kernel_suseconds_t = __kernel_long_t;
pub type __kernel_daddr_t = ::std::os::raw::c_int;
pub type __kernel_uid32_t = ::std::os::raw::c_uint;
pub type __kernel_gid32_t = ::std::os::raw::c_uint;
pub type __kernel_size_t = __kernel_ulong_t;
pub type __kernel_ssize_t = __kernel_long_t;
pub type __kernel_ptrdiff_t = __kernel_long_t;
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct __kernel_fsid_t {
pub val: [::std::os::raw::c_int; 2usize],
}
#[test]
fn bindgen_test_layout___kernel_fsid_t() {
assert_eq!(
::std::mem::size_of::<__kernel_fsid_t>(),
8usize,
concat!("Size of: ", stringify!(__kernel_fsid_t))
);
assert_eq!(
::std::mem::align_of::<__kernel_fsid_t>(),
4usize,
concat!("Alignment of ", stringify!(__kernel_fsid_t))
);
assert_eq!(
unsafe { &(*(0 as *const __kernel_fsid_t)).val as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(__kernel_fsid_t),
"::",
stringify!(val)
)
);
}
impl Clone for __kernel_fsid_t {
fn clone(&self) -> Self {
*self
}
}
pub type __kernel_off_t = __kernel_long_t;
pub type __kernel_loff_t = ::std::os::raw::c_longlong;
pub type __kernel_time_t = __kernel_long_t;
pub type __kernel_clock_t = __kernel_long_t;
pub type __kernel_timer_t = ::std::os::raw::c_int;
pub type __kernel_clockid_t = ::std::os::raw::c_int;
pub type __kernel_caddr_t = *mut ::std::os::raw::c_char;
pub type __kernel_uid16_t = ::std::os::raw::c_ushort;
pub type __kernel_gid16_t = ::std::os::raw::c_ushort;
pub type __le16 = __u16;
pub type __be16 = __u16;
pub type __le32 = __u32;
pub type __be32 = __u32;
pub type __le64 = __u64;
pub type __be64 = __u64;
pub type __sum16 = __u16;
pub type __wsum = __u32;
pub type __kernel_sa_family_t = ::std::os::raw::c_ushort;
#[repr(C)]
pub struct __kernel_sockaddr_storage {
pub ss_family: __kernel_sa_family_t,
pub __data: [::std::os::raw::c_char; 126usize],
pub __bindgen_align: [u64; 0usize],
}
#[test]
fn bindgen_test_layout___kernel_sockaddr_storage() {
assert_eq!(
::std::mem::size_of::<__kernel_sockaddr_storage>(),
128usize,
concat!("Size of: ", stringify!(__kernel_sockaddr_storage))
);
assert_eq!(
::std::mem::align_of::<__kernel_sockaddr_storage>(),
8usize,
concat!("Alignment of ", stringify!(__kernel_sockaddr_storage))
);
assert_eq!(
unsafe { &(*(0 as *const __kernel_sockaddr_storage)).ss_family as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(__kernel_sockaddr_storage),
"::",
stringify!(ss_family)
)
);
assert_eq!(
unsafe { &(*(0 as *const __kernel_sockaddr_storage)).__data as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(__kernel_sockaddr_storage),
"::",
stringify!(__data)
)
);
}
impl Default for __kernel_sockaddr_storage {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
pub const IPPROTO_IP: _bindgen_ty_1 = 0;
pub const IPPROTO_ICMP: _bindgen_ty_1 = 1;
pub const IPPROTO_IGMP: _bindgen_ty_1 = 2;
pub const IPPROTO_IPIP: _bindgen_ty_1 = 4;
pub const IPPROTO_TCP: _bindgen_ty_1 = 6;
pub const IPPROTO_EGP: _bindgen_ty_1 = 8;
pub const IPPROTO_PUP: _bindgen_ty_1 = 12;
pub const IPPROTO_UDP: _bindgen_ty_1 = 17;
pub const IPPROTO_IDP: _bindgen_ty_1 = 22;
pub const IPPROTO_TP: _bindgen_ty_1 = 29;
pub const IPPROTO_DCCP: _bindgen_ty_1 = 33;
pub const IPPROTO_IPV6: _bindgen_ty_1 = 41;
pub const IPPROTO_RSVP: _bindgen_ty_1 = 46;
pub const IPPROTO_GRE: _bindgen_ty_1 = 47;
pub const IPPROTO_ESP: _bindgen_ty_1 = 50;
pub const IPPROTO_AH: _bindgen_ty_1 = 51;
pub const IPPROTO_MTP: _bindgen_ty_1 = 92;
pub const IPPROTO_BEETPH: _bindgen_ty_1 = 94;
pub const IPPROTO_ENCAP: _bindgen_ty_1 = 98;
pub const IPPROTO_PIM: _bindgen_ty_1 = 103;
pub const IPPROTO_COMP: _bindgen_ty_1 = 108;
pub const IPPROTO_SCTP: _bindgen_ty_1 = 132;
pub const IPPROTO_UDPLITE: _bindgen_ty_1 = 136;
pub const IPPROTO_MPLS: _bindgen_ty_1 = 137;
pub const IPPROTO_RAW: _bindgen_ty_1 = 255;
pub const IPPROTO_MAX: _bindgen_ty_1 = 256;
pub type _bindgen_ty_1 = ::std::os::raw::c_uint;
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct in_addr {
pub s_addr: __be32,
}
#[test]
fn bindgen_test_layout_in_addr() {
assert_eq!(
::std::mem::size_of::<in_addr>(),
4usize,
concat!("Size of: ", stringify!(in_addr))
);
assert_eq!(
::std::mem::align_of::<in_addr>(),
4usize,
concat!("Alignment of ", stringify!(in_addr))
);
assert_eq!(
unsafe { &(*(0 as *const in_addr)).s_addr as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(in_addr),
"::",
stringify!(s_addr)
)
);
}
impl Clone for in_addr {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct ip_mreq {
pub imr_multiaddr: in_addr,
pub imr_interface: in_addr,
}
#[test]
fn bindgen_test_layout_ip_mreq() {
assert_eq!(
::std::mem::size_of::<ip_mreq>(),
8usize,
concat!("Size of: ", stringify!(ip_mreq))
);
assert_eq!(
::std::mem::align_of::<ip_mreq>(),
4usize,
concat!("Alignment of ", stringify!(ip_mreq))
);
assert_eq!(
unsafe { &(*(0 as *const ip_mreq)).imr_multiaddr as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(ip_mreq),
"::",
stringify!(imr_multiaddr)
)
);
assert_eq!(
unsafe { &(*(0 as *const ip_mreq)).imr_interface as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(ip_mreq),
"::",
stringify!(imr_interface)
)
);
}
impl Clone for ip_mreq {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct ip_mreqn {
pub imr_multiaddr: in_addr,
pub imr_address: in_addr,
pub imr_ifindex: ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout_ip_mreqn() {
assert_eq!(
::std::mem::size_of::<ip_mreqn>(),
12usize,
concat!("Size of: ", stringify!(ip_mreqn))
);
assert_eq!(
::std::mem::align_of::<ip_mreqn>(),
4usize,
concat!("Alignment of ", stringify!(ip_mreqn))
);
assert_eq!(
unsafe { &(*(0 as *const ip_mreqn)).imr_multiaddr as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(ip_mreqn),
"::",
stringify!(imr_multiaddr)
)
);
assert_eq!(
unsafe { &(*(0 as *const ip_mreqn)).imr_address as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(ip_mreqn),
"::",
stringify!(imr_address)
)
);
assert_eq!(
unsafe { &(*(0 as *const ip_mreqn)).imr_ifindex as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(ip_mreqn),
"::",
stringify!(imr_ifindex)
)
);
}
impl Clone for ip_mreqn {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct ip_mreq_source {
pub imr_multiaddr: __be32,
pub imr_interface: __be32,
pub imr_sourceaddr: __be32,
}
#[test]
fn bindgen_test_layout_ip_mreq_source() {
assert_eq!(
::std::mem::size_of::<ip_mreq_source>(),
12usize,
concat!("Size of: ", stringify!(ip_mreq_source))
);
assert_eq!(
::std::mem::align_of::<ip_mreq_source>(),
4usize,
concat!("Alignment of ", stringify!(ip_mreq_source))
);
assert_eq!(
unsafe { &(*(0 as *const ip_mreq_source)).imr_multiaddr as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(ip_mreq_source),
"::",
stringify!(imr_multiaddr)
)
);
assert_eq!(
unsafe { &(*(0 as *const ip_mreq_source)).imr_interface as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(ip_mreq_source),
"::",
stringify!(imr_interface)
)
);
assert_eq!(
unsafe { &(*(0 as *const ip_mreq_source)).imr_sourceaddr as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(ip_mreq_source),
"::",
stringify!(imr_sourceaddr)
)
);
}
impl Clone for ip_mreq_source {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct ip_msfilter {
pub imsf_multiaddr: __be32,
pub imsf_interface: __be32,
pub imsf_fmode: __u32,
pub imsf_numsrc: __u32,
pub imsf_slist: [__be32; 1usize],
}
#[test]
fn bindgen_test_layout_ip_msfilter() {
assert_eq!(
::std::mem::size_of::<ip_msfilter>(),
20usize,
concat!("Size of: ", stringify!(ip_msfilter))
);
assert_eq!(
::std::mem::align_of::<ip_msfilter>(),
4usize,
concat!("Alignment of ", stringify!(ip_msfilter))
);
assert_eq!(
unsafe { &(*(0 as *const ip_msfilter)).imsf_multiaddr as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(ip_msfilter),
"::",
stringify!(imsf_multiaddr)
)
);
assert_eq!(
unsafe { &(*(0 as *const ip_msfilter)).imsf_interface as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(ip_msfilter),
"::",
stringify!(imsf_interface)
)
);
assert_eq!(
unsafe { &(*(0 as *const ip_msfilter)).imsf_fmode as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(ip_msfilter),
"::",
stringify!(imsf_fmode)
)
);
assert_eq!(
unsafe { &(*(0 as *const ip_msfilter)).imsf_numsrc as *const _ as usize },
12usize,
concat!(
"Alignment of field: ",
stringify!(ip_msfilter),
"::",
stringify!(imsf_numsrc)
)
);
assert_eq!(
unsafe { &(*(0 as *const ip_msfilter)).imsf_slist as *const _ as usize },
16usize,
concat!(
"Alignment of field: ",
stringify!(ip_msfilter),
"::",
stringify!(imsf_slist)
)
);
}
impl Clone for ip_msfilter {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
pub struct group_req {
pub gr_interface: __u32,
pub gr_group: __kernel_sockaddr_storage,
}
#[test]
fn bindgen_test_layout_group_req() {
assert_eq!(
::std::mem::size_of::<group_req>(),
136usize,
concat!("Size of: ", stringify!(group_req))
);
assert_eq!(
::std::mem::align_of::<group_req>(),
8usize,
concat!("Alignment of ", stringify!(group_req))
);
assert_eq!(
unsafe { &(*(0 as *const group_req)).gr_interface as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(group_req),
"::",
stringify!(gr_interface)
)
);
assert_eq!(
unsafe { &(*(0 as *const group_req)).gr_group as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(group_req),
"::",
stringify!(gr_group)
)
);
}
impl Default for group_req {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
#[repr(C)]
pub struct group_source_req {
pub gsr_interface: __u32,
pub gsr_group: __kernel_sockaddr_storage,
pub gsr_source: __kernel_sockaddr_storage,
}
#[test]
fn bindgen_test_layout_group_source_req() {
assert_eq!(
::std::mem::size_of::<group_source_req>(),
264usize,
concat!("Size of: ", stringify!(group_source_req))
);
assert_eq!(
::std::mem::align_of::<group_source_req>(),
8usize,
concat!("Alignment of ", stringify!(group_source_req))
);
assert_eq!(
unsafe { &(*(0 as *const group_source_req)).gsr_interface as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(group_source_req),
"::",
stringify!(gsr_interface)
)
);
assert_eq!(
unsafe { &(*(0 as *const group_source_req)).gsr_group as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(group_source_req),
"::",
stringify!(gsr_group)
)
);
assert_eq!(
unsafe { &(*(0 as *const group_source_req)).gsr_source as *const _ as usize },
136usize,
concat!(
"Alignment of field: ",
stringify!(group_source_req),
"::",
stringify!(gsr_source)
)
);
}
impl Default for group_source_req {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
#[repr(C)]
pub struct group_filter {
pub gf_interface: __u32,
pub gf_group: __kernel_sockaddr_storage,
pub gf_fmode: __u32,
pub gf_numsrc: __u32,
pub gf_slist: [__kernel_sockaddr_storage; 1usize],
}
#[test]
fn bindgen_test_layout_group_filter() {
assert_eq!(
::std::mem::size_of::<group_filter>(),
272usize,
concat!("Size of: ", stringify!(group_filter))
);
assert_eq!(
::std::mem::align_of::<group_filter>(),
8usize,
concat!("Alignment of ", stringify!(group_filter))
);
assert_eq!(
unsafe { &(*(0 as *const group_filter)).gf_interface as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(group_filter),
"::",
stringify!(gf_interface)
)
);
assert_eq!(
unsafe { &(*(0 as *const group_filter)).gf_group as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(group_filter),
"::",
stringify!(gf_group)
)
);
assert_eq!(
unsafe { &(*(0 as *const group_filter)).gf_fmode as *const _ as usize },
136usize,
concat!(
"Alignment of field: ",
stringify!(group_filter),
"::",
stringify!(gf_fmode)
)
);
assert_eq!(
unsafe { &(*(0 as *const group_filter)).gf_numsrc as *const _ as usize },
140usize,
concat!(
"Alignment of field: ",
stringify!(group_filter),
"::",
stringify!(gf_numsrc)
)
);
assert_eq!(
unsafe { &(*(0 as *const group_filter)).gf_slist as *const _ as usize },
144usize,
concat!(
"Alignment of field: ",
stringify!(group_filter),
"::",
stringify!(gf_slist)
)
);
}
impl Default for group_filter {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct in_pktinfo {
pub ipi_ifindex: ::std::os::raw::c_int,
pub ipi_spec_dst: in_addr,
pub ipi_addr: in_addr,
}
#[test]
fn bindgen_test_layout_in_pktinfo() {
assert_eq!(
::std::mem::size_of::<in_pktinfo>(),
12usize,
concat!("Size of: ", stringify!(in_pktinfo))
);
assert_eq!(
::std::mem::align_of::<in_pktinfo>(),
4usize,
concat!("Alignment of ", stringify!(in_pktinfo))
);
assert_eq!(
unsafe { &(*(0 as *const in_pktinfo)).ipi_ifindex as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(in_pktinfo),
"::",
stringify!(ipi_ifindex)
)
);
assert_eq!(
unsafe { &(*(0 as *const in_pktinfo)).ipi_spec_dst as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(in_pktinfo),
"::",
stringify!(ipi_spec_dst)
)
);
assert_eq!(
unsafe { &(*(0 as *const in_pktinfo)).ipi_addr as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(in_pktinfo),
"::",
stringify!(ipi_addr)
)
);
}
impl Clone for in_pktinfo {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct sockaddr_in {
pub sin_family: __kernel_sa_family_t,
pub sin_port: __be16,
pub sin_addr: in_addr,
pub __pad: [::std::os::raw::c_uchar; 8usize],
}
#[test]
fn bindgen_test_layout_sockaddr_in() {
assert_eq!(
::std::mem::size_of::<sockaddr_in>(),
16usize,
concat!("Size of: ", stringify!(sockaddr_in))
);
assert_eq!(
::std::mem::align_of::<sockaddr_in>(),
4usize,
concat!("Alignment of ", stringify!(sockaddr_in))
);
assert_eq!(
unsafe { &(*(0 as *const sockaddr_in)).sin_family as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(sockaddr_in),
"::",
stringify!(sin_family)
)
);
assert_eq!(
unsafe { &(*(0 as *const sockaddr_in)).sin_port as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(sockaddr_in),
"::",
stringify!(sin_port)
)
);
assert_eq!(
unsafe { &(*(0 as *const sockaddr_in)).sin_addr as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(sockaddr_in),
"::",
stringify!(sin_addr)
)
);
assert_eq!(
unsafe { &(*(0 as *const sockaddr_in)).__pad as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(sockaddr_in),
"::",
stringify!(__pad)
)
);
}
impl Clone for sockaddr_in {
fn clone(&self) -> Self {
*self
}
}

61
net_gen/src/lib.rs Normal file
View File

@ -0,0 +1,61 @@
// Copyright TUNTAP, 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
#![allow(clippy::all)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#[macro_use]
extern crate vmm_sys_util;
// generated with bindgen /usr/include/linux/if.h --no-unstable-rust
// --constified-enum '*' --with-derive-default -- -D __UAPI_DEF_IF_IFNAMSIZ -D
// __UAPI_DEF_IF_NET_DEVICE_FLAGS -D __UAPI_DEF_IF_IFREQ -D __UAPI_DEF_IF_IFMAP
// Name is "iff" to avoid conflicting with "if" keyword.
// Generated against Linux 4.11 to include fix "uapi: fix linux/if.h userspace
// compilation errors".
// Manual fixup of ifrn_name to be of type c_uchar instead of c_char.
pub mod iff;
// generated with bindgen /usr/include/linux/if_tun.h --no-unstable-rust
// --constified-enum '*' --with-derive-default
pub mod if_tun;
// generated with bindgen /usr/include/linux/in.h --no-unstable-rust
// --constified-enum '*' --with-derive-default
// Name is "inn" to avoid conflicting with "in" keyword.
pub mod inn;
// generated with bindgen /usr/include/linux/sockios.h --no-unstable-rust
// --constified-enum '*' --with-derive-default
pub mod sockios;
pub use if_tun::*;
pub use iff::*;
pub use inn::*;
pub use sockios::*;
pub const TUNTAP: ::std::os::raw::c_uint = 84;
ioctl_iow_nr!(TUNSETNOCSUM, TUNTAP, 200, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETDEBUG, TUNTAP, 201, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETIFF, TUNTAP, 202, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETPERSIST, TUNTAP, 203, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETOWNER, TUNTAP, 204, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETLINK, TUNTAP, 205, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETGROUP, TUNTAP, 206, ::std::os::raw::c_int);
ioctl_ior_nr!(TUNGETFEATURES, TUNTAP, 207, ::std::os::raw::c_uint);
ioctl_iow_nr!(TUNSETOFFLOAD, TUNTAP, 208, ::std::os::raw::c_uint);
ioctl_iow_nr!(TUNSETTXFILTER, TUNTAP, 209, ::std::os::raw::c_uint);
ioctl_ior_nr!(TUNGETIFF, TUNTAP, 210, ::std::os::raw::c_uint);
ioctl_ior_nr!(TUNGETSNDBUF, TUNTAP, 211, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETSNDBUF, TUNTAP, 212, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNATTACHFILTER, TUNTAP, 213, sock_fprog);
ioctl_iow_nr!(TUNDETACHFILTER, TUNTAP, 214, sock_fprog);
ioctl_ior_nr!(TUNGETVNETHDRSZ, TUNTAP, 215, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETVNETHDRSZ, TUNTAP, 216, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETQUEUE, TUNTAP, 217, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETIFINDEX, TUNTAP, 218, ::std::os::raw::c_uint);
ioctl_ior_nr!(TUNGETFILTER, TUNTAP, 219, sock_fprog);
ioctl_iow_nr!(TUNSETVNETLE, TUNTAP, 220, ::std::os::raw::c_int);
ioctl_ior_nr!(TUNGETVNETLE, TUNTAP, 221, ::std::os::raw::c_int);
ioctl_iow_nr!(TUNSETVNETBE, TUNTAP, 222, ::std::os::raw::c_int);
ioctl_ior_nr!(TUNGETVNETBE, TUNTAP, 223, ::std::os::raw::c_int);

89
net_gen/src/sockios.rs Normal file
View File

@ -0,0 +1,89 @@
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
/* automatically generated by rust-bindgen */
pub const FIOSETOWN: ::std::os::raw::c_uint = 35073;
pub const SIOCSPGRP: ::std::os::raw::c_uint = 35074;
pub const FIOGETOWN: ::std::os::raw::c_uint = 35075;
pub const SIOCGPGRP: ::std::os::raw::c_uint = 35076;
pub const SIOCATMARK: ::std::os::raw::c_uint = 35077;
pub const SIOCGSTAMP: ::std::os::raw::c_uint = 35078;
pub const SIOCGSTAMPNS: ::std::os::raw::c_uint = 35079;
pub const SOCK_IOC_TYPE: ::std::os::raw::c_uint = 137;
pub const SIOCADDRT: ::std::os::raw::c_uint = 35083;
pub const SIOCDELRT: ::std::os::raw::c_uint = 35084;
pub const SIOCRTMSG: ::std::os::raw::c_uint = 35085;
pub const SIOCGIFNAME: ::std::os::raw::c_uint = 35088;
pub const SIOCSIFLINK: ::std::os::raw::c_uint = 35089;
pub const SIOCGIFCONF: ::std::os::raw::c_uint = 35090;
pub const SIOCGIFFLAGS: ::std::os::raw::c_uint = 35091;
pub const SIOCSIFFLAGS: ::std::os::raw::c_uint = 35092;
pub const SIOCGIFADDR: ::std::os::raw::c_uint = 35093;
pub const SIOCSIFADDR: ::std::os::raw::c_uint = 35094;
pub const SIOCGIFDSTADDR: ::std::os::raw::c_uint = 35095;
pub const SIOCSIFDSTADDR: ::std::os::raw::c_uint = 35096;
pub const SIOCGIFBRDADDR: ::std::os::raw::c_uint = 35097;
pub const SIOCSIFBRDADDR: ::std::os::raw::c_uint = 35098;
pub const SIOCGIFNETMASK: ::std::os::raw::c_uint = 35099;
pub const SIOCSIFNETMASK: ::std::os::raw::c_uint = 35100;
pub const SIOCGIFMETRIC: ::std::os::raw::c_uint = 35101;
pub const SIOCSIFMETRIC: ::std::os::raw::c_uint = 35102;
pub const SIOCGIFMEM: ::std::os::raw::c_uint = 35103;
pub const SIOCSIFMEM: ::std::os::raw::c_uint = 35104;
pub const SIOCGIFMTU: ::std::os::raw::c_uint = 35105;
pub const SIOCSIFMTU: ::std::os::raw::c_uint = 35106;
pub const SIOCSIFNAME: ::std::os::raw::c_uint = 35107;
pub const SIOCSIFHWADDR: ::std::os::raw::c_uint = 35108;
pub const SIOCGIFENCAP: ::std::os::raw::c_uint = 35109;
pub const SIOCSIFENCAP: ::std::os::raw::c_uint = 35110;
pub const SIOCGIFHWADDR: ::std::os::raw::c_uint = 35111;
pub const SIOCGIFSLAVE: ::std::os::raw::c_uint = 35113;
pub const SIOCSIFSLAVE: ::std::os::raw::c_uint = 35120;
pub const SIOCADDMULTI: ::std::os::raw::c_uint = 35121;
pub const SIOCDELMULTI: ::std::os::raw::c_uint = 35122;
pub const SIOCGIFINDEX: ::std::os::raw::c_uint = 35123;
pub const SIOGIFINDEX: ::std::os::raw::c_uint = 35123;
pub const SIOCSIFPFLAGS: ::std::os::raw::c_uint = 35124;
pub const SIOCGIFPFLAGS: ::std::os::raw::c_uint = 35125;
pub const SIOCDIFADDR: ::std::os::raw::c_uint = 35126;
pub const SIOCSIFHWBROADCAST: ::std::os::raw::c_uint = 35127;
pub const SIOCGIFCOUNT: ::std::os::raw::c_uint = 35128;
pub const SIOCGIFBR: ::std::os::raw::c_uint = 35136;
pub const SIOCSIFBR: ::std::os::raw::c_uint = 35137;
pub const SIOCGIFTXQLEN: ::std::os::raw::c_uint = 35138;
pub const SIOCSIFTXQLEN: ::std::os::raw::c_uint = 35139;
pub const SIOCETHTOOL: ::std::os::raw::c_uint = 35142;
pub const SIOCGMIIPHY: ::std::os::raw::c_uint = 35143;
pub const SIOCGMIIREG: ::std::os::raw::c_uint = 35144;
pub const SIOCSMIIREG: ::std::os::raw::c_uint = 35145;
pub const SIOCWANDEV: ::std::os::raw::c_uint = 35146;
pub const SIOCOUTQNSD: ::std::os::raw::c_uint = 35147;
pub const SIOCGSKNS: ::std::os::raw::c_uint = 35148;
pub const SIOCDARP: ::std::os::raw::c_uint = 35155;
pub const SIOCGARP: ::std::os::raw::c_uint = 35156;
pub const SIOCSARP: ::std::os::raw::c_uint = 35157;
pub const SIOCDRARP: ::std::os::raw::c_uint = 35168;
pub const SIOCGRARP: ::std::os::raw::c_uint = 35169;
pub const SIOCSRARP: ::std::os::raw::c_uint = 35170;
pub const SIOCGIFMAP: ::std::os::raw::c_uint = 35184;
pub const SIOCSIFMAP: ::std::os::raw::c_uint = 35185;
pub const SIOCADDDLCI: ::std::os::raw::c_uint = 35200;
pub const SIOCDELDLCI: ::std::os::raw::c_uint = 35201;
pub const SIOCGIFVLAN: ::std::os::raw::c_uint = 35202;
pub const SIOCSIFVLAN: ::std::os::raw::c_uint = 35203;
pub const SIOCBONDENSLAVE: ::std::os::raw::c_uint = 35216;
pub const SIOCBONDRELEASE: ::std::os::raw::c_uint = 35217;
pub const SIOCBONDSETHWADDR: ::std::os::raw::c_uint = 35218;
pub const SIOCBONDSLAVEINFOQUERY: ::std::os::raw::c_uint = 35219;
pub const SIOCBONDINFOQUERY: ::std::os::raw::c_uint = 35220;
pub const SIOCBONDCHANGEACTIVE: ::std::os::raw::c_uint = 35221;
pub const SIOCBRADDBR: ::std::os::raw::c_uint = 35232;
pub const SIOCBRDELBR: ::std::os::raw::c_uint = 35233;
pub const SIOCBRADDIF: ::std::os::raw::c_uint = 35234;
pub const SIOCBRDELIF: ::std::os::raw::c_uint = 35235;
pub const SIOCSHWTSTAMP: ::std::os::raw::c_uint = 35248;
pub const SIOCGHWTSTAMP: ::std::os::raw::c_uint = 35249;
pub const SIOCDEVPRIVATE: ::std::os::raw::c_uint = 35312;
pub const SIOCPROTOPRIVATE: ::std::os::raw::c_uint = 35296;

16
net_util/Cargo.toml Normal file
View File

@ -0,0 +1,16 @@
[package]
name = "net_util"
version = "0.1.0"
authors = ["The Chromium OS Authors"]
[dependencies]
libc = ">=0.2.39"
serde = ">=1.0.27"
net_gen = { path = "../net_gen" }
vmm-sys-util = { git = "https://github.com/sameo/vmm-sys-util" }
[dev-dependencies]
lazy_static = ">=1.1.0"
pnet = "=0.21.0"
serde_json = ">=1.0.9"

87
net_util/src/lib.rs Normal file
View File

@ -0,0 +1,87 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
// This is only used by the tests module from tap.rs, but we cannot use #[macro_use] unless the
// reference to lazy_static is declared at the root level of the importing crate.
#[cfg(test)]
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate serde;
extern crate net_gen;
extern crate vmm_sys_util;
mod mac;
mod tap;
use std::io::Error as IoError;
use std::mem;
use std::net;
use std::os::unix::io::FromRawFd;
pub use mac::{MacAddr, MAC_ADDR_LEN};
pub use tap::{Error as TapError, Tap};
#[derive(Debug)]
pub enum Error {
/// Failed to create a socket.
CreateSocket(IoError),
}
pub type Result<T> = std::result::Result<T, Error>;
/// Create a sockaddr_in from an IPv4 address, and expose it as
/// an opaque sockaddr suitable for usage by socket ioctls.
fn create_sockaddr(ip_addr: net::Ipv4Addr) -> net_gen::sockaddr {
// IPv4 addresses big-endian (network order), but Ipv4Addr will give us
// a view of those bytes directly so we can avoid any endian trickiness.
let addr_in = net_gen::sockaddr_in {
sin_family: net_gen::AF_INET as u16,
sin_port: 0,
sin_addr: unsafe { mem::transmute(ip_addr.octets()) },
__pad: [0; 8usize],
};
unsafe { mem::transmute(addr_in) }
}
fn create_socket() -> Result<net::UdpSocket> {
// This is safe since we check the return value.
let sock = unsafe { libc::socket(libc::AF_INET, libc::SOCK_DGRAM, 0) };
if sock < 0 {
return Err(Error::CreateSocket(IoError::last_os_error()));
}
// This is safe; nothing else will use or hold onto the raw sock fd.
Ok(unsafe { net::UdpSocket::from_raw_fd(sock) })
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_sockaddr() {
let addr: net::Ipv4Addr = "10.0.0.1".parse().unwrap();
let sockaddr = create_sockaddr(addr);
assert_eq!(sockaddr.sa_family, net_gen::AF_INET as u16);
let data = &sockaddr.sa_data[..];
// The first two bytes should represent the port, which is 0.
assert_eq!(data[0], 0);
assert_eq!(data[1], 0);
// The next four bytes should represent the actual IPv4 address, in network order.
assert_eq!(data[2], 10);
assert_eq!(data[3], 0);
assert_eq!(data[4], 0);
assert_eq!(data[5], 1);
}
}

149
net_util/src/mac.rs Normal file
View File

@ -0,0 +1,149 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use std::result::Result;
use serde::de::{Deserialize, Deserializer, Error};
use serde::ser::{Serialize, Serializer};
pub const MAC_ADDR_LEN: usize = 6;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct MacAddr {
bytes: [u8; MAC_ADDR_LEN],
}
impl MacAddr {
// The error contains the str that failed to be parsed, for nicer error message generation.
pub fn parse_str<S>(s: &S) -> Result<MacAddr, &str>
where
S: AsRef<str> + ?Sized,
{
let v: Vec<&str> = s.as_ref().split(':').collect();
let mut bytes = [0u8; MAC_ADDR_LEN];
if v.len() != MAC_ADDR_LEN {
return Err(s.as_ref());
}
for i in 0..MAC_ADDR_LEN {
if v[i].len() != 2 {
return Err(s.as_ref());
}
bytes[i] = u8::from_str_radix(v[i], 16).map_err(|_| s.as_ref())?;
}
Ok(MacAddr { bytes })
}
// Does not check whether src.len() == MAC_ADDR_LEN.
#[inline]
pub fn from_bytes_unchecked(src: &[u8]) -> MacAddr {
// TODO: using something like std::mem::uninitialized could avoid the extra initialization,
// if this ever becomes a performance bottleneck.
let mut bytes = [0u8; MAC_ADDR_LEN];
bytes[..].copy_from_slice(&src[..]);
MacAddr { bytes }
}
// An error can only occur if the slice length is different from MAC_ADDR_LEN.
#[inline]
pub fn from_bytes(src: &[u8]) -> Result<MacAddr, ()> {
if src.len() != MAC_ADDR_LEN {
return Err(());
}
Ok(MacAddr::from_bytes_unchecked(src))
}
#[inline]
pub fn get_bytes(&self) -> &[u8] {
&self.bytes
}
pub fn to_string(self) -> String {
let b = &self.bytes;
format!(
"{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
b[0], b[1], b[2], b[3], b[4], b[5]
)
}
}
impl Serialize for MacAddr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.to_string().serialize(serializer)
}
}
impl<'de> Deserialize<'de> for MacAddr {
fn deserialize<D>(deserializer: D) -> Result<MacAddr, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
MacAddr::parse_str(&s).map_err(|_| D::Error::custom("The provided MAC address is invalid."))
}
}
#[cfg(test)]
mod tests {
extern crate serde_json;
use super::*;
#[test]
fn test_mac_addr() {
// too long
assert!(MacAddr::parse_str("aa:aa:aa:aa:aa:aa:aa").is_err());
// invalid hex
assert!(MacAddr::parse_str("aa:aa:aa:aa:aa:ax").is_err());
// single digit mac address component should be invalid
assert!(MacAddr::parse_str("aa:aa:aa:aa:aa:b").is_err());
// components with more than two digits should also be invalid
assert!(MacAddr::parse_str("aa:aa:aa:aa:aa:bbb").is_err());
let mac = MacAddr::parse_str("12:34:56:78:9a:BC").unwrap();
println!("parsed MAC address: {}", mac.to_string());
let bytes = mac.get_bytes();
assert_eq!(bytes, [0x12u8, 0x34, 0x56, 0x78, 0x9a, 0xbc]);
}
#[test]
fn test_from_bytes() {
let src1 = [0x01, 0x02, 0x03, 0x04, 0x05];
let src2 = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06];
let src3 = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
assert!(MacAddr::from_bytes(&src1[..]).is_err());
let x = MacAddr::from_bytes(&src2[..]).unwrap();
assert_eq!(x.to_string(), String::from("01:02:03:04:05:06"));
assert!(MacAddr::from_bytes(&src3[..]).is_err());
}
#[test]
fn test_mac_addr_serialization_and_deserialization() {
let mac: MacAddr =
serde_json::from_str("\"12:34:56:78:9a:bc\"").expect("MacAddr deserialization failed.");
let bytes = mac.get_bytes();
assert_eq!(bytes, [0x12u8, 0x34, 0x56, 0x78, 0x9a, 0xbc]);
let s = serde_json::to_string(&mac).expect("MacAddr serialization failed.");
assert_eq!(s, "\"12:34:56:78:9a:bc\"");
}
}

586
net_util/src/tap.rs Normal file
View File

@ -0,0 +1,586 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use std::fs::File;
use std::io::{Error as IoError, Read, Result as IoResult, Write};
use std::net;
use std::os::raw::*;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use super::{create_sockaddr, create_socket, Error as NetUtilError};
use libc;
use net_gen;
use vmm_sys_util::ioctl::{ioctl_with_mut_ref, ioctl_with_ref, ioctl_with_val};
#[derive(Debug)]
pub enum Error {
/// Couldn't open /dev/net/tun.
OpenTun(IoError),
/// Unable to create tap interface.
CreateTap(IoError),
/// ioctl failed.
IoctlError(IoError),
/// Failed to create a socket.
NetUtil(NetUtilError),
InvalidIfname,
}
pub type Result<T> = ::std::result::Result<T, Error>;
/// Handle for a network tap interface.
///
/// For now, this simply wraps the file descriptor for the tap device so methods
/// can run ioctls on the interface. The tap interface fd will be closed when
/// Tap goes out of scope, and the kernel will clean up the interface
/// automatically.
#[derive(Debug)]
pub struct Tap {
tap_file: File,
if_name: [u8; 16usize],
}
impl PartialEq for Tap {
fn eq(&self, other: &Tap) -> bool {
self.if_name == other.if_name
}
}
// Returns a byte vector representing the contents of a null terminated C string which
// contains if_name.
fn build_terminated_if_name(if_name: &str) -> Result<Vec<u8>> {
// Convert the string slice to bytes, and shadow the variable,
// since we no longer need the &str version.
let if_name = if_name.as_bytes();
// TODO: the 16usize limit of the if_name member from struct Tap is pretty arbitrary.
// We leave it as is for now, but this should be refactored at some point.
if if_name.len() > 15 {
return Err(Error::InvalidIfname);
}
let mut terminated_if_name = vec![b'\0'; if_name.len() + 1];
terminated_if_name[..if_name.len()].copy_from_slice(if_name);
Ok(terminated_if_name)
}
impl Tap {
pub fn open_named(if_name: &str) -> Result<Tap> {
let terminated_if_name = build_terminated_if_name(if_name)?;
let fd = unsafe {
// Open calls are safe because we give a constant null-terminated
// string and verify the result.
libc::open(
b"/dev/net/tun\0".as_ptr() as *const c_char,
libc::O_RDWR | libc::O_NONBLOCK | libc::O_CLOEXEC,
)
};
if fd < 0 {
return Err(Error::OpenTun(IoError::last_os_error()));
}
// We just checked that the fd is valid.
let tuntap = unsafe { File::from_raw_fd(fd) };
// This is pretty messy because of the unions used by ifreq. Since we
// don't call as_mut on the same union field more than once, this block
// is safe.
let mut ifreq: net_gen::ifreq = Default::default();
unsafe {
let ifrn_name = ifreq.ifr_ifrn.ifrn_name.as_mut();
let ifru_flags = ifreq.ifr_ifru.ifru_flags.as_mut();
let name_slice = &mut ifrn_name[..terminated_if_name.len()];
name_slice.copy_from_slice(terminated_if_name.as_slice());
*ifru_flags =
(net_gen::IFF_TAP | net_gen::IFF_NO_PI | net_gen::IFF_VNET_HDR) as c_short;
}
// ioctl is safe since we call it with a valid tap fd and check the return
// value.
let ret = unsafe { ioctl_with_mut_ref(&tuntap, net_gen::TUNSETIFF(), &mut ifreq) };
if ret < 0 {
return Err(Error::CreateTap(IoError::last_os_error()));
}
// Safe since only the name is accessed, and it's cloned out.
Ok(Tap {
tap_file: tuntap,
if_name: unsafe { *ifreq.ifr_ifrn.ifrn_name.as_ref() },
})
}
/// Create a new tap interface.
pub fn new() -> Result<Tap> {
Self::open_named("vmtap%d")
}
/// Set the host-side IP address for the tap interface.
pub fn set_ip_addr(&self, ip_addr: net::Ipv4Addr) -> Result<()> {
let sock = create_socket().map_err(Error::NetUtil)?;
let addr = create_sockaddr(ip_addr);
let mut ifreq = self.get_ifreq();
// We only access one field of the ifru union, hence this is safe.
unsafe {
let ifru_addr = ifreq.ifr_ifru.ifru_addr.as_mut();
*ifru_addr = addr;
}
// ioctl is safe. Called with a valid sock fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFADDR as c_ulong, &ifreq) };
if ret < 0 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
Ok(())
}
/// Set the netmask for the subnet that the tap interface will exist on.
pub fn set_netmask(&self, netmask: net::Ipv4Addr) -> Result<()> {
let sock = create_socket().map_err(Error::NetUtil)?;
let addr = create_sockaddr(netmask);
let mut ifreq = self.get_ifreq();
// We only access one field of the ifru union, hence this is safe.
unsafe {
let ifru_addr = ifreq.ifr_ifru.ifru_addr.as_mut();
*ifru_addr = addr;
}
// ioctl is safe. Called with a valid sock fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFNETMASK as c_ulong, &ifreq) };
if ret < 0 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
Ok(())
}
/// Set the offload flags for the tap interface.
pub fn set_offload(&self, flags: c_uint) -> Result<()> {
// ioctl is safe. Called with a valid tap fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_val(&self.tap_file, net_gen::TUNSETOFFLOAD(), flags as c_ulong) };
if ret < 0 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
Ok(())
}
/// Enable the tap interface.
pub fn enable(&self) -> Result<()> {
let sock = create_socket().map_err(Error::NetUtil)?;
let mut ifreq = self.get_ifreq();
// We only access one field of the ifru union, hence this is safe.
unsafe {
let ifru_flags = ifreq.ifr_ifru.ifru_flags.as_mut();
*ifru_flags =
(net_gen::net_device_flags_IFF_UP | net_gen::net_device_flags_IFF_RUNNING) as i16;
}
// ioctl is safe. Called with a valid sock fd, and we check the return.
#[allow(clippy::cast_lossless)]
let ret =
unsafe { ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFFLAGS as c_ulong, &ifreq) };
if ret < 0 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
Ok(())
}
/// Set the size of the vnet hdr.
pub fn set_vnet_hdr_size(&self, size: c_int) -> Result<()> {
// ioctl is safe. Called with a valid tap fd, and we check the return.
let ret = unsafe { ioctl_with_ref(&self.tap_file, net_gen::TUNSETVNETHDRSZ(), &size) };
if ret < 0 {
return Err(Error::IoctlError(IoError::last_os_error()));
}
Ok(())
}
fn get_ifreq(&self) -> net_gen::ifreq {
let mut ifreq: net_gen::ifreq = Default::default();
// This sets the name of the interface, which is the only entry
// in a single-field union.
unsafe {
let ifrn_name = ifreq.ifr_ifrn.ifrn_name.as_mut();
ifrn_name.clone_from_slice(&self.if_name);
}
ifreq
}
}
impl Read for Tap {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
self.tap_file.read(buf)
}
}
impl Write for Tap {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
self.tap_file.write(&buf)
}
fn flush(&mut self) -> IoResult<()> {
Ok(())
}
}
impl AsRawFd for Tap {
fn as_raw_fd(&self) -> RawFd {
self.tap_file.as_raw_fd()
}
}
#[cfg(test)]
mod tests {
extern crate pnet;
use std::net::Ipv4Addr;
use std::str;
use std::sync::{mpsc, Mutex};
use std::thread;
use std::time::Duration;
use self::pnet::datalink::Channel::Ethernet;
use self::pnet::datalink::{self, DataLinkReceiver, DataLinkSender, NetworkInterface};
use self::pnet::packet::ethernet::{EtherTypes, EthernetPacket, MutableEthernetPacket};
use self::pnet::packet::ip::IpNextHeaderProtocols;
use self::pnet::packet::ipv4::{Ipv4Packet, MutableIpv4Packet};
use self::pnet::packet::udp::{MutableUdpPacket, UdpPacket};
use self::pnet::packet::{MutablePacket, Packet};
use self::pnet::util::MacAddr;
use super::*;
static DATA_STRING: &str = "test for tap";
static SUBNET_MASK: &str = "255.255.255.0";
// We needed to have a mutex as a global variable, so we used the crate that provides the
// lazy_static! macro for testing. The main potential problem, caused by tests being run in
// parallel by cargo, is creating different TAPs and trying to associate the same address,
// so we hide the IP address &str behind this mutex, more as a convention to remember to lock
// it at the very beginning of each function susceptible to this issue. Another variant is
// to use a different IP address per function, but we must remember to pick an unique one
// each time.
lazy_static! {
static ref TAP_IP_LOCK: Mutex<&'static str> = Mutex::new("192.168.241.1");
}
// Describes the outcomes we are currently interested in when parsing a packet (we use
// an UDP packet for testing).
struct ParsedPkt<'a> {
eth: EthernetPacket<'a>,
ipv4: Option<Ipv4Packet<'a>>,
udp: Option<UdpPacket<'a>>,
}
impl<'a> ParsedPkt<'a> {
fn new(buf: &'a [u8]) -> Self {
let eth = EthernetPacket::new(buf).unwrap();
let mut ipv4 = None;
let mut udp = None;
if eth.get_ethertype() == EtherTypes::Ipv4 {
let ipv4_start = 14;
ipv4 = Some(Ipv4Packet::new(&buf[ipv4_start..]).unwrap());
// Hiding the old ipv4 variable for the rest of this block.
let ipv4 = Ipv4Packet::new(eth.payload()).unwrap();
if ipv4.get_next_level_protocol() == IpNextHeaderProtocols::Udp {
// The value in header_length indicates the number of 32 bit words
// that make up the header, not the actual length in bytes.
let udp_start = ipv4_start + ipv4.get_header_length() as usize * 4;
udp = Some(UdpPacket::new(&buf[udp_start..]).unwrap());
}
}
ParsedPkt { eth, ipv4, udp }
}
fn print(&self) {
print!(
"{} {} {} ",
self.eth.get_source(),
self.eth.get_destination(),
self.eth.get_ethertype()
);
if let Some(ref ipv4) = self.ipv4 {
print!(
"{} {} {} ",
ipv4.get_source(),
ipv4.get_destination(),
ipv4.get_next_level_protocol()
);
}
if let Some(ref udp) = self.udp {
print!(
"{} {} {}",
udp.get_source(),
udp.get_destination(),
str::from_utf8(udp.payload()).unwrap()
);
}
println!();
}
}
fn tap_name_to_string(tap: &Tap) -> String {
let null_pos = tap.if_name.iter().position(|x| *x == 0).unwrap();
str::from_utf8(&tap.if_name[..null_pos])
.unwrap()
.to_string()
}
// Given a buffer of appropriate size, this fills in the relevant fields based on the
// provided information. Payload refers to the UDP payload.
fn pnet_build_packet(buf: &mut [u8], dst_mac: MacAddr, payload: &[u8]) {
let mut eth = MutableEthernetPacket::new(buf).unwrap();
eth.set_source(MacAddr::new(0x06, 0, 0, 0, 0, 0));
eth.set_destination(dst_mac);
eth.set_ethertype(EtherTypes::Ipv4);
let mut ipv4 = MutableIpv4Packet::new(eth.payload_mut()).unwrap();
ipv4.set_version(4);
ipv4.set_header_length(5);
ipv4.set_total_length(20 + 8 + payload.len() as u16);
ipv4.set_ttl(200);
ipv4.set_next_level_protocol(IpNextHeaderProtocols::Udp);
ipv4.set_source(Ipv4Addr::new(192, 168, 241, 1));
ipv4.set_destination(Ipv4Addr::new(192, 168, 241, 2));
let mut udp = MutableUdpPacket::new(ipv4.payload_mut()).unwrap();
udp.set_source(1000);
udp.set_destination(1001);
udp.set_length(8 + payload.len() as u16);
udp.set_payload(payload);
}
// Sends a test packet on the interface named "ifname".
fn pnet_send_packet(ifname: String) {
let payload = DATA_STRING.as_bytes();
// eth hdr + ip hdr + udp hdr + payload len
let buf_size = 14 + 20 + 8 + payload.len();
let (mac, mut tx, _) = pnet_get_mac_tx_rx(ifname);
let res = tx.build_and_send(1, buf_size, &mut |buf| {
pnet_build_packet(buf, mac, payload);
});
// Make sure build_and_send() -> Option<io::Result<()>> succeeds.
res.unwrap().unwrap();
}
// For a given interface name, this returns a tuple that contains the MAC address of the
// interface, an object that can be used to send Ethernet frames, and a receiver of
// Ethernet frames arriving at the specified interface.
fn pnet_get_mac_tx_rx(ifname: String) -> (MacAddr, Box<DataLinkSender>, Box<DataLinkReceiver>) {
let interface_name_matches = |iface: &NetworkInterface| iface.name == ifname;
// Find the network interface with the provided name.
let interfaces = datalink::interfaces();
let interface = interfaces.into_iter().find(interface_name_matches).unwrap();
if let Ok(Ethernet(tx, rx)) = datalink::channel(&interface, Default::default()) {
(interface.mac_address(), tx, rx)
} else {
panic!("datalink channel error or unhandled channel type");
}
}
#[test]
fn test_tap_create() {
let t = Tap::new().unwrap();
println!("created tap: {:?}", t);
}
#[test]
fn test_tap_configure() {
// This should be the first thing to be called inside the function, so everything else
// is torn down by the time the mutex is automatically released. Also, we should
// explicitly bind the MutexGuard to a variable via let, the make sure it lives until
// the end of the function.
let tap_ip_guard = TAP_IP_LOCK.lock().unwrap();
let tap = Tap::new().unwrap();
let ip_addr: net::Ipv4Addr = (*tap_ip_guard).parse().unwrap();
let netmask: net::Ipv4Addr = SUBNET_MASK.parse().unwrap();
let ret = tap.set_ip_addr(ip_addr);
assert!(ret.is_ok());
let ret = tap.set_netmask(netmask);
assert!(ret.is_ok());
}
#[test]
fn test_set_options() {
// This line will fail to provide an initialized FD if the test is not run as root.
let tap = Tap::new().unwrap();
tap.set_vnet_hdr_size(16).unwrap();
tap.set_offload(0).unwrap();
}
#[test]
fn test_tap_enable() {
let tap = Tap::new().unwrap();
let ret = tap.enable();
assert!(ret.is_ok());
}
#[test]
fn test_tap_get_ifreq() {
let tap = Tap::new().unwrap();
let ret = tap.get_ifreq();
assert_eq!(
"__BindgenUnionField",
format!("{:?}", ret.ifr_ifrn.ifrn_name)
);
}
#[test]
fn test_raw_fd() {
let tap = Tap::new().unwrap();
assert_eq!(tap.as_raw_fd(), tap.tap_file.as_raw_fd());
}
#[test]
fn test_read() {
let tap_ip_guard = TAP_IP_LOCK.lock().unwrap();
let mut tap = Tap::new().unwrap();
tap.set_ip_addr((*tap_ip_guard).parse().unwrap()).unwrap();
tap.set_netmask(SUBNET_MASK.parse().unwrap()).unwrap();
tap.enable().unwrap();
// Send a packet to the interface. We expect to be able to receive it on the associated fd.
pnet_send_packet(tap_name_to_string(&tap));
let mut buf = [0u8; 4096];
let mut found_packet_sz = None;
// In theory, this could actually loop forever if something keeps sending data through the
// tap interface, but it's highly unlikely.
while found_packet_sz.is_none() {
let result = tap.read(&mut buf);
assert!(result.is_ok());
let size = result.unwrap();
// We skip the first 10 bytes because the IFF_VNET_HDR flag is set when the interface
// is created, and the legacy header is 10 bytes long without a certain flag which
// is not set in Tap::new().
let eth_bytes = &buf[10..size];
let packet = EthernetPacket::new(eth_bytes).unwrap();
if packet.get_ethertype() != EtherTypes::Ipv4 {
// not an IPv4 packet
continue;
}
let ipv4_bytes = &eth_bytes[14..];
let packet = Ipv4Packet::new(ipv4_bytes).unwrap();
// Our packet should carry an UDP payload, and not contain IP options.
if packet.get_next_level_protocol() != IpNextHeaderProtocols::Udp
&& packet.get_header_length() != 5
{
continue;
}
let udp_bytes = &ipv4_bytes[20..];
let udp_len = UdpPacket::new(udp_bytes).unwrap().get_length() as usize;
// Skip the header bytes.
let inner_string = str::from_utf8(&udp_bytes[8..udp_len]).unwrap();
if inner_string.eq(DATA_STRING) {
found_packet_sz = Some(size);
break;
}
}
assert!(found_packet_sz.is_some());
}
#[test]
fn test_write() {
let tap_ip_guard = TAP_IP_LOCK.lock().unwrap();
let mut tap = Tap::new().unwrap();
tap.set_ip_addr((*tap_ip_guard).parse().unwrap()).unwrap();
tap.set_netmask(SUBNET_MASK.parse().unwrap()).unwrap();
tap.enable().unwrap();
let (mac, _, mut rx) = pnet_get_mac_tx_rx(tap_name_to_string(&tap));
let payload = DATA_STRING.as_bytes();
// vnet hdr + eth hdr + ip hdr + udp hdr + payload len
let buf_size = 10 + 14 + 20 + 8 + payload.len();
let mut buf = vec![0u8; buf_size];
// leave the vnet hdr as is
pnet_build_packet(&mut buf[10..], mac, payload);
assert!(tap.write(&buf[..]).is_ok());
assert!(tap.flush().is_ok());
let (channel_tx, channel_rx) = mpsc::channel();
// We use a separate thread to wait for the test packet because the API exposed by pnet is
// blocking. This thread will be killed when the main thread exits.
let _handle = thread::spawn(move || loop {
let buf = rx.next().unwrap();
let p = ParsedPkt::new(buf);
p.print();
if let Some(ref udp) = p.udp {
if payload == udp.payload() {
channel_tx.send(true).unwrap();
break;
}
}
});
// We wait for at most SLEEP_MILLIS * SLEEP_ITERS milliseconds for the reception of the
// test packet to be detected.
static SLEEP_MILLIS: u64 = 500;
static SLEEP_ITERS: u32 = 6;
let mut found_test_packet = false;
for _ in 0..SLEEP_ITERS {
thread::sleep(Duration::from_millis(SLEEP_MILLIS));
if let Ok(true) = channel_rx.try_recv() {
found_test_packet = true;
break;
}
}
assert!(found_test_packet);
}
}