From e65cbf2908fa255ac77e3352c053dfa78abdbeea Mon Sep 17 00:00:00 2001 From: hejiaqi Date: Mon, 26 May 2025 16:27:24 +0800 Subject: [PATCH] feat(ref #1): add new source for LLDP --- Cargo.lock | 60 +- Cargo.toml | 5 + build.rs | 17 + distribution/docker/debian/Dockerfile | 2 +- .../cross/x86_64-unknown-linux-gnu.dockerfile | 23 +- src/sources/lldp/bindings.rs | 1637 +++++++++++++++++ src/sources/lldp/ffi.rs | 247 +++ src/sources/lldp/mod.rs | 202 ++ src/sources/lldp/wrapper.h | 1 + src/sources/mod.rs | 2 + 10 files changed, 2190 insertions(+), 6 deletions(-) create mode 100644 src/sources/lldp/bindings.rs create mode 100644 src/sources/lldp/ffi.rs create mode 100644 src/sources/lldp/mod.rs create mode 100644 src/sources/lldp/wrapper.h diff --git a/Cargo.lock b/Cargo.lock index bac185081e193..0fc8c206e269c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1737,6 +1737,26 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bindgen" +version = "0.71.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +dependencies = [ + "bitflags 2.9.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease 0.2.15", + "proc-macro2 1.0.94", + "quote 1.0.40", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.100", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -2088,6 +2108,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfb-mode" version = "0.8.2" @@ -2224,6 +2253,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.35" @@ -5761,6 +5801,16 @@ dependencies = [ "rle-decode-fast", ] +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + [[package]] name = "libm" version = "0.2.8" @@ -7410,9 +7460,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "platforms" @@ -8814,9 +8864,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_version" @@ -11429,6 +11479,7 @@ dependencies = [ "azure_storage", "azure_storage_blobs", "base64 0.22.1", + "bindgen", "bloomy", "bollard", "byteorder", @@ -11559,6 +11610,7 @@ dependencies = [ "test-generator", "thread_local", "tikv-jemallocator", + "time", "tokio", "tokio-openssl", "tokio-postgres", diff --git a/Cargo.toml b/Cargo.toml index 503132c85f507..497f6fe0354f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -353,6 +353,7 @@ ipnet = { version = "2", default-features = false, optional = true, features = [ itertools = { version = "0.14.0", default-features = false, optional = false, features = ["use_alloc"] } k8s-openapi = { version = "0.22.0", default-features = false, features = ["v1_26"], optional = true } kube = { version = "0.93.0", default-features = false, features = ["client", "openssl-tls", "runtime"], optional = true } +libc = "0.2.171" listenfd = { version = "1.0.2", default-features = false, optional = true } lru = { version = "0.13.0", default-features = false, optional = true } maxminddb = { version = "0.26.0", default-features = false, optional = true, features = ["simdutf8"] } @@ -405,6 +406,7 @@ heim = { git = "https://github.com/vectordotdev/heim.git", branch = "update-nix" mlua = { version = "0.10.3", default-features = false, features = ["lua54", "send", "vendored", "macros"], optional = true } sysinfo = "0.34.2" byteorder = "1.5.0" +time = "0.3.36" [target.'cfg(windows)'.dependencies] windows-service = "0.7.0" @@ -419,6 +421,7 @@ netlink-packet-core = "0.7.0" netlink-sys = { version = "0.8.7", features = ["tokio_socket"] } [build-dependencies] +bindgen = "0.71.1" prost-build = { workspace = true, optional = true } tonic-build = { workspace = true, optional = true } # update 'openssl_version' in website/config.toml whenever version changes @@ -605,6 +608,7 @@ sources-metrics = [ "sources-static_metrics", "sources-statsd", "sources-vector", + "sources-lldp", ] sources-amqp = ["lapin"] @@ -634,6 +638,7 @@ sources-journald = [] sources-kafka = ["dep:rdkafka"] sources-kubernetes_logs = ["vector-lib/file-source", "kubernetes", "transforms-reduce"] sources-logstash = ["sources-utils-net-tcp", "tokio-util/net"] +sources-lldp = [] sources-mongodb_metrics = ["dep:mongodb"] sources-nats = ["dep:async-nats", "dep:nkeys"] sources-nginx_metrics = ["dep:nom"] diff --git a/build.rs b/build.rs index b603074f90bcc..2f14f6d041c9c 100644 --- a/build.rs +++ b/build.rs @@ -110,6 +110,23 @@ fn main() { // Always rerun if the build script itself changes. println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu"); + println!("cargo:rustc-link-lib=dylib=lldpctl"); + + println!("cargo:rerun-if-changed=src/sources/lldp/wrapper.h"); + + // 生成 lldpctl bindings + let lldp_bindings = bindgen::Builder::default() + .header("src/sources/lldp/wrapper.h") // 你要创建这个 wrapper.h + .clang_arg("-I/usr/include/") // 可能需要根据实际 lldp 安装路径添加 + .layout_tests(false) + .generate() + .expect("Unable to generate lldpctl bindings"); + + lldp_bindings + .write_to_file("src/sources/lldp/bindings.rs") + .expect("Couldn't write lldpctl bindings!"); + // re-run if the HEAD has changed. This is only necessary for non-release and nightly builds. #[cfg(not(feature = "nightly"))] println!("cargo:rerun-if-changed=.git/HEAD"); diff --git a/distribution/docker/debian/Dockerfile b/distribution/docker/debian/Dockerfile index f037a7f06e62a..694a958570a1a 100644 --- a/distribution/docker/debian/Dockerfile +++ b/distribution/docker/debian/Dockerfile @@ -16,7 +16,7 @@ LABEL org.opencontainers.image.documentation="https://vector.dev/docs" # we want the latest versions of these # hadolint ignore=DL3008 -RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates tzdata systemd && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates tzdata systemd liblldpctl-dev && rm -rf /var/lib/apt/lists/* COPY --from=builder /usr/bin/vector /usr/bin/vector COPY --from=builder /usr/share/vector /usr/share/vector diff --git a/scripts/cross/x86_64-unknown-linux-gnu.dockerfile b/scripts/cross/x86_64-unknown-linux-gnu.dockerfile index aabbd92c25249..78c5440ad30ae 100644 --- a/scripts/cross/x86_64-unknown-linux-gnu.dockerfile +++ b/scripts/cross/x86_64-unknown-linux-gnu.dockerfile @@ -1,4 +1,25 @@ FROM ghcr.io/cross-rs/x86_64-unknown-linux-gnu:0.2.5 +RUN apt-get update && apt-get install -y \ + apt-transport-https \ + ca-certificates \ + wget \ + gnupg \ + software-properties-common \ + && rm -rf /var/lib/apt/lists/* + +RUN sed -i \ + -e 's|http://[^/]*/ubuntu|https://mirrors.tuna.tsinghua.edu.cn/ubuntu|g' \ + /etc/apt/sources.list + +RUN apt-get update && apt-get install -y \ + liblldpctl-dev \ + pkg-config \ + build-essential \ + libc6-dev \ + libclang-dev \ + clang \ + && rm -rf /var/lib/apt/lists/* + COPY scripts/cross/bootstrap-ubuntu.sh scripts/environment/install-protoc.sh / -RUN /bootstrap-ubuntu.sh && bash /install-protoc.sh +RUN /bootstrap-ubuntu.sh && bash /install-protoc.sh \ No newline at end of file diff --git a/src/sources/lldp/bindings.rs b/src/sources/lldp/bindings.rs new file mode 100644 index 0000000000000..2356c42a29a20 --- /dev/null +++ b/src/sources/lldp/bindings.rs @@ -0,0 +1,1637 @@ +/* automatically generated by rust-bindgen 0.71.1 */ + +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + fn extract_bit(byte: u8, index: usize) -> bool { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = *(core::ptr::addr_of!((*this).storage) as *const u8).offset(byte_index as isize); + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + byte | mask + } else { + byte & !mask + } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = + (core::ptr::addr_of_mut!((*this).storage) as *mut u8).offset(byte_index as isize); + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::()); + let mut val = 0; + for i in 0..(bit_width as usize) { + if Self::raw_get_bit(this, i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::()); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + Self::raw_set_bit(this, index + bit_offset, val_bit_is_set); + } + } +} +pub const _FEATURES_H: u32 = 1; +pub const _DEFAULT_SOURCE: u32 = 1; +pub const __USE_ISOC11: u32 = 1; +pub const __USE_ISOC99: u32 = 1; +pub const __USE_ISOC95: u32 = 1; +pub const __USE_POSIX_IMPLICITLY: u32 = 1; +pub const _POSIX_SOURCE: u32 = 1; +pub const _POSIX_C_SOURCE: u32 = 200809; +pub const __USE_POSIX: u32 = 1; +pub const __USE_POSIX2: u32 = 1; +pub const __USE_POSIX199309: u32 = 1; +pub const __USE_POSIX199506: u32 = 1; +pub const __USE_XOPEN2K: u32 = 1; +pub const __USE_XOPEN2K8: u32 = 1; +pub const _ATFILE_SOURCE: u32 = 1; +pub const __USE_MISC: u32 = 1; +pub const __USE_ATFILE: u32 = 1; +pub const __USE_FORTIFY_LEVEL: u32 = 0; +pub const _STDC_PREDEF_H: u32 = 1; +pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_ISO_10646__: u32 = 201505; +pub const __STDC_NO_THREADS__: u32 = 1; +pub const __GNU_LIBRARY__: u32 = 6; +pub const __GLIBC__: u32 = 2; +pub const __GLIBC_MINOR__: u32 = 23; +pub const _SYS_CDEFS_H: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const _STDLIB_H: u32 = 1; +pub const WNOHANG: u32 = 1; +pub const WUNTRACED: u32 = 2; +pub const WSTOPPED: u32 = 2; +pub const WEXITED: u32 = 4; +pub const WCONTINUED: u32 = 8; +pub const WNOWAIT: u32 = 16777216; +pub const __WNOTHREAD: u32 = 536870912; +pub const __WALL: u32 = 1073741824; +pub const __WCLONE: u32 = 2147483648; +pub const __ENUM_IDTYPE_T: u32 = 1; +pub const __W_CONTINUED: u32 = 65535; +pub const __WCOREFLAG: u32 = 128; +pub const _ENDIAN_H: u32 = 1; +pub const __LITTLE_ENDIAN: u32 = 1234; +pub const __BIG_ENDIAN: u32 = 4321; +pub const __PDP_ENDIAN: u32 = 3412; +pub const __BYTE_ORDER: u32 = 1234; +pub const __FLOAT_WORD_ORDER: u32 = 1234; +pub const LITTLE_ENDIAN: u32 = 1234; +pub const BIG_ENDIAN: u32 = 4321; +pub const PDP_ENDIAN: u32 = 3412; +pub const BYTE_ORDER: u32 = 1234; +pub const _BITS_BYTESWAP_H: u32 = 1; +pub const _BITS_TYPES_H: u32 = 1; +pub const _BITS_TYPESIZES_H: u32 = 1; +pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; +pub const __INO_T_MATCHES_INO64_T: u32 = 1; +pub const __FD_SETSIZE: u32 = 1024; +pub const __ldiv_t_defined: u32 = 1; +pub const __lldiv_t_defined: u32 = 1; +pub const RAND_MAX: u32 = 2147483647; +pub const EXIT_FAILURE: u32 = 1; +pub const EXIT_SUCCESS: u32 = 0; +pub const _SYS_TYPES_H: u32 = 1; +pub const __clock_t_defined: u32 = 1; +pub const __time_t_defined: u32 = 1; +pub const __clockid_t_defined: u32 = 1; +pub const __timer_t_defined: u32 = 1; +pub const __BIT_TYPES_DEFINED__: u32 = 1; +pub const _SYS_SELECT_H: u32 = 1; +pub const __FD_ZERO_STOS: &[u8; 6] = b"stosq\0"; +pub const _SIGSET_H_types: u32 = 1; +pub const __timespec_defined: u32 = 1; +pub const _STRUCT_TIMEVAL: u32 = 1; +pub const FD_SETSIZE: u32 = 1024; +pub const _SYS_SYSMACROS_H: u32 = 1; +pub const _BITS_PTHREADTYPES_H: u32 = 1; +pub const __SIZEOF_PTHREAD_ATTR_T: u32 = 56; +pub const __SIZEOF_PTHREAD_MUTEX_T: u32 = 40; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_COND_T: u32 = 48; +pub const __SIZEOF_PTHREAD_CONDATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: u32 = 56; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: u32 = 8; +pub const __SIZEOF_PTHREAD_BARRIER_T: u32 = 32; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: u32 = 4; +pub const __have_pthread_attr_t: u32 = 1; +pub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1; +pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: u32 = 1; +pub const _ALLOCA_H: u32 = 1; +pub const _STDINT_H: u32 = 1; +pub const _BITS_WCHAR_H: u32 = 1; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; +pub const UINT8_MAX: u32 = 255; +pub const UINT16_MAX: u32 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST16_MIN: i64 = -9223372036854775808; +pub const INT_FAST32_MIN: i64 = -9223372036854775808; +pub const INT_FAST8_MAX: u32 = 127; +pub const INT_FAST16_MAX: u64 = 9223372036854775807; +pub const INT_FAST32_MAX: u64 = 9223372036854775807; +pub const UINT_FAST8_MAX: u32 = 255; +pub const UINT_FAST16_MAX: i32 = -1; +pub const UINT_FAST32_MAX: i32 = -1; +pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const UINTPTR_MAX: i32 = -1; +pub const PTRDIFF_MIN: i64 = -9223372036854775808; +pub const PTRDIFF_MAX: u64 = 9223372036854775807; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const SIZE_MAX: i32 = -1; +pub const WINT_MIN: u32 = 0; +pub const WINT_MAX: u32 = 4294967295; +pub type wchar_t = ::std::os::raw::c_int; +pub const idtype_t_P_ALL: idtype_t = 0; +pub const idtype_t_P_PID: idtype_t = 1; +pub const idtype_t_P_PGID: idtype_t = 2; +pub type idtype_t = ::std::os::raw::c_uint; +pub type __u_char = ::std::os::raw::c_uchar; +pub type __u_short = ::std::os::raw::c_ushort; +pub type __u_int = ::std::os::raw::c_uint; +pub type __u_long = ::std::os::raw::c_ulong; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_long; +pub type __uint64_t = ::std::os::raw::c_ulong; +pub type __quad_t = ::std::os::raw::c_long; +pub type __u_quad_t = ::std::os::raw::c_ulong; +pub type __dev_t = ::std::os::raw::c_ulong; +pub type __uid_t = ::std::os::raw::c_uint; +pub type __gid_t = ::std::os::raw::c_uint; +pub type __ino_t = ::std::os::raw::c_ulong; +pub type __ino64_t = ::std::os::raw::c_ulong; +pub type __mode_t = ::std::os::raw::c_uint; +pub type __nlink_t = ::std::os::raw::c_ulong; +pub type __off_t = ::std::os::raw::c_long; +pub type __off64_t = ::std::os::raw::c_long; +pub type __pid_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __fsid_t { + pub __val: [::std::os::raw::c_int; 2usize], +} +pub type __clock_t = ::std::os::raw::c_long; +pub type __rlim_t = ::std::os::raw::c_ulong; +pub type __rlim64_t = ::std::os::raw::c_ulong; +pub type __id_t = ::std::os::raw::c_uint; +pub type __time_t = ::std::os::raw::c_long; +pub type __useconds_t = ::std::os::raw::c_uint; +pub type __suseconds_t = ::std::os::raw::c_long; +pub type __daddr_t = ::std::os::raw::c_int; +pub type __key_t = ::std::os::raw::c_int; +pub type __clockid_t = ::std::os::raw::c_int; +pub type __timer_t = *mut ::std::os::raw::c_void; +pub type __blksize_t = ::std::os::raw::c_long; +pub type __blkcnt_t = ::std::os::raw::c_long; +pub type __blkcnt64_t = ::std::os::raw::c_long; +pub type __fsblkcnt_t = ::std::os::raw::c_ulong; +pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; +pub type __fsword_t = ::std::os::raw::c_long; +pub type __ssize_t = ::std::os::raw::c_long; +pub type __syscall_slong_t = ::std::os::raw::c_long; +pub type __syscall_ulong_t = ::std::os::raw::c_ulong; +pub type __loff_t = __off64_t; +pub type __qaddr_t = *mut __quad_t; +pub type __caddr_t = *mut ::std::os::raw::c_char; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __socklen_t = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Copy, Clone)] +pub union wait { + pub w_status: ::std::os::raw::c_int, + pub __wait_terminated: wait__bindgen_ty_1, + pub __wait_stopped: wait__bindgen_ty_2, +} +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Copy, Clone)] +pub struct wait__bindgen_ty_1 { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl wait__bindgen_ty_1 { + #[inline] + pub fn __w_termsig(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u32) } + } + #[inline] + pub fn set___w_termsig(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 7u8, val as u64) + } + } + #[inline] + pub unsafe fn __w_termsig_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute(<__BindgenBitfieldUnit<[u8; 4usize]>>::raw_get( + ::std::ptr::addr_of!((*this)._bitfield_1), + 0usize, + 7u8, + ) as u32) + } + } + #[inline] + pub unsafe fn set___w_termsig_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit<[u8; 4usize]>>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 7u8, + val as u64, + ) + } + } + #[inline] + pub fn __w_coredump(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } + } + #[inline] + pub fn set___w_coredump(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub unsafe fn __w_coredump_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute(<__BindgenBitfieldUnit<[u8; 4usize]>>::raw_get( + ::std::ptr::addr_of!((*this)._bitfield_1), + 7usize, + 1u8, + ) as u32) + } + } + #[inline] + pub unsafe fn set___w_coredump_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit<[u8; 4usize]>>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 7usize, + 1u8, + val as u64, + ) + } + } + #[inline] + pub fn __w_retcode(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u32) } + } + #[inline] + pub fn set___w_retcode(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub unsafe fn __w_retcode_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute(<__BindgenBitfieldUnit<[u8; 4usize]>>::raw_get( + ::std::ptr::addr_of!((*this)._bitfield_1), + 8usize, + 8u8, + ) as u32) + } + } + #[inline] + pub unsafe fn set___w_retcode_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit<[u8; 4usize]>>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 8u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_1( + __w_termsig: ::std::os::raw::c_uint, + __w_coredump: ::std::os::raw::c_uint, + __w_retcode: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 7u8, { + let __w_termsig: u32 = unsafe { ::std::mem::transmute(__w_termsig) }; + __w_termsig as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let __w_coredump: u32 = unsafe { ::std::mem::transmute(__w_coredump) }; + __w_coredump as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let __w_retcode: u32 = unsafe { ::std::mem::transmute(__w_retcode) }; + __w_retcode as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Copy, Clone)] +pub struct wait__bindgen_ty_2 { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl wait__bindgen_ty_2 { + #[inline] + pub fn __w_stopval(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u32) } + } + #[inline] + pub fn set___w_stopval(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub unsafe fn __w_stopval_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute(<__BindgenBitfieldUnit<[u8; 4usize]>>::raw_get( + ::std::ptr::addr_of!((*this)._bitfield_1), + 0usize, + 8u8, + ) as u32) + } + } + #[inline] + pub unsafe fn set___w_stopval_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit<[u8; 4usize]>>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 8u8, + val as u64, + ) + } + } + #[inline] + pub fn __w_stopsig(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u32) } + } + #[inline] + pub fn set___w_stopsig(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub unsafe fn __w_stopsig_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute(<__BindgenBitfieldUnit<[u8; 4usize]>>::raw_get( + ::std::ptr::addr_of!((*this)._bitfield_1), + 8usize, + 8u8, + ) as u32) + } + } + #[inline] + pub unsafe fn set___w_stopsig_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit<[u8; 4usize]>>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 8u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_1( + __w_stopval: ::std::os::raw::c_uint, + __w_stopsig: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 8u8, { + let __w_stopval: u32 = unsafe { ::std::mem::transmute(__w_stopval) }; + __w_stopval as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let __w_stopsig: u32 = unsafe { ::std::mem::transmute(__w_stopsig) }; + __w_stopsig as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __WAIT_STATUS { + pub __uptr: *mut wait, + pub __iptr: *mut ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct div_t { + pub quot: ::std::os::raw::c_int, + pub rem: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ldiv_t { + pub quot: ::std::os::raw::c_long, + pub rem: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lldiv_t { + pub quot: ::std::os::raw::c_longlong, + pub rem: ::std::os::raw::c_longlong, +} +unsafe extern "C" { + pub fn __ctype_get_mb_cur_max() -> usize; +} +unsafe extern "C" { + pub fn atof(__nptr: *const ::std::os::raw::c_char) -> f64; +} +unsafe extern "C" { + pub fn atoi(__nptr: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn atol(__nptr: *const ::std::os::raw::c_char) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn atoll(__nptr: *const ::std::os::raw::c_char) -> ::std::os::raw::c_longlong; +} +unsafe extern "C" { + pub fn strtod( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + ) -> f64; +} +unsafe extern "C" { + pub fn strtof( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + ) -> f32; +} +unsafe extern "C" { + pub fn strtold( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + ) -> u128; +} +unsafe extern "C" { + pub fn strtol( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn strtoul( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn strtoq( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_longlong; +} +unsafe extern "C" { + pub fn strtouq( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulonglong; +} +unsafe extern "C" { + pub fn strtoll( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_longlong; +} +unsafe extern "C" { + pub fn strtoull( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulonglong; +} +unsafe extern "C" { + pub fn l64a(__n: ::std::os::raw::c_long) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn a64l(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_long; +} +pub type u_char = __u_char; +pub type u_short = __u_short; +pub type u_int = __u_int; +pub type u_long = __u_long; +pub type quad_t = __quad_t; +pub type u_quad_t = __u_quad_t; +pub type fsid_t = __fsid_t; +pub type loff_t = __loff_t; +pub type ino_t = __ino_t; +pub type dev_t = __dev_t; +pub type gid_t = __gid_t; +pub type mode_t = __mode_t; +pub type nlink_t = __nlink_t; +pub type uid_t = __uid_t; +pub type off_t = __off_t; +pub type pid_t = __pid_t; +pub type id_t = __id_t; +pub type daddr_t = __daddr_t; +pub type caddr_t = __caddr_t; +pub type key_t = __key_t; +pub type clock_t = __clock_t; +pub type time_t = __time_t; +pub type clockid_t = __clockid_t; +pub type timer_t = __timer_t; +pub type ulong = ::std::os::raw::c_ulong; +pub type ushort = ::std::os::raw::c_ushort; +pub type uint = ::std::os::raw::c_uint; +pub type u_int8_t = ::std::os::raw::c_uchar; +pub type u_int16_t = ::std::os::raw::c_ushort; +pub type u_int32_t = ::std::os::raw::c_uint; +pub type u_int64_t = ::std::os::raw::c_ulong; +pub type register_t = ::std::os::raw::c_long; +pub type __sig_atomic_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sigset_t { + pub __val: [::std::os::raw::c_ulong; 16usize], +} +pub type sigset_t = __sigset_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timespec { + pub tv_sec: __time_t, + pub tv_nsec: __syscall_slong_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timeval { + pub tv_sec: __time_t, + pub tv_usec: __suseconds_t, +} +pub type suseconds_t = __suseconds_t; +pub type __fd_mask = ::std::os::raw::c_long; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fd_set { + pub __fds_bits: [__fd_mask; 16usize], +} +pub type fd_mask = __fd_mask; +unsafe extern "C" { + pub fn select( + __nfds: ::std::os::raw::c_int, + __readfds: *mut fd_set, + __writefds: *mut fd_set, + __exceptfds: *mut fd_set, + __timeout: *mut timeval, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn pselect( + __nfds: ::std::os::raw::c_int, + __readfds: *mut fd_set, + __writefds: *mut fd_set, + __exceptfds: *mut fd_set, + __timeout: *const timespec, + __sigmask: *const __sigset_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn gnu_dev_major(__dev: ::std::os::raw::c_ulonglong) -> ::std::os::raw::c_uint; +} +unsafe extern "C" { + pub fn gnu_dev_minor(__dev: ::std::os::raw::c_ulonglong) -> ::std::os::raw::c_uint; +} +unsafe extern "C" { + pub fn gnu_dev_makedev( + __major: ::std::os::raw::c_uint, + __minor: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_ulonglong; +} +pub type blksize_t = __blksize_t; +pub type blkcnt_t = __blkcnt_t; +pub type fsblkcnt_t = __fsblkcnt_t; +pub type fsfilcnt_t = __fsfilcnt_t; +pub type pthread_t = ::std::os::raw::c_ulong; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_attr_t { + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_internal_list { + pub __prev: *mut __pthread_internal_list, + pub __next: *mut __pthread_internal_list, +} +pub type __pthread_list_t = __pthread_internal_list; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutex_t { + pub __data: pthread_mutex_t___pthread_mutex_s, + pub __size: [::std::os::raw::c_char; 40usize], + pub __align: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_mutex_t___pthread_mutex_s { + pub __lock: ::std::os::raw::c_int, + pub __count: ::std::os::raw::c_uint, + pub __owner: ::std::os::raw::c_int, + pub __nusers: ::std::os::raw::c_uint, + pub __kind: ::std::os::raw::c_int, + pub __spins: ::std::os::raw::c_short, + pub __elision: ::std::os::raw::c_short, + pub __list: __pthread_list_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutexattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_cond_t { + pub __data: pthread_cond_t__bindgen_ty_1, + pub __size: [::std::os::raw::c_char; 48usize], + pub __align: ::std::os::raw::c_longlong, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_cond_t__bindgen_ty_1 { + pub __lock: ::std::os::raw::c_int, + pub __futex: ::std::os::raw::c_uint, + pub __total_seq: ::std::os::raw::c_ulonglong, + pub __wakeup_seq: ::std::os::raw::c_ulonglong, + pub __woken_seq: ::std::os::raw::c_ulonglong, + pub __mutex: *mut ::std::os::raw::c_void, + pub __nwaiters: ::std::os::raw::c_uint, + pub __broadcast_seq: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_condattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, +} +pub type pthread_key_t = ::std::os::raw::c_uint; +pub type pthread_once_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlock_t { + pub __data: pthread_rwlock_t__bindgen_ty_1, + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_rwlock_t__bindgen_ty_1 { + pub __lock: ::std::os::raw::c_int, + pub __nr_readers: ::std::os::raw::c_uint, + pub __readers_wakeup: ::std::os::raw::c_uint, + pub __writer_wakeup: ::std::os::raw::c_uint, + pub __nr_readers_queued: ::std::os::raw::c_uint, + pub __nr_writers_queued: ::std::os::raw::c_uint, + pub __writer: ::std::os::raw::c_int, + pub __shared: ::std::os::raw::c_int, + pub __rwelision: ::std::os::raw::c_schar, + pub __pad1: [::std::os::raw::c_uchar; 7usize], + pub __pad2: ::std::os::raw::c_ulong, + pub __flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlockattr_t { + pub __size: [::std::os::raw::c_char; 8usize], + pub __align: ::std::os::raw::c_long, +} +pub type pthread_spinlock_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrier_t { + pub __size: [::std::os::raw::c_char; 32usize], + pub __align: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrierattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, +} +unsafe extern "C" { + pub fn random() -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn srandom(__seed: ::std::os::raw::c_uint); +} +unsafe extern "C" { + pub fn initstate( + __seed: ::std::os::raw::c_uint, + __statebuf: *mut ::std::os::raw::c_char, + __statelen: usize, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn setstate(__statebuf: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct random_data { + pub fptr: *mut i32, + pub rptr: *mut i32, + pub state: *mut i32, + pub rand_type: ::std::os::raw::c_int, + pub rand_deg: ::std::os::raw::c_int, + pub rand_sep: ::std::os::raw::c_int, + pub end_ptr: *mut i32, +} +unsafe extern "C" { + pub fn random_r(__buf: *mut random_data, __result: *mut i32) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn srandom_r( + __seed: ::std::os::raw::c_uint, + __buf: *mut random_data, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn initstate_r( + __seed: ::std::os::raw::c_uint, + __statebuf: *mut ::std::os::raw::c_char, + __statelen: usize, + __buf: *mut random_data, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn setstate_r( + __statebuf: *mut ::std::os::raw::c_char, + __buf: *mut random_data, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn rand() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn srand(__seed: ::std::os::raw::c_uint); +} +unsafe extern "C" { + pub fn rand_r(__seed: *mut ::std::os::raw::c_uint) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn drand48() -> f64; +} +unsafe extern "C" { + pub fn erand48(__xsubi: *mut ::std::os::raw::c_ushort) -> f64; +} +unsafe extern "C" { + pub fn lrand48() -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn nrand48(__xsubi: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn mrand48() -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn jrand48(__xsubi: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn srand48(__seedval: ::std::os::raw::c_long); +} +unsafe extern "C" { + pub fn seed48(__seed16v: *mut ::std::os::raw::c_ushort) -> *mut ::std::os::raw::c_ushort; +} +unsafe extern "C" { + pub fn lcong48(__param: *mut ::std::os::raw::c_ushort); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct drand48_data { + pub __x: [::std::os::raw::c_ushort; 3usize], + pub __old_x: [::std::os::raw::c_ushort; 3usize], + pub __c: ::std::os::raw::c_ushort, + pub __init: ::std::os::raw::c_ushort, + pub __a: ::std::os::raw::c_ulonglong, +} +unsafe extern "C" { + pub fn drand48_r(__buffer: *mut drand48_data, __result: *mut f64) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn erand48_r( + __xsubi: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + __result: *mut f64, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn lrand48_r( + __buffer: *mut drand48_data, + __result: *mut ::std::os::raw::c_long, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn nrand48_r( + __xsubi: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + __result: *mut ::std::os::raw::c_long, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mrand48_r( + __buffer: *mut drand48_data, + __result: *mut ::std::os::raw::c_long, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn jrand48_r( + __xsubi: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + __result: *mut ::std::os::raw::c_long, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn srand48_r( + __seedval: ::std::os::raw::c_long, + __buffer: *mut drand48_data, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn seed48_r( + __seed16v: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn lcong48_r( + __param: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn malloc(__size: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn calloc( + __nmemb: ::std::os::raw::c_ulong, + __size: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn realloc( + __ptr: *mut ::std::os::raw::c_void, + __size: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn free(__ptr: *mut ::std::os::raw::c_void); +} +unsafe extern "C" { + pub fn cfree(__ptr: *mut ::std::os::raw::c_void); +} +unsafe extern "C" { + pub fn alloca(__size: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn valloc(__size: usize) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn posix_memalign( + __memptr: *mut *mut ::std::os::raw::c_void, + __alignment: usize, + __size: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn aligned_alloc(__alignment: usize, __size: usize) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn abort() -> !; +} +unsafe extern "C" { + pub fn atexit(__func: ::std::option::Option) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn at_quick_exit( + __func: ::std::option::Option, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn on_exit( + __func: ::std::option::Option< + unsafe extern "C" fn( + __status: ::std::os::raw::c_int, + __arg: *mut ::std::os::raw::c_void, + ), + >, + __arg: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn exit(__status: ::std::os::raw::c_int) -> !; +} +unsafe extern "C" { + pub fn quick_exit(__status: ::std::os::raw::c_int) -> !; +} +unsafe extern "C" { + pub fn _Exit(__status: ::std::os::raw::c_int) -> !; +} +unsafe extern "C" { + pub fn getenv(__name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn putenv(__string: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn setenv( + __name: *const ::std::os::raw::c_char, + __value: *const ::std::os::raw::c_char, + __replace: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn unsetenv(__name: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn clearenv() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mktemp(__template: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn mkstemp(__template: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkstemps( + __template: *mut ::std::os::raw::c_char, + __suffixlen: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkdtemp(__template: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn system(__command: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn realpath( + __name: *const ::std::os::raw::c_char, + __resolved: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +pub type __compar_fn_t = ::std::option::Option< + unsafe extern "C" fn( + arg1: *const ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, +>; +unsafe extern "C" { + pub fn bsearch( + __key: *const ::std::os::raw::c_void, + __base: *const ::std::os::raw::c_void, + __nmemb: usize, + __size: usize, + __compar: __compar_fn_t, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn qsort( + __base: *mut ::std::os::raw::c_void, + __nmemb: usize, + __size: usize, + __compar: __compar_fn_t, + ); +} +unsafe extern "C" { + pub fn abs(__x: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn labs(__x: ::std::os::raw::c_long) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn llabs(__x: ::std::os::raw::c_longlong) -> ::std::os::raw::c_longlong; +} +unsafe extern "C" { + pub fn div(__numer: ::std::os::raw::c_int, __denom: ::std::os::raw::c_int) -> div_t; +} +unsafe extern "C" { + pub fn ldiv(__numer: ::std::os::raw::c_long, __denom: ::std::os::raw::c_long) -> ldiv_t; +} +unsafe extern "C" { + pub fn lldiv( + __numer: ::std::os::raw::c_longlong, + __denom: ::std::os::raw::c_longlong, + ) -> lldiv_t; +} +unsafe extern "C" { + pub fn ecvt( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn fcvt( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn gcvt( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn qecvt( + __value: u128, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn qfcvt( + __value: u128, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn qgcvt( + __value: u128, + __ndigit: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn ecvt_r( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fcvt_r( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn qecvt_r( + __value: u128, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn qfcvt_r( + __value: u128, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mblen(__s: *const ::std::os::raw::c_char, __n: usize) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mbtowc( + __pwc: *mut wchar_t, + __s: *const ::std::os::raw::c_char, + __n: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn wctomb(__s: *mut ::std::os::raw::c_char, __wchar: wchar_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mbstowcs(__pwcs: *mut wchar_t, __s: *const ::std::os::raw::c_char, __n: usize) -> usize; +} +unsafe extern "C" { + pub fn wcstombs(__s: *mut ::std::os::raw::c_char, __pwcs: *const wchar_t, __n: usize) -> usize; +} +unsafe extern "C" { + pub fn rpmatch(__response: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn getsubopt( + __optionp: *mut *mut ::std::os::raw::c_char, + __tokens: *const *mut ::std::os::raw::c_char, + __valuep: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn getloadavg(__loadavg: *mut f64, __nelem: ::std::os::raw::c_int) + -> ::std::os::raw::c_int; +} +pub type int_least8_t = ::std::os::raw::c_schar; +pub type int_least16_t = ::std::os::raw::c_short; +pub type int_least32_t = ::std::os::raw::c_int; +pub type int_least64_t = ::std::os::raw::c_long; +pub type uint_least8_t = ::std::os::raw::c_uchar; +pub type uint_least16_t = ::std::os::raw::c_ushort; +pub type uint_least32_t = ::std::os::raw::c_uint; +pub type uint_least64_t = ::std::os::raw::c_ulong; +pub type int_fast8_t = ::std::os::raw::c_schar; +pub type int_fast16_t = ::std::os::raw::c_long; +pub type int_fast32_t = ::std::os::raw::c_long; +pub type int_fast64_t = ::std::os::raw::c_long; +pub type uint_fast8_t = ::std::os::raw::c_uchar; +pub type uint_fast16_t = ::std::os::raw::c_ulong; +pub type uint_fast32_t = ::std::os::raw::c_ulong; +pub type uint_fast64_t = ::std::os::raw::c_ulong; +pub type intmax_t = ::std::os::raw::c_long; +pub type uintmax_t = ::std::os::raw::c_ulong; +unsafe extern "C" { + pub fn lldpctl_get_default_transport() -> *const ::std::os::raw::c_char; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lldpctl_conn_t { + _unused: [u8; 0], +} +pub type lldpctl_send_callback = ::std::option::Option< + unsafe extern "C" fn( + conn: *mut lldpctl_conn_t, + data: *const u8, + length: usize, + user_data: *mut ::std::os::raw::c_void, + ) -> isize, +>; +pub type lldpctl_recv_callback = ::std::option::Option< + unsafe extern "C" fn( + conn: *mut lldpctl_conn_t, + data: *const u8, + length: usize, + user_data: *mut ::std::os::raw::c_void, + ) -> isize, +>; +unsafe extern "C" { + pub fn lldpctl_recv(conn: *mut lldpctl_conn_t, data: *const u8, length: usize) -> isize; +} +unsafe extern "C" { + pub fn lldpctl_send(conn: *mut lldpctl_conn_t) -> isize; +} +unsafe extern "C" { + pub fn lldpctl_process_conn_buffer(conn: *mut lldpctl_conn_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn lldpctl_new( + send: lldpctl_send_callback, + recv: lldpctl_recv_callback, + user_data: *mut ::std::os::raw::c_void, + ) -> *mut lldpctl_conn_t; +} +unsafe extern "C" { + pub fn lldpctl_new_name( + ctlname: *const ::std::os::raw::c_char, + send: lldpctl_send_callback, + recv: lldpctl_recv_callback, + user_data: *mut ::std::os::raw::c_void, + ) -> *mut lldpctl_conn_t; +} +unsafe extern "C" { + pub fn lldpctl_release(conn: *mut lldpctl_conn_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn lldpctl_log_callback( + cb: ::std::option::Option< + unsafe extern "C" fn( + severity: ::std::os::raw::c_int, + msg: *const ::std::os::raw::c_char, + ), + >, + ); +} +unsafe extern "C" { + pub fn lldpctl_log_level(level: ::std::os::raw::c_int); +} +pub const lldpctl_error_t_LLDPCTL_NO_ERROR: lldpctl_error_t = 0; +pub const lldpctl_error_t_LLDPCTL_ERR_WOULDBLOCK: lldpctl_error_t = -501; +pub const lldpctl_error_t_LLDPCTL_ERR_EOF: lldpctl_error_t = -502; +pub const lldpctl_error_t_LLDPCTL_ERR_NOT_EXIST: lldpctl_error_t = -503; +pub const lldpctl_error_t_LLDPCTL_ERR_CANNOT_CONNECT: lldpctl_error_t = -504; +pub const lldpctl_error_t_LLDPCTL_ERR_INCORRECT_ATOM_TYPE: lldpctl_error_t = -505; +pub const lldpctl_error_t_LLDPCTL_ERR_SERIALIZATION: lldpctl_error_t = -506; +pub const lldpctl_error_t_LLDPCTL_ERR_INVALID_STATE: lldpctl_error_t = -507; +pub const lldpctl_error_t_LLDPCTL_ERR_CANNOT_ITERATE: lldpctl_error_t = -508; +pub const lldpctl_error_t_LLDPCTL_ERR_BAD_VALUE: lldpctl_error_t = -509; +pub const lldpctl_error_t_LLDPCTL_ERR_CANNOT_CREATE: lldpctl_error_t = -510; +pub const lldpctl_error_t_LLDPCTL_ERR_FATAL: lldpctl_error_t = -900; +pub const lldpctl_error_t_LLDPCTL_ERR_NOMEM: lldpctl_error_t = -901; +pub const lldpctl_error_t_LLDPCTL_ERR_CALLBACK_FAILURE: lldpctl_error_t = -902; +pub type lldpctl_error_t = ::std::os::raw::c_int; +unsafe extern "C" { + pub fn lldpctl_strerror(error: lldpctl_error_t) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn lldpctl_last_error(conn: *mut lldpctl_conn_t) -> lldpctl_error_t; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lldpctl_atom_t { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _bindgen_ty_1 { + pub value: ::std::os::raw::c_int, + pub string: *mut ::std::os::raw::c_char, +} +pub type lldpctl_map_t = _bindgen_ty_1; +unsafe extern "C" { + pub fn lldpctl_atom_get_connection(atom: *mut lldpctl_atom_t) -> *mut lldpctl_conn_t; +} +unsafe extern "C" { + pub fn lldpctl_atom_inc_ref(atom: *mut lldpctl_atom_t); +} +unsafe extern "C" { + pub fn lldpctl_atom_dec_ref(atom: *mut lldpctl_atom_t); +} +pub const lldpctl_change_t_lldpctl_c_deleted: lldpctl_change_t = 0; +pub const lldpctl_change_t_lldpctl_c_updated: lldpctl_change_t = 1; +pub const lldpctl_change_t_lldpctl_c_added: lldpctl_change_t = 2; +pub type lldpctl_change_t = ::std::os::raw::c_uint; +pub type lldpctl_change_callback = ::std::option::Option< + unsafe extern "C" fn( + conn: *mut lldpctl_conn_t, + type_: lldpctl_change_t, + interface: *mut lldpctl_atom_t, + neighbor: *mut lldpctl_atom_t, + data: *mut ::std::os::raw::c_void, + ), +>; +unsafe extern "C" { + pub fn lldpctl_watch_callback( + conn: *mut lldpctl_conn_t, + cb: lldpctl_change_callback, + data: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn lldpctl_watch(conn: *mut lldpctl_conn_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn lldpctl_get_configuration(conn: *mut lldpctl_conn_t) -> *mut lldpctl_atom_t; +} +unsafe extern "C" { + pub fn lldpctl_get_interfaces(conn: *mut lldpctl_conn_t) -> *mut lldpctl_atom_t; +} +unsafe extern "C" { + pub fn lldpctl_get_local_chassis(conn: *mut lldpctl_conn_t) -> *mut lldpctl_atom_t; +} +unsafe extern "C" { + pub fn lldpctl_get_port(port: *mut lldpctl_atom_t) -> *mut lldpctl_atom_t; +} +pub const lldpctl_key_t_lldpctl_k_config_tx_interval: lldpctl_key_t = 0; +pub const lldpctl_key_t_lldpctl_k_config_receiveonly: lldpctl_key_t = 1; +pub const lldpctl_key_t_lldpctl_k_config_mgmt_pattern: lldpctl_key_t = 2; +pub const lldpctl_key_t_lldpctl_k_config_iface_pattern: lldpctl_key_t = 3; +pub const lldpctl_key_t_lldpctl_k_config_cid_pattern: lldpctl_key_t = 4; +pub const lldpctl_key_t_lldpctl_k_config_description: lldpctl_key_t = 5; +pub const lldpctl_key_t_lldpctl_k_config_platform: lldpctl_key_t = 6; +pub const lldpctl_key_t_lldpctl_k_config_hostname: lldpctl_key_t = 7; +pub const lldpctl_key_t_lldpctl_k_config_advertise_version: lldpctl_key_t = 8; +pub const lldpctl_key_t_lldpctl_k_config_lldpmed_noinventory: lldpctl_key_t = 9; +pub const lldpctl_key_t_lldpctl_k_config_paused: lldpctl_key_t = 10; +pub const lldpctl_key_t_lldpctl_k_config_fast_start_enabled: lldpctl_key_t = 11; +pub const lldpctl_key_t_lldpctl_k_config_fast_start_interval: lldpctl_key_t = 12; +pub const lldpctl_key_t_lldpctl_k_config_ifdescr_update: lldpctl_key_t = 13; +pub const lldpctl_key_t_lldpctl_k_config_iface_promisc: lldpctl_key_t = 14; +pub const lldpctl_key_t_lldpctl_k_config_chassis_cap_advertise: lldpctl_key_t = 15; +pub const lldpctl_key_t_lldpctl_k_config_chassis_mgmt_advertise: lldpctl_key_t = 16; +pub const lldpctl_key_t_lldpctl_k_interface_name: lldpctl_key_t = 1000; +pub const lldpctl_key_t_lldpctl_k_port_name: lldpctl_key_t = 1100; +pub const lldpctl_key_t_lldpctl_k_port_index: lldpctl_key_t = 1101; +pub const lldpctl_key_t_lldpctl_k_port_neighbors: lldpctl_key_t = 1200; +pub const lldpctl_key_t_lldpctl_k_port_protocol: lldpctl_key_t = 1201; +pub const lldpctl_key_t_lldpctl_k_port_age: lldpctl_key_t = 1202; +pub const lldpctl_key_t_lldpctl_k_port_id_subtype: lldpctl_key_t = 1203; +pub const lldpctl_key_t_lldpctl_k_port_id: lldpctl_key_t = 1204; +pub const lldpctl_key_t_lldpctl_k_port_descr: lldpctl_key_t = 1205; +pub const lldpctl_key_t_lldpctl_k_port_hidden: lldpctl_key_t = 1206; +pub const lldpctl_key_t_lldpctl_k_port_chassis: lldpctl_key_t = 1207; +pub const lldpctl_key_t_lldpctl_k_port_dot3_mfs: lldpctl_key_t = 1300; +pub const lldpctl_key_t_lldpctl_k_port_dot3_aggregid: lldpctl_key_t = 1301; +pub const lldpctl_key_t_lldpctl_k_port_dot3_autoneg_support: lldpctl_key_t = 1302; +pub const lldpctl_key_t_lldpctl_k_port_dot3_autoneg_enabled: lldpctl_key_t = 1303; +pub const lldpctl_key_t_lldpctl_k_port_dot3_autoneg_advertised: lldpctl_key_t = 1304; +pub const lldpctl_key_t_lldpctl_k_port_dot3_mautype: lldpctl_key_t = 1305; +pub const lldpctl_key_t_lldpctl_k_port_dot3_power: lldpctl_key_t = 1400; +pub const lldpctl_key_t_lldpctl_k_dot3_power_devicetype: lldpctl_key_t = 1401; +pub const lldpctl_key_t_lldpctl_k_dot3_power_supported: lldpctl_key_t = 1402; +pub const lldpctl_key_t_lldpctl_k_dot3_power_enabled: lldpctl_key_t = 1403; +pub const lldpctl_key_t_lldpctl_k_dot3_power_paircontrol: lldpctl_key_t = 1404; +pub const lldpctl_key_t_lldpctl_k_dot3_power_pairs: lldpctl_key_t = 1405; +pub const lldpctl_key_t_lldpctl_k_dot3_power_class: lldpctl_key_t = 1406; +pub const lldpctl_key_t_lldpctl_k_dot3_power_type: lldpctl_key_t = 1407; +pub const lldpctl_key_t_lldpctl_k_dot3_power_source: lldpctl_key_t = 1408; +pub const lldpctl_key_t_lldpctl_k_dot3_power_priority: lldpctl_key_t = 1409; +pub const lldpctl_key_t_lldpctl_k_dot3_power_allocated: lldpctl_key_t = 1410; +pub const lldpctl_key_t_lldpctl_k_dot3_power_requested: lldpctl_key_t = 1411; +pub const lldpctl_key_t_lldpctl_k_port_vlan_pvid: lldpctl_key_t = 1500; +pub const lldpctl_key_t_lldpctl_k_port_vlans: lldpctl_key_t = 1501; +pub const lldpctl_key_t_lldpctl_k_vlan_id: lldpctl_key_t = 1502; +pub const lldpctl_key_t_lldpctl_k_vlan_name: lldpctl_key_t = 1503; +pub const lldpctl_key_t_lldpctl_k_port_ppvids: lldpctl_key_t = 1600; +pub const lldpctl_key_t_lldpctl_k_ppvid_status: lldpctl_key_t = 1601; +pub const lldpctl_key_t_lldpctl_k_ppvid_id: lldpctl_key_t = 1602; +pub const lldpctl_key_t_lldpctl_k_port_pis: lldpctl_key_t = 1700; +pub const lldpctl_key_t_lldpctl_k_pi_id: lldpctl_key_t = 1701; +pub const lldpctl_key_t_lldpctl_k_chassis_index: lldpctl_key_t = 1800; +pub const lldpctl_key_t_lldpctl_k_chassis_id_subtype: lldpctl_key_t = 1801; +pub const lldpctl_key_t_lldpctl_k_chassis_id: lldpctl_key_t = 1802; +pub const lldpctl_key_t_lldpctl_k_chassis_name: lldpctl_key_t = 1803; +pub const lldpctl_key_t_lldpctl_k_chassis_descr: lldpctl_key_t = 1804; +pub const lldpctl_key_t_lldpctl_k_chassis_cap_available: lldpctl_key_t = 1805; +pub const lldpctl_key_t_lldpctl_k_chassis_cap_enabled: lldpctl_key_t = 1806; +pub const lldpctl_key_t_lldpctl_k_chassis_mgmt: lldpctl_key_t = 1807; +pub const lldpctl_key_t_lldpctl_k_chassis_med_type: lldpctl_key_t = 1900; +pub const lldpctl_key_t_lldpctl_k_chassis_med_cap: lldpctl_key_t = 1901; +pub const lldpctl_key_t_lldpctl_k_chassis_med_inventory_hw: lldpctl_key_t = 1902; +pub const lldpctl_key_t_lldpctl_k_chassis_med_inventory_sw: lldpctl_key_t = 1903; +pub const lldpctl_key_t_lldpctl_k_chassis_med_inventory_fw: lldpctl_key_t = 1904; +pub const lldpctl_key_t_lldpctl_k_chassis_med_inventory_sn: lldpctl_key_t = 1905; +pub const lldpctl_key_t_lldpctl_k_chassis_med_inventory_manuf: lldpctl_key_t = 1906; +pub const lldpctl_key_t_lldpctl_k_chassis_med_inventory_model: lldpctl_key_t = 1907; +pub const lldpctl_key_t_lldpctl_k_chassis_med_inventory_asset: lldpctl_key_t = 1908; +pub const lldpctl_key_t_lldpctl_k_port_med_policies: lldpctl_key_t = 2000; +pub const lldpctl_key_t_lldpctl_k_med_policy_type: lldpctl_key_t = 2001; +pub const lldpctl_key_t_lldpctl_k_med_policy_unknown: lldpctl_key_t = 2002; +pub const lldpctl_key_t_lldpctl_k_med_policy_tagged: lldpctl_key_t = 2003; +pub const lldpctl_key_t_lldpctl_k_med_policy_vid: lldpctl_key_t = 2004; +pub const lldpctl_key_t_lldpctl_k_med_policy_priority: lldpctl_key_t = 2005; +pub const lldpctl_key_t_lldpctl_k_med_policy_dscp: lldpctl_key_t = 2006; +pub const lldpctl_key_t_lldpctl_k_port_med_locations: lldpctl_key_t = 2100; +pub const lldpctl_key_t_lldpctl_k_med_location_format: lldpctl_key_t = 2101; +pub const lldpctl_key_t_lldpctl_k_med_location_geoid: lldpctl_key_t = 2102; +pub const lldpctl_key_t_lldpctl_k_med_location_latitude: lldpctl_key_t = 2103; +pub const lldpctl_key_t_lldpctl_k_med_location_longitude: lldpctl_key_t = 2104; +pub const lldpctl_key_t_lldpctl_k_med_location_altitude: lldpctl_key_t = 2105; +pub const lldpctl_key_t_lldpctl_k_med_location_altitude_unit: lldpctl_key_t = 2106; +pub const lldpctl_key_t_lldpctl_k_med_location_country: lldpctl_key_t = 2200; +pub const lldpctl_key_t_lldpctl_k_med_location_elin: lldpctl_key_t = 2201; +pub const lldpctl_key_t_lldpctl_k_med_location_ca_elements: lldpctl_key_t = 2300; +pub const lldpctl_key_t_lldpctl_k_med_civicaddress_type: lldpctl_key_t = 2301; +pub const lldpctl_key_t_lldpctl_k_med_civicaddress_value: lldpctl_key_t = 2302; +pub const lldpctl_key_t_lldpctl_k_port_med_power: lldpctl_key_t = 2400; +pub const lldpctl_key_t_lldpctl_k_med_power_type: lldpctl_key_t = 2401; +pub const lldpctl_key_t_lldpctl_k_med_power_source: lldpctl_key_t = 2402; +pub const lldpctl_key_t_lldpctl_k_med_power_priority: lldpctl_key_t = 2403; +pub const lldpctl_key_t_lldpctl_k_med_power_val: lldpctl_key_t = 2404; +pub const lldpctl_key_t_lldpctl_k_mgmt_ip: lldpctl_key_t = 3000; +pub const lldpctl_key_t_lldpctl_k_tx_cnt: lldpctl_key_t = 4000; +pub const lldpctl_key_t_lldpctl_k_rx_cnt: lldpctl_key_t = 4001; +pub const lldpctl_key_t_lldpctl_k_rx_discarded_cnt: lldpctl_key_t = 4002; +pub const lldpctl_key_t_lldpctl_k_rx_unrecognized_cnt: lldpctl_key_t = 4003; +pub const lldpctl_key_t_lldpctl_k_ageout_cnt: lldpctl_key_t = 4004; +pub const lldpctl_key_t_lldpctl_k_insert_cnt: lldpctl_key_t = 4005; +pub const lldpctl_key_t_lldpctl_k_delete_cnt: lldpctl_key_t = 4006; +pub const lldpctl_key_t_lldpctl_k_config_tx_hold: lldpctl_key_t = 4007; +pub const lldpctl_key_t_lldpctl_k_config_bond_slave_src_mac_type: lldpctl_key_t = 4008; +pub const lldpctl_key_t_lldpctl_k_config_lldp_portid_type: lldpctl_key_t = 4009; +pub const lldpctl_key_t_lldpctl_k_custom_tlvs: lldpctl_key_t = 5000; +pub const lldpctl_key_t_lldpctl_k_custom_tlvs_clear: lldpctl_key_t = 5001; +pub const lldpctl_key_t_lldpctl_k_custom_tlv: lldpctl_key_t = 5002; +pub const lldpctl_key_t_lldpctl_k_custom_tlv_oui: lldpctl_key_t = 5003; +pub const lldpctl_key_t_lldpctl_k_custom_tlv_oui_subtype: lldpctl_key_t = 5004; +pub const lldpctl_key_t_lldpctl_k_custom_tlv_oui_info_string: lldpctl_key_t = 5005; +pub type lldpctl_key_t = ::std::os::raw::c_uint; +unsafe extern "C" { + pub fn lldpctl_key_get_map(key: lldpctl_key_t) -> *const _bindgen_ty_1; +} +unsafe extern "C" { + pub fn lldpctl_atom_get(atom: *mut lldpctl_atom_t, key: lldpctl_key_t) -> *mut lldpctl_atom_t; +} +unsafe extern "C" { + pub fn lldpctl_atom_set( + atom: *mut lldpctl_atom_t, + key: lldpctl_key_t, + value: *mut lldpctl_atom_t, + ) -> *mut lldpctl_atom_t; +} +unsafe extern "C" { + pub fn lldpctl_atom_get_str( + atom: *mut lldpctl_atom_t, + key: lldpctl_key_t, + ) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn lldpctl_atom_set_str( + atom: *mut lldpctl_atom_t, + key: lldpctl_key_t, + value: *const ::std::os::raw::c_char, + ) -> *mut lldpctl_atom_t; +} +unsafe extern "C" { + pub fn lldpctl_atom_get_buffer( + atom: *mut lldpctl_atom_t, + key: lldpctl_key_t, + length: *mut usize, + ) -> *const u8; +} +unsafe extern "C" { + pub fn lldpctl_atom_set_buffer( + atom: *mut lldpctl_atom_t, + key: lldpctl_key_t, + value: *const u8, + length: usize, + ) -> *mut lldpctl_atom_t; +} +unsafe extern "C" { + pub fn lldpctl_atom_get_int( + atom: *mut lldpctl_atom_t, + key: lldpctl_key_t, + ) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn lldpctl_atom_set_int( + atom: *mut lldpctl_atom_t, + key: lldpctl_key_t, + value: ::std::os::raw::c_long, + ) -> *mut lldpctl_atom_t; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lldpctl_atom_iter_t { + _unused: [u8; 0], +} +unsafe extern "C" { + pub fn lldpctl_atom_iter(atom: *mut lldpctl_atom_t) -> *mut lldpctl_atom_iter_t; +} +unsafe extern "C" { + pub fn lldpctl_atom_iter_next( + atom: *mut lldpctl_atom_t, + iter: *mut lldpctl_atom_iter_t, + ) -> *mut lldpctl_atom_iter_t; +} +unsafe extern "C" { + pub fn lldpctl_atom_iter_value( + atom: *mut lldpctl_atom_t, + iter: *mut lldpctl_atom_iter_t, + ) -> *mut lldpctl_atom_t; +} +unsafe extern "C" { + pub fn lldpctl_atom_create(atom: *mut lldpctl_atom_t) -> *mut lldpctl_atom_t; +} diff --git a/src/sources/lldp/ffi.rs b/src/sources/lldp/ffi.rs new file mode 100644 index 0000000000000..1970ec08f6053 --- /dev/null +++ b/src/sources/lldp/ffi.rs @@ -0,0 +1,247 @@ +use std::error::Error as StdError; +use std::ffi::CStr; +use std::fmt; +use std::ptr; +use crate::sources::lldp::bindings::*; + +/// LLDP consts +pub const LLDPCTL_K_PORT_CHASSIS: lldpctl_key_t = 1208; + +/// LLDP error +#[derive(Debug)] +pub enum LldpError { + ConnectionFailed, + InterfaceFetchFailed, + NullPointer(&'static str), + ThreadJoinFailed, +} + +impl fmt::Display for LldpError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + LldpError::ConnectionFailed => { + write!(f, "LLDP connection failed") + } + LldpError::InterfaceFetchFailed => write!(f, "Failed to fetch network interfaces"), + LldpError::NullPointer(ctx) => write!(f, "Null pointer encountered in: {}", ctx), + LldpError::ThreadJoinFailed => write!(f, "Blocking thread error"), + } + } +} + +impl StdError for LldpError {} + +/// LLDP data +#[derive(Debug, Clone)] +pub struct LldpInterface { + pub name: String, + pub device_name: String, +} + +#[derive(Debug, Clone)] +pub struct LldpNeighbor { + pub local_interface: String, + pub local_device: String, + pub remote_device: String, + pub remote_port: String, +} + +/// RAII +struct AtomGuard { + ptr: *mut lldpctl_atom_t, +} + +impl AtomGuard { + fn new(ptr: *mut lldpctl_atom_t) -> Self { + Self { ptr } + } + + fn ptr(&self) -> *mut lldpctl_atom_t { + self.ptr + } +} + +impl Drop for AtomGuard { + fn drop(&mut self) { + unsafe { + lldpctl_atom_dec_ref(self.ptr); + } + } +} + +pub struct LldpHandle { + conn: *mut lldpctl_conn_t, +} + +impl LldpHandle { + pub fn new() -> Result { + unsafe { + let conn = lldpctl_new(None, None, ptr::null_mut()); + if conn.is_null() { + Err(LldpError::ConnectionFailed) + } else { + Ok(Self { conn }) + } + } + } + + pub fn get_interfaces(&self) -> Result, LldpError> { + unsafe { + let interfaces = lldpctl_get_interfaces(self.conn); + if interfaces.is_null() { + return Err(LldpError::InterfaceFetchFailed); + } + + let interfaces = AtomGuard::new(interfaces); + let mut result = Vec::new(); + + let mut iter = lldpctl_atom_iter(interfaces.ptr()); + while !iter.is_null() { + let interface_atom = lldpctl_atom_iter_value(interfaces.ptr(), iter); + iter = lldpctl_atom_iter_next(interfaces.ptr(), iter); + if interface_atom.is_null() { + continue; + } + + let interface = AtomGuard::new(interface_atom); + + let name = get_string_property(interface.ptr(), lldpctl_key_t_lldpctl_k_interface_name) + .unwrap_or_default(); + + let port_ptr = lldpctl_get_port(interface.ptr()); + if port_ptr.is_null() { + continue; + } + let port = AtomGuard::new(port_ptr); + + let chassis_ptr = lldpctl_atom_get(port.ptr(), LLDPCTL_K_PORT_CHASSIS); + if chassis_ptr.is_null() { + continue; + } + + let chassis = AtomGuard::new(chassis_ptr); + let device_name = + get_string_property(chassis.ptr(), lldpctl_key_t_lldpctl_k_chassis_name).unwrap_or_default(); + + result.push(LldpInterface { + name, + device_name, + }); + } + + Ok(result) + } + } + + pub fn get_neighbors(&self) -> Result, LldpError> { + unsafe { + let interface_list = lldpctl_get_interfaces(self.conn); + if interface_list.is_null() { + return Err(LldpError::InterfaceFetchFailed); + } + let interface_list = AtomGuard::new(interface_list); + let mut result = Vec::new(); + + let mut iter = lldpctl_atom_iter(interface_list.ptr()); + while !iter.is_null() { + let interface_ptr = lldpctl_atom_iter_value(interface_list.ptr(), iter); + iter = lldpctl_atom_iter_next(interface_list.ptr(), iter); + + if interface_ptr.is_null() { + continue; + } + let interface = AtomGuard::new(interface_ptr); + + let interface_name = get_string_property(interface.ptr(), lldpctl_key_t_lldpctl_k_interface_name) + .unwrap_or_default(); + + let port_ptr = lldpctl_get_port(interface.ptr()); + if port_ptr.is_null() { + continue; + } + let port = AtomGuard::new(port_ptr); + + let chassis_ptr = lldpctl_atom_get(port.ptr(), LLDPCTL_K_PORT_CHASSIS); + if chassis_ptr.is_null() { + continue; + } + + let chassis = AtomGuard::new(chassis_ptr); + let local_chassis_name = + get_string_property(chassis.ptr(), lldpctl_key_t_lldpctl_k_chassis_name).unwrap_or_default(); + + // 获取 neighbor 列表 + let neighbors_ptr = lldpctl_atom_get(port.ptr(), lldpctl_key_t_lldpctl_k_port_neighbors as lldpctl_key_t); + if neighbors_ptr.is_null() { + continue; + } + let neighbors = AtomGuard::new(neighbors_ptr); + + // 遍历每个 neighbor + let mut n_iter = lldpctl_atom_iter(neighbors.ptr()); + while !n_iter.is_null() { + let neighbor_ptr = lldpctl_atom_iter_value(neighbors.ptr(), n_iter); + n_iter = lldpctl_atom_iter_next(neighbors.ptr(), n_iter); + + if neighbor_ptr.is_null() { + continue; + } + + let neighbor = AtomGuard::new(neighbor_ptr); + + let remote_device = get_string_property(neighbor.ptr(), lldpctl_key_t_lldpctl_k_chassis_name) + .unwrap_or_default(); + let remote_port = + get_string_property(neighbor.ptr(), lldpctl_key_t_lldpctl_k_port_id).unwrap_or_default(); + + result.push(LldpNeighbor { + local_interface: interface_name.clone(), + local_device: local_chassis_name.clone(), + remote_device, + remote_port, + }); + } + } + + Ok(result) + } + } +} + +impl Drop for LldpHandle { + fn drop(&mut self) { + unsafe { + lldpctl_release(self.conn); + } + } +} + +fn get_string_property(atom: *mut lldpctl_atom_t, key: lldpctl_key_t) -> Result { + unsafe { + let cstr = lldpctl_atom_get_str(atom, key); + + if cstr.is_null() { + Err(LldpError::NullPointer("get_string_property")) + } else { + let value = CStr::from_ptr(cstr).to_string_lossy().into_owned(); + Ok(value) + } + } +} +pub async fn get_lldp_interfaces_async() -> Result, LldpError> { + tokio::task::spawn_blocking(|| { + let handle = LldpHandle::new()?; + handle.get_interfaces() + }) + .await + .map_err(|_| LldpError::ThreadJoinFailed)? +} + +pub async fn get_lldp_neighbors_async() -> Result, LldpError> { + tokio::task::spawn_blocking(|| { + let handle = LldpHandle::new()?; + handle.get_neighbors() + }) + .await + .map_err(|_| LldpError::ThreadJoinFailed)? +} diff --git a/src/sources/lldp/mod.rs b/src/sources/lldp/mod.rs new file mode 100644 index 0000000000000..f0fd8ac2f2f88 --- /dev/null +++ b/src/sources/lldp/mod.rs @@ -0,0 +1,202 @@ +use chrono::Utc; +use std::time::Duration; + +use crate::sources::lldp::ffi::{LldpInterface, LldpNeighbor}; +use crate::{ + config::{SourceConfig, SourceContext, SourceOutput}, + event::metric::{Metric, MetricKind, MetricTags, MetricValue}, +}; +use vector_lib::configurable::configurable_component; + +mod ffi; +#[allow(improper_ctypes, unused_imports, non_camel_case_types, non_snake_case, non_upper_case_globals, dead_code)] +mod bindings; + +/// Configuration for the `lldp` source. +#[configurable_component(source("lldp", "Collect lldp data."))] +#[derive(Clone, Debug, Default)] +#[serde(deny_unknown_fields)] +pub struct LldpMetricsConfig { + /// interface data of lldp. + #[serde(default = "default_interface_scrape_interval")] + pub interface_scrape_secs: u64, + + /// link data of lldp. + #[serde(default = "default_link_scrape_interval")] + pub link_scrape_secs: u64, +} + +fn default_interface_scrape_interval() -> u64 { + 30 +} + +fn default_link_scrape_interval() -> u64 { + 60 +} +#[derive(Clone)] +pub struct Config { + pub node_name: String, + pub cluster: String, +} + +impl_generate_config_from_default!(LldpMetricsConfig); + +#[async_trait::async_trait] +#[typetag::serde(name = "lldp")] +impl SourceConfig for LldpMetricsConfig { + async fn build(&self, cx: SourceContext) -> crate::Result { + let interface_scrape_secs = self.interface_scrape_secs; + let link_scrape_secs = self.link_scrape_secs; + let mut interface_out = cx.out.clone(); + let mut link_out = cx.out; + let shutdown = cx.shutdown.clone(); + + Ok(Box::pin(async move { + let config = Config { + node_name: std::env::var("NODE_NAME").unwrap_or_else(|_| "unknown-node".into()), + cluster: std::env::var("CLUSTER_NAME").unwrap_or_else(|_| "unknown-cluster".into()), + }; + + let mut interface_interval = + tokio::time::interval(Duration::from_secs(interface_scrape_secs)); + let mut link_interval = tokio::time::interval(Duration::from_secs(link_scrape_secs)); + + loop { + tokio::select! { + _ = interface_interval.tick() => { + match ffi::get_lldp_interfaces_async().await { + Ok(interfaces) => { + let interfaces_metrics = map_interfaces_to_metrics(interfaces, &config); + if let Err(_) = interface_out.send_batch(interfaces_metrics).await { + return Err(()); + } + } + Err(e) => warn!("LLDP interface error: {}", e), + } + } + + _ = link_interval.tick() => { + match ffi::get_lldp_neighbors_async().await { + Ok(neighbors) => { + let (interfaces, links) = map_neighbors_to_interface_and_link(neighbors, &config); + if let Err(_) = link_out.send_batch(interfaces).await { + return Err(()); + } + if let Err(_) = link_out.send_batch(links).await { + return Err(()); + } + } + Err(e) => warn!("LLDP link error: {}", e), + } + } + + _ = shutdown.clone() => { + info!("Shutting down LLDP source"); + break; + } + } + } + + Ok(()) + })) + } + fn outputs(&self, _: vector_lib::config::LogNamespace) -> Vec { + vec![SourceOutput::new_metrics()] + } + + fn can_acknowledge(&self) -> bool { + false + } +} + +pub fn map_interfaces_to_metrics(interfaces: Vec, config: &Config) -> Vec { + let now = Utc::now(); + let mut metrics = Vec::new(); + + for interface in interfaces { + let mut tags = MetricTags::default(); + tags.insert("name".to_string(), interface.name.clone()); + tags.insert("device".to_string(), interface.device_name.clone()); + tags.insert("node_name".to_string(), config.node_name.clone()); + tags.insert("type".to_string(), "0".to_string()); + tags.insert("cluster".to_string(), config.cluster.clone()); + + metrics.push( + Metric::new( + "lldp_interface", + MetricKind::Absolute, + MetricValue::Gauge { value: 1.0 }, + ) + .with_timestamp(Some(now)) + .with_tags(Some(tags)), + ); + } + + metrics +} + +pub fn map_neighbors_to_interface_and_link( + neighbors: Vec, + config: &Config, +) -> (Vec, Vec) { + let mut interface_metrics = Vec::new(); + let mut link_metrics = Vec::new(); + + for neighbor in neighbors { + let remote_type = if neighbor.remote_device.to_lowercase().contains("leaf") { + 1 + } else if neighbor.remote_device.to_lowercase().contains("spine") { + 2 + } else { + 3 + }; + + let now = Utc::now(); + + // switch interface + let mut switch_tags = MetricTags::default(); + switch_tags.insert("name".to_string(), neighbor.remote_port.clone()); + switch_tags.insert("device".to_string(), neighbor.remote_device.clone()); + switch_tags.insert("node_name".to_string(), config.node_name.to_string()); + switch_tags.insert("type".to_string(), remote_type.to_string()); + switch_tags.insert("cluster".to_string(), config.cluster.clone()); + + interface_metrics.push( + Metric::new( + "lldp_interface", + MetricKind::Absolute, + MetricValue::Gauge { value: 1.0 }, + ) + .with_timestamp(Some(now)) + .with_tags(Some(switch_tags)), + ); + + let level = match remote_type { + 1 => 0, + 2 => 1, + _ => 0, + }; + + // link + let mut link_tags = MetricTags::default(); + link_tags.insert("from_name".to_string(), neighbor.local_interface.clone()); + link_tags.insert("from_device".to_string(), neighbor.local_device.clone()); + link_tags.insert("from_node".to_string(), config.node_name.clone()); + link_tags.insert("to_name".to_string(), neighbor.remote_port.clone()); + link_tags.insert("to_device".to_string(), neighbor.remote_device.to_string()); + link_tags.insert("cluster".to_string(), config.cluster.clone()); + link_tags.insert("level".to_string(), level.to_string()); + + link_metrics.push( + Metric::new( + "lldp_link", + MetricKind::Absolute, + MetricValue::Gauge { value: 1.0 }, + ) + .with_timestamp(Some(now)) + .with_tags(Some(link_tags)), + ); + } + + (interface_metrics, link_metrics) +} diff --git a/src/sources/lldp/wrapper.h b/src/sources/lldp/wrapper.h new file mode 100644 index 0000000000000..e15c805b8a58f --- /dev/null +++ b/src/sources/lldp/wrapper.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/src/sources/mod.rs b/src/sources/mod.rs index 8a86d9d6343d0..b2b5f8c5c9c74 100644 --- a/src/sources/mod.rs +++ b/src/sources/mod.rs @@ -88,6 +88,8 @@ pub mod statsd; pub mod syslog; #[cfg(feature = "sources-vector")] pub mod vector; +#[cfg(feature = "sources-lldp")] +pub mod lldp; pub mod util;