diff options
author | Michael Biebl <biebl@debian.org> | 2018-01-28 22:49:17 +0100 |
---|---|---|
committer | Michael Biebl <biebl@debian.org> | 2018-01-28 22:49:17 +0100 |
commit | 1d42b86df9052528a8f56b2f52d8bc2faf87b2da (patch) | |
tree | 0d80f37a1ad6f02067261ee3e7ee62e1869fcd56 | |
parent | 52ad194e0b816b8273dd8d0fea3e6d467f6ca34e (diff) | |
download | systemd-1d42b86df9052528a8f56b2f52d8bc2faf87b2da.tar.gz |
New upstream version 237
605 files changed, 31264 insertions, 16045 deletions
@@ -142,3 +142,10 @@ Lukáš Říha <cedel@centrum.cz> Alan Robertson <aroberts@zen.iomart.com> <alanjrobertson@gmail.com> Martin Steuer <martinsteuer@gmx.de> Matthias-Christian Ott <ott@mirix.org> <ott@users.noreply.github.com> +Larry Bernstone <lbernstone@gmail.com> +Michał Szczepański <skrzatu@hotmail.com> <skrzatu@gmail.com> +Tomasz Bachorski <tomasz.bachorski@x7f.io> <34866781+nulsoh@users.noreply.github.com> +Zachary Winnerman <33329648+winnerman-pythian@users.noreply.github.com> +Vladislav Vishnyakov <split7fire@yandex.ru> +Robert Kolchmeyer <rkolchmeyer@google.com> <rkolchmeyer@users.noreply.github.com> +George Gaydarov <git@gg7.io> <gg7@users.noreply.github.com> diff --git a/.mkosi/mkosi.arch b/.mkosi/mkosi.arch index a823a95e70..d7f6bc866a 100644 --- a/.mkosi/mkosi.arch +++ b/.mkosi/mkosi.arch @@ -50,7 +50,7 @@ BuildPackages= kmod libcap libgcrypt - libidn + libidn2 libmicrohttpd libseccomp libtool @@ -66,7 +66,6 @@ BuildPackages= python-lxml qrencode xz -# TODO use libidn2 once it's available in official repositories Packages= - libidn + libidn2 diff --git a/.travis.yml b/.travis.yml index 5d63474c1d..1f09a78fa6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,178 @@ -language: c -compiler: - - gcc -before_install: - - sudo apt-get update -qq - - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libmount-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gperf python2.7-dev -script: ./autogen.sh && ./configure && make V=1 && sudo ./systemd-machine-id-setup && make check && make distcheck -after_failure: cat test-suite.log +sudo: required + +services: + - docker + +jobs: + include: + - stage: build docker image + env: + # The machine id will be passed to Dockerfile for later checks + - MACHINE_ID=$(cat /var/lib/dbus/machine-id) + before_script: &update + # Ensure the latest version of docker is installed + - sudo apt-get update + - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce + - docker --version + - env > .env + script: + # Copy content of CI_DIR into WORKDIR + - find $CI_DIR -maxdepth 1 -type f -exec cp -t . {} + + - echo "ENV GIT_SHA ${TRAVIS_COMMIT}" >> Dockerfile + - echo "ENV MACHINE_ID ${MACHINE_ID}" >> Dockerfile + - echo "$(git log -1 ${TRAVIS_COMMIT})" >> COMMITINFO + # Build docker container + - $CI_SCRIPT_DIR/build-docker-image.sh + + - docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}" + - docker push ${DOCKER_REPOSITORY} + + - stage: build + language: c + compiler: gcc + env: + # The machine id will be passed to container + - MACHINE_ID=$(cat /var/lib/dbus/machine-id) + before_script: *update + script: + - docker run -dit --name travis_build ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} bash + - docker exec -u 0 -ti travis_build bash -c "echo ${MACHINE_ID} > /etc/machine-id" + - docker exec -ti travis_build meson build + - docker exec -ti travis_build ninja -C build + # Commit it to the new image that will be used for testing + - docker commit -m "systemd build state" -a "${AUTHOR_NAME}" travis_build ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} + - docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}" + - docker push ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} + + - stage: test + language: c + compiler: gcc + before_script: *update + script: + - docker run --privileged --net=host -dit --name travis_test ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} bash + - docker exec -ti travis_test ninja -C build test + - docker commit -m "systemd test state" -a "${AUTHOR_NAME}" travis_test ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} + - docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}" + - docker push ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} + + - stage: coverity scan + language: c + compiler: gcc + before_script: *update + env: + - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG" + - COVERITY_SCAN_NOTIFICATION_EMAIL="${AUTHOR_EMAIL}" + - COVERITY_SCAN_BRANCH_PATTERN="$TRAVIS_BRANCH" + # Disable CCACHE for cov-build to compilation units correctly + - CCACHE_DISABLE=1 + # Token for systemd/systemd Coverity Scan Analysis + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "UNQLspT89GYWuVKFqW5W5RyqqnYg5RvX20IrNraOddhpdV9nhKBtozrfmhGXDGZwfHGWHt6g7YROlD/NIMvDvThVJIEYvSQiXCoo2zRrwkl2siET5MjPfRG8numiLq0KX47KGmyBJISJZCgDUdNGqqGwgf7AhDN78I3XtgqjFT1z0mGl8n0wiFpKPi7i3nECvF4Mk7xCCHqwByaq0z5G9NkVlOvP1EyCxwv3B6I5Umfch7ibp7iH44YnVXILK+yEry5dMuctYwYkDouR80ChEPQQ5fhhpO4++HJmFuSpfMTeCHpucAd2xwSUijejYeN/GNQ177GxSSk/8hRBGcuSK8T/WJ+KiuJPhZObV8mw+a6+qdQssWY4F9jya5ZKbZ/yTbxjtQ0m4AgtL28P9bEze8pLh16zFMX+hIEuoFSNmJqmtNttfbD5TKyYVZml59s9wvhlvMnlNpRSQva88OAOjXtiA41g+XtTxxpfW9mgd7HYhzSBs1efNiK7PfkANgve7KIYMAmCAqasgb1IIAyX7stOlJH06QOFXNH55PmJLkkKyL3SMQzgryMDWegU+XbS8t43r0x14WLuE7sc9JtnOr/G8hthFaMRp8xLy9aCBwyEIkEsyWa50VMoZDa3Spdb4r1CKBwcGdCbyE4rCehwEIznbfrsSovhwiUds7bbhBU=" + script: + # Copy content of CI_DIR into WORKDIR + - find $CI_DIR -maxdepth 1 -type f -exec cp -t . {} + + # Build container for current user + - $CI_SCRIPT_DIR/build-docker-image.sh + + # For kernel version 4.8+ + - sudo sysctl vsyscall=emulate || true + # Prepare environment for Coverity tool + - | + PLATFORM=`uname` + export TOOL_BASE="/tmp/coverity-scan-analysis" + export SCAN_URL="https://scan.coverity.com" + export UPLOAD_URL="https://scan.coverity.com/builds" + export TOOL_ARCHIVE="/tmp/cov-analysis-${PLATFORM}.tgz" + + # Get Coverity tool + - $CI_TOOL_DIR/get-coverity.sh + - TOOL_DIR="$(find $TOOL_BASE -type d -name 'cov-analysis*')" + + # Export env variables for Coverity scan + - env | grep -E "TRAVIS|COV|TOOL|URL" > .cov-env + - | + docker run -dit --env-file .cov-env \ + -v ${TOOL_BASE}:${TOOL_BASE}:ro \ + --name travis_coverity_scan ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} bash + # Make sure Coverity script is executable + - docker cp scripts/coverity.sh travis_coverity_scan:/usr/local/bin + # Preconfigure with meson to prevent Coverity from capturing meson metadata + # Set compiler flag to prevent emit failure + - docker exec -it travis_coverity_scan sh -c "CFLAGS='-D_Float128=long\ double' meson cov-build -Dman=false" + # Run Coverity Analysis + - docker exec -it travis_coverity_scan coverity.sh build + - docker exec -it travis_coverity_scan coverity.sh upload + + - stage: clean docker + language: python + # python: + # - "3.6" Probably broken ATM + env: + - SIZE_LIMIT="3000" # Limit in MBs + - TAG_LIMIT="3" # Number of tags to be kept at the time + before-script: + - sudo apt-get -y install python3 + script: + # Get docker-remote tool and setup venv + - sudo $CI_TOOL_DIR/get-docker-remote.sh + # Activate virtual environment to be able to use docker-remote safely + - source venv/bin/activate + # Check the size and tag limit of the repo + - REPO_SIZE=$(docker-remote repository --size $DOCKER_REPOSITORY) + - TAG_COUNT=$(docker-remote tags --count $DOCKER_REPOSITORY) + - 'echo -e "\033[33;1mCurrent repository size: $REPO_SIZE in $TAG_COUNT tags \033[0m"' + - | + if [[ ${REPO_SIZE%.*} -gt $SIZE_LIMIT ]] || [[ $TAG_COUNT -gt $TAG_LIMIT ]] + then + docker-remote --login $DOCKER_USERNAME:$DOCKER_PASSWORD \ + tags --assumeyes --pop-back --keep $TAG_LIMIT $DOCKER_REPOSITORY + fi + + + +# Specify the order of stages and conditions +stages: + # Helper stage to determine whether coverity stage should be allowed + - name: initialization + + - name: build docker image + if: type != cron + - name: build + if: type != cron + - name: test + if: type != cron + + # These stages run separately, the resulting container will not be pushed to Docker Hub + # This stage will only run on special conditions + - name: coverity scan + if: type = cron + + # Check for repository size and clean Docker repo if necessary + - name: clean Docker + if: type = cron + +env: + global: + # Secure Docker Hub credentials + - secure: "TY61ufmEJyxCer8vuAlQ3mYwGRynFZXPCFTxKgIzobAHHyE1Zwx0bZDDwDd88Gdgz7EGnOJtMABfa0axfPOK9il5u7lYmmZ8Usa0HAvKavkpSRnw2b16zz88N98x3DyaIquvg2J8iQpHHoM32+BGiAS7P8BiYTO6r+E0CMPYC0Ylh7eHVSBGfWbR9m+yCo/mDIEAWyop6Jv4rTMN4qP9U7e6Kou7m/AJeiCWMaR7rlanpLFNQi3+qF/Mt5dbE7LVLNSOkmpg/FPw34g4RC5mfLAh+c8YBadqo6kFA6qV1b931or0aZUYVtobI6UwC9U1GGqzfCTjXuVMNgPBBQ6n3JMt91mFFkP0lXdGMxpBNbwFL/btBrt2a359L/wNtqv6PuSJwJ3oTe/FP++X6xjbM7LcAHZMWZiK+0BFefNOUcRzBpaEJ2nGNzcLKHn4Bl0pl4LwZ0uVocN8RBwHnDX+hyUwwQPoQTLJQB9tpwDweIzftt9KmrIHmL9v7KZXR4s/8CKpNfVQ/XSysdtsK+7EKK5AsnbMNrZLjpH7D0Lo/Xp92/eJ2UGyqI7awJbJGPV2FNwyGcojDEXIBUsVssUjb5+B4LpHP1x4UQe/m9SuPJdtRB0R7PKe/tyPD3GTyfVO9K7imQATDdnMY32nkWXmXej8YWo76yA732rTZRZtFAc=" + - secure: "NAEzWn5Ru6IqDA1RSyTVhpIp2iQluumg0EOI111EN7qWWGUDNgAZi+QgvRI+OBNyuMpBpN/GX1Ys4YxUDos1F/fhm2vytoB4A/LG463FQsSVP3wnyMFJTSOI8H0jgK41xj79qiww7edbfq93MZ/XS95Ws4tUTi/0etUGvAgIHGgofFCPPdMNkOvSHLgzSnYfydzLuD9FVpCgvpbJnQ+47XHyN+sKoA+OlZ+EfIOVZt+Mk/dqYrsM7MRKEfplk1MvUiJpHvrw+xWTslCIiO03V6ws091fBMgedIFRpsySrsd1KwH8JIeOK6KFn5W7Q53auzZkKYk7ymknlJt4WVBy7Qg33njMQ53t3qMQYTRUIV4dcR60cdII7tatzgpKBcycxHQMAshOYPT6pYhSsO6JEKgiO+ZhOxvqWGwtEeH9Zq7P4ft8Q7GJhRkdi0X0WY7/6RjwinO/1LLj1LODim3mDFfAK7xS7e+nQW/JEOdWohT2+qm97j9IOZeQtPtdqZP9F8HJXgw6WjiGJIXMF3Ov9GkQh4uJyMYJ6hN7T3iRoenV86Dzgg6u5Ku131Ziwvlm+n94qlXF8Jl47wCcAS7VmyYxMft1gH+Zs+4Wq7KO0vysmnEk6rCqb87ZQSDOdTzBfK9HTyyAqmBCgS4Dp5x7/xOBMVXfq/SOb9c3Sh/JItA=" + - DOCKER_REPOSITORY=$DOCKER_USERNAME/systemd + + - ADMIN_EMAIL=macermak@redhat.com + + - AUTHOR_NAME="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aN\")" + - AUTHOR_EMAIL="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aE\")" + + - CI_DIR="$TRAVIS_BUILD_DIR/travis-ci" + - CI_TOOL_DIR="$CI_DIR/tools" + - CI_SCRIPT_DIR="$CI_DIR/scripts" + notifications: + email: + recipients: + - ${ADMIN_EMAIL} + - ${AUTHOR_EMAIL} irc: channels: - "irc.freenode.org#systemd" diff --git a/CODING_STYLE b/CODING_STYLE index 4119cfec23..ae818126cb 100644 --- a/CODING_STYLE +++ b/CODING_STYLE @@ -1,9 +1,11 @@ - 8ch indent, no tabs, except for files in man/ which are 2ch indent, and still no tabs -- We prefer /* comments */ over // comments, please. This is not C++, after - all. (Yes we know that C99 supports both kinds of comments, but still, - please!) +- We prefer /* comments */ over // comments in code you commit, please. This + way // comments are left for developers to use for local, temporary + commenting of code for debug purposes (i.e. uncommittable stuff), making such + comments easily discernable from explanatory, documenting code comments + (i.e. committable stuff). - Don't break code lines too eagerly. We do *not* force line breaks at 80ch, all of today's screens should be much larger than that. But diff --git a/ENVIRONMENT.md b/ENVIRONMENT.md index 4ae561a892..581bf3c238 100644 --- a/ENVIRONMENT.md +++ b/ENVIRONMENT.md @@ -13,10 +13,21 @@ documented in the proper man pages. All tools: +* `$SYSTEMD_OFFLINE=[0|1]` — if set to `1`, then `systemctl` will + refrain from talking to PID 1; this has the same effect as the historical + detection of `chroot()`. Setting this variable to `0` instead has a similar + effect as `SYSTEMD_IGNORE_CHROOT=1`; i.e. tools will try to + communicate with PID 1 even if a `chroot()` environment is detected. + You almost certainly want to set this to `1` if you maintain a package build system + or similar and are trying to use a modern container system and not plain + `chroot()`. + * `$SYSTEMD_IGNORE_CHROOT=1` — if set, don't check whether being invoked in a - chroot() environment. This is particularly relevant for systemctl, as it will - not alter its behaviour for chroot() environments if set. (Normally it - refrains from talking to PID 1 in such a case.) + `chroot()` environment. This is particularly relevant for systemctl, as it + will not alter its behaviour for `chroot()` environments if set. Normally it + refrains from talking to PID 1 in such a case; turning most operations such + as `start` into no-ops. If that's what's explicitly desired, you might + consider setting `SYSTEMD_OFFLINE=1`. * `$SD_EVENT_PROFILE_DELAYS=1` — if set, the sd-event event loop implementation will print latency information at runtime. @@ -79,3 +79,38 @@ for systemd (this example is for Fedora): And after that, head over to your repo on github and click "Compare & pull request" Happy hacking! + + +FUZZERS + +systemd includes fuzzers in src/fuzz that use libFuzzer and are automatically +run by OSS-Fuzz (https://github.com/google/oss-fuzz) with sanitizers. To add a +fuzz target, create a new src/fuzz/fuzz-foo.c file with a LLVMFuzzerTestOneInput +function and add it to the list in src/fuzz/meson.build. + +Whenever possible, a seed corpus and a dictionary should also be added with new +fuzz targets. The dictionary should be named src/fuzz/fuzz-foo.dict and the seed +corpus should be built and exported as $OUT/fuzz-foo_seed_corpus.zip in +scripts/oss-fuzz.sh. + +The fuzzers can be built locally if you have libFuzzer installed by running +scripts/oss-fuzz.sh. You should also confirm that the fuzzer runs in the +OSS-Fuzz environment by checking out the OSS-Fuzz repo, and then running +commands like this: + + python infra/helper.py build_image systemd + python infra/helper.py build_fuzzers --sanitizer memory systemd ../systemd + python infra/helper.py run_fuzzer systemd fuzz-foo + +If you find a bug that impacts the security of systemd, please follow the +guidance in .github/CONTRIBUTING.md on how to report a security vulnerability. + +For more details on building fuzzers and integrating with OSS-Fuzz, visit: + + https://github.com/google/oss-fuzz/blob/master/docs/new_project_guide.md + + https://llvm.org/docs/LibFuzzer.html + + https://github.com/google/fuzzer-test-suite/blob/master/tutorial/libFuzzerTutorial.md + + https://chromium.googlesource.com/chromium/src/testing/libfuzzer/+/HEAD/efficient_fuzzer.md @@ -1,5 +1,195 @@ systemd System and Service Manager +CHANGES WITH 237: + + * Some keyboards come with a zoom see-saw or rocker which until now got + mapped to the Linux "zoomin/out" keys in hwdb. However, these + keycodes are not recognized by any major desktop. They now produce + Up/Down key events so that they can be used for scrolling. + + * INCOMPATIBILITY: systemd-tmpfiles' "f" lines changed behaviour + slightly: previously, if an argument was specified for lines of this + type (i.e. the right-most column was set) this string was appended to + existing files each time systemd-tmpfiles was run. This behaviour was + different from what the documentation said, and not particularly + useful, as repeated systemd-tmpfiles invocations would not be + idempotent and grow such files without bounds. With this release + behaviour has been altered slightly, to match what the documentation + says: lines of this type only have an effect if the indicated files + don't exist yet, and only then the argument string is written to the + file. + + * FUTURE INCOMPATIBILITY: In systemd v238 we intend to slightly change + systemd-tmpfiles behaviour: previously, read-only files owned by root + were always excluded from the file "aging" algorithm (i.e. the + automatic clean-up of directories like /tmp based on + atime/mtime/ctime). We intend to drop this restriction, and age files + by default even when owned by root and read-only. This behaviour was + inherited from older tools, but there have been requests to remove + it, and it's not obvious why this restriction was made in the first + place. Please speak up now, if you are aware of software that reqires + this behaviour, otherwise we'll remove the restriction in v238. + + * A new environment variable $SYSTEMD_OFFLINE is now understood by + systemctl. It takes a boolean argument. If on, systemctl assumes it + operates on an "offline" OS tree, and will not attempt to talk to the + service manager. Previously, this mode was implicitly enabled if a + chroot() environment was detected, and this new environment variable + now provides explicit control. + + * .path and .socket units may now be created transiently, too. + Previously only service, mount, automount and timer units were + supported as transient units. The systemd-run tool has been updated + to expose this new functionality, you may hence use it now to bind + arbitrary commands to path or socket activation on-the-fly from the + command line. Moreover, almost all properties are now exposed for the + unit types that already supported transient operation. + + * The systemd-mount command gained support for a new --owner= parameter + which takes a user name, which is then resolved and included in uid= + and gid= mount options string of the file system to mount. + + * A new unit condition ConditionControlGroupController= has been added + that checks whether a specific cgroup controller is available. + + * Unit files, udev's .link files, and systemd-networkd's .netdev and + .network files all gained support for a new condition + ConditionKernelVersion= for checking against specific kernel + versions. + + * In systemd-networkd, the [IPVLAN] section in .netdev files gained + support for configuring device flags in the Flags= setting. In the + same files, the [Tunnel] section gained support for configuring + AllowLocalRemote=. The [Route] section in .network files gained + support for configuring InitialCongestionWindow=, + InitialAdvertisedReceiveWindow= and QuickAck=. The [DHCP] section now + understands RapidCommit=. + + * systemd-networkd's DHCPv6 support gained support for Prefix + Delegation. + + * sd-bus gained support for a new "watch-bind" feature. When this + feature is enabled, an sd_bus connection may be set up to connect to + an AF_UNIX socket in the file system as soon as it is created. This + functionality is useful for writing early-boot services that + automatically connect to the system bus as soon as it is started, + without ugly time-based polling. systemd-networkd and + systemd-resolved have been updated to make use of this + functionality. busctl exposes this functionality in a new + --watch-bind= command line switch. + + * sd-bus will now optionally synthesize a local "Connected" signal as + soon as a D-Bus connection is set up fully. This message mirrors the + already existing "Disconnected" signal which is synthesized when the + connection is terminated. This signal is generally useful but + particularly handy in combination with the "watch-bind" feature + described above. Synthesizing of this message has to be requested + explicitly through the new API call sd_bus_set_connected_signal(). In + addition a new call sd_bus_is_ready() has been added that checks + whether a connection is fully set up (i.e. between the "Connected" and + "Disconnected" signals). + + * sd-bus gained two new calls sd_bus_request_name_async() and + sd_bus_release_name_async() for asynchronously registering bus + names. Similar, there is now sd_bus_add_match_async() for installing + a signal match asynchronously. All of systemd's own services have + been updated to make use of these calls. Doing these operations + asynchronously has two benefits: it reduces the risk of deadlocks in + case of cyclic dependencies between bus services, and it speeds up + service initialization since synchronization points for bus + round-trips are removed. + + * sd-bus gained two new calls sd_bus_match_signal() and + sd_bus_match_signal_async(), which are similar to sd_bus_add_match() + and sd_bus_add_match_async() but instead of taking a D-Bus match + string take match fields as normal function parameters. + + * sd-bus gained two new calls sd_bus_set_sender() and + sd_bus_message_set_sender() for setting the sender name of outgoing + messages (either for all outgoing messages or for just one specific + one). These calls are only useful in direct connections as on + brokered connections the broker fills in the sender anyway, + overwriting whatever the client filled in. + + * sd-event gained a new pseudo-handle that may be specified on all API + calls where an "sd_event*" object is expected: SD_EVENT_DEFAULT. When + used this refers to the default event loop object of the calling + thread. Note however that this does not implicitly allocate one — + which has to be done prior by using sd_event_default(). Similarly + sd-bus gained three new pseudo-handles SD_BUS_DEFAULT, + SD_BUS_DEFAULT_USER, SD_BUS_DEFAULT_SYSTEM that may be used to refer + to the default bus of the specified type of the calling thread. Here + too this does not implicitly allocate bus connection objects, this + has to be done prior with sd_bus_default() and friends. + + * sd-event gained a new call pair + sd_event_source_{get|set}_io_fd_own(). This may be used to request + automatic closure of the file descriptor an IO event source watches + when the event source is destroyed. + + * systemd-networkd gained support for natively configuring WireGuard + connections. + + * In previous versions systemd synthesized user records both for the + "nobody" (UID 65534) and "root" (UID 0) users in nss-systemd and + internally. In order to simplify distribution-wide renames of the + "nobody" user (like it is planned in Fedora: nfsnobody → nobody), a + new transitional flag file has been added: if + /etc/systemd/dont-synthesize-nobody exists synthesizing of the 65534 + user and group record within the systemd codebase is disabled. + + * systemd-notify gained a new --uid= option for selecting the source + user/UID to use for notification messages sent to the service + manager. + + * journalctl gained a new --grep= option to list only entries in which + the message matches a certain pattern. By default matching is case + insensitive if the pattern is lowercase, and case sensitive + otherwise. Option --case-sensitive=yes|no can be used to override + this an specify case sensitivity or case insensitivity. + + * There's now a "systemd-analyze service-watchdogs" command for printing + the current state of the service runtime watchdog, and optionally + enabling or disabling the per-service watchdogs system-wide if given a + boolean argument (i.e. the concept you configure in WatchdogSec=), for + debugging purposes. There's also a kernel command line option + systemd.service_watchdogs= for controlling the same. + + * Two new "log-level" and "log-target" options for systemd-analyze were + addded that merge the now deprecated get-log-level, set-log-level and + get-log-target, set-log-target pairs. The deprecated options are still + understood for backwards compatibility. The two new options print the + current value when no arguments are given, and set them when a + level/target is given as an argument. + + * sysusers.d's "u" lines now optionally accept both a UID and a GID + specification, separated by a ":" character, in order to create users + where UID and GID do not match. + + Contributions from: Adam Duskett, Alan Jenkins, Alexander Kuleshov, + Alexis Deruelle, Andrew Jeddeloh, Armin Widegreen, Batuhan Osman + Taşkaya, Björn Esser, bleep_blop, Bruce A. Johnson, Chris Down, Clinton + Roy, Colin Walters, Daniel Rusek, Dimitri John Ledkov, Dmitry Rozhkov, + Evgeny Vereshchagin, Ewout van Mansom, Felipe Sateler, Franck Bui, + Frantisek Sumsal, George Gaydarov, Gianluca Boiano, Hans-Christian + Noren Egtvedt, Hans de Goede, Henrik Grindal Bakken, Jan Alexander + Steffens, Jan Klötzke, Jason A. Donenfeld, jdkbx, Jérémy Rosen, + Jerónimo Borque, John Lin, John Paul Herold, Jonathan Rudenberg, Jörg + Thalheim, Ken (Bitsko) MacLeod, Larry Bernstone, Lennart Poettering, + Lucas Werkmeister, Maciej S. Szmigiero, Marek Čermák, Martin Pitt, + Mathieu Malaterre, Matthew Thode, Matthias-Christian Ott, Max Harmathy, + Michael Biebl, Michael Vogt, Michal Koutný, Michal Sekletar, Michał + Szczepański, Mike Gilbert, Nathaniel McCallum, Nicolas Chauvet, Olaf + Hering, Olivier Schwander, Patrik Flykt, Paul Cercueil, Peter Hutterer, + Piotr Drąg, Raphael Vogelgsang, Reverend Homer, Robert Kolchmeyer, + Samuel Dionne-Riel, Sergey Ptashnick, Shawn Landden, Susant Sahani, + Sylvain Plantefève, Thomas H. P. Andersen, Thomas Huth, Tomasz + Bachorski, Vladislav Vishnyakov, Wieland Hoffmann, Yu Watanabe, Zachary + Winnerman, Zbigniew Jędrzejewski-Szmek, Дамјан Георгиевски, Дилян + Палаузов + + — Brno, 2018-01-28 + CHANGES WITH 236: * The modprobe.d/ drop-in for the bonding.ko kernel module introduced @@ -2074,6 +2264,13 @@ CHANGES WITH 229: d /run/lock/lockdev 0775 root lock - + * The settings StartLimitBurst=, StartLimitInterval=, StartLimitAction= + and RebootArgument= have been moved from the [Service] section of + unit files to [Unit], and they are now supported on all unit types, + not just service units. Of course, systemd will continue to + understand these settings also at the old location, in order to + maintain compatibility. + Contributions from: Abdo Roig-Maranges, Alban Crequy, Aleksander Adamowski, Alexander Kuleshov, Andreas Pokorny, Andrei Borzenkov, Andrew Wilcox, Arthur Clement, Beniamino Galvani, Casey Schaufler, @@ -5314,7 +5511,7 @@ CHANGES WITH 209: option as supported by Debian is added. It allows indicating which LUKS slot to use on disk, speeding up key loading. - * The sd_journald_sendv() API call has been checked and + * The sd_journal_sendv() API call has been checked and officially declared to be async-signal-safe so that it may be invoked from signal handlers for logging purposes. @@ -69,11 +69,10 @@ REQUIREMENTS: create additional symlinks in /dev/disk/ and /dev/tape: CONFIG_BLK_DEV_BSG - Required for PrivateNetwork= and PrivateDevices= in service units: + Required for PrivateNetwork= in service units: CONFIG_NET_NS - CONFIG_DEVPTS_MULTIPLE_INSTANCES Note that systemd-localed.service and other systemd units use - PrivateNetwork and PrivateDevices so this is effectively required. + PrivateNetwork so this is effectively required. Required for PrivateUsers= in service units: CONFIG_USER_NS @@ -82,7 +81,7 @@ REQUIREMENTS: CONFIG_IPV6 CONFIG_AUTOFS4_FS CONFIG_TMPFS_XATTR - CONFIG_{TMPFS,EXT4,XFS,BTRFS_FS,...}_POSIX_ACL + CONFIG_{TMPFS,EXT4_FS,XFS,BTRFS_FS,...}_POSIX_ACL CONFIG_SECCOMP CONFIG_SECCOMP_FILTER (required for seccomp support) CONFIG_CHECKPOINT_RESTORE (for the kcmp() syscall) @@ -119,6 +118,9 @@ REQUIREMENTS: isn't. The next best thing is to make this change through a modprobe.d drop-in. This is shipped by default, see modprobe.d/systemd.conf. + Required for systemd-nspawn: + CONFIG_DEVPTS_MULTIPLE_INSTANCES or Linux kernel >= 4.7 + Note that kernel auditing is broken when used with systemd's container code. When using systemd in conjunction with containers, please make sure to either turn off auditing at @@ -24,6 +24,38 @@ Janitorial Clean-ups: Features: +* maybe rework get_user_creds() to query the user database if $SHELL is used + for root, but only then. + +* there should be path_hash_ops and we should use it in tmpfiles' hashmap object to deal with identical but differently spelt paths + +* be stricter with fds we receive for the fdstore: close them asynchronously + +* calenderspec: add support for week numbers and day numbers within a + year. This would allow us to define "bi-weekly" triggers safely. + +* add support for recursive bpf firewalling as supported by the newest kernel + +* add bpf-based implementation of devices cgroup controller logic for compat with cgroupsv2 as supported by newest kernel + +* introduce sd_id128_get_boot_app_specific() which is like + sd_id128_get_machine_app_specific(). After all on long-running systems both + IDs have similar properties. + +* emulate properties of the root cgroup on controllers that don't support such + properties natively on cpu/io/memory, the way we already do it for + "pids". Also, add the same logic to cgtop. + +* set TasksAccounting=1 on the root slice if we are running on the root cgroup, + and similar for the others, as soon as we emulate them properly. After all, + Linux keeps these system-wide stats anyway, and it costs nothing to expose + them. + +* sd-bus: add vtable flag, that may be used to request client creds implicitly + and asynchronously before dispatching the operation + +* implement transient socket unit. + * make use of ethtool veth peer info in machined, for automatically finding out host-side interface pointing to the container. @@ -41,10 +73,6 @@ Features: the runtime dir as we maintain for the fdstore: i.e. keep it around as long as the unit is running or has a job queued. -* hook up sd-bus' creds stuff with SO_PEERGROUPS - -* add async version of sd_bus_add_match and make use of that - * support projid-based quota in machinectl for containers, and then drop implicit btrfs loopback magic in machined @@ -136,9 +164,6 @@ Features: O_NONBLOCK on it. That way people can control if and when to block for logging. -* tighten sd_notify() MAINPID= checks a bit: don't accept foreign PIDs (i.e. - PIDs not managed by the service manager) - * hostnamed: populate form factor data from a new hwdb database, so that old yogas can be recognized as "convertible" too, even if they predate the DMI "convertible" form factor @@ -165,9 +190,6 @@ Features: "systemd-gdb" for attaching to the start-up of any system service in its natural habitat. -* replace all canonicalize_file_name() invocations by chase_symlinks(), in - particulr those where a rootdir is relevant. - * maybe introduce gpt auto discovery for /var/tmp? * maybe add gpt-partition-based user management: each user gets his own @@ -291,10 +313,6 @@ Features: * docs: bring http://www.freedesktop.org/wiki/Software/systemd/MyServiceCantGetRealtime up to date -* mounting and unmounting mount points manually with different source - devices will result in collected on all devices used. - http://lists.freedesktop.org/archives/systemd-devel/2015-April/030225.html - * add a job mode that will fail if a transaction would mean stopping running units. Use this in timedated to manage the NTP service state. @@ -315,7 +333,7 @@ Features: * Rework systemctl's GetAll property parsing to use the generic bus_map_all_properties() API * Port various tools to make use of verbs.[ch], where applicable: busctl, - coredumpctl, hostnamectl, localectl, systemd-analyze, timedatectl + coredumpctl, hostnamectl, localectl, timedatectl * hostnamectl: show root image uuid @@ -482,14 +500,12 @@ Features: - see if we can introduce a new sd_bus_get_owner_machine_id() call to retrieve the machine ID of the machine of the bus itself - see if we can drop more message validation on the sending side - add API to clone sd_bus_message objects - - make AddMatch calls on dbus1 transports async? - longer term: priority inheritance - dbus spec updates: - NameLost/NameAcquired obsolete - GVariant - path escaping - update systemd.special(7) to mention that dbus.socket is only about the compatibility socket now - - test bloom filter generation indexes * sd-event - allow multiple signal handlers per signal? @@ -588,8 +604,6 @@ Features: * exec: when deinitializating a tty device fix the perms and group, too, not only when initializing. Set access mode/gid to 0620/tty. -* service: watchdog logic: for testing purposes allow ping, but do not require pong - * journal: - consider introducing implicit _TTY= + _PPID= + _EUID= + _EGID= + _FSUID= + _FSGID= fields - import and delete pstore filesystem content at startup diff --git a/TRANSIENT-SETTINGS.md b/TRANSIENT-SETTINGS.md index 17fe0604ec..3614456acf 100644 --- a/TRANSIENT-SETTINGS.md +++ b/TRANSIENT-SETTINGS.md @@ -2,20 +2,20 @@ Our intention is to make all settings that are available as unit file settings also available for transient units, through the D-Bus API. At the moment, some -unit types (socket, swap, path) are not supported at all via unit types, but -most others are pretty well supported, with some notable omissions. +unit types (device, swap, target) are not supported at all via unit types, +but most others are pretty well supported, with some notable omissions. The lists below contain all settings currently available in unit files. The ones currently available in transient units are prefixed with `✓`. ## Generic Unit Settings -Only the most important generic unit settings are available for transient units. +Most generic unit settings are available for transient units. ``` ✓ Description= - Documentation= - SourcePath= +✓ Documentation= +✓ SourcePath= ✓ Requires= ✓ Requisite= ✓ Wants= @@ -27,67 +27,70 @@ Only the most important generic unit settings are available for transient units. ✓ PropagatesReloadTo= ✓ ReloadPropagatedFrom= ✓ PartOf= - JoinsNamespaceOf= - RequiresMountsFor= - StopWhenUnneeded= - RefuseManualStart= - RefuseManualStop= - AllowIsolate= +✓ JoinsNamespaceOf= +✓ RequiresMountsFor= +✓ StopWhenUnneeded= +✓ RefuseManualStart= +✓ RefuseManualStop= +✓ AllowIsolate= ✓ DefaultDependencies= - OnFailureJobMode= - OnFailureIsolate= - IgnoreOnIsolate= - JobTimeoutSec= - JobRunningTimeoutSec= - JobTimeoutAction= - JobTimeoutRebootArgument= - StartLimitIntervalSec=SECONDS - StartLimitBurst=UNSIGNED - StartLimitAction=ACTION +✓ OnFailureJobMode= +✓ IgnoreOnIsolate= +✓ JobTimeoutSec= +✓ JobRunningTimeoutSec= +✓ JobTimeoutAction= +✓ JobTimeoutRebootArgument= +✓ StartLimitIntervalSec=SECONDS +✓ StartLimitBurst=UNSIGNED +✓ StartLimitAction=ACTION ✓ FailureAction= ✓ SuccessAction= ✓ AddRef= - RebootArgument=STRING - ConditionPathExists= - ConditionPathExistsGlob= - ConditionPathIsDirectory= - ConditionPathIsSymbolicLink= - ConditionPathIsMountPoint= - ConditionPathIsReadWrite= - ConditionDirectoryNotEmpty= - ConditionFileNotEmpty= - ConditionFileIsExecutable= - ConditionNeedsUpdate= - ConditionFirstBoot= - ConditionKernelCommandLine= - ConditionArchitecture= - ConditionVirtualization= - ConditionSecurity= - ConditionCapability= - ConditionHost= - ConditionACPower= - ConditionUser= - ConditionGroup= - AssertPathExists= - AssertPathExistsGlob= - AssertPathIsDirectory= - AssertPathIsSymbolicLink= - AssertPathIsMountPoint= - AssertPathIsReadWrite= - AssertDirectoryNotEmpty= - AssertFileNotEmpty= - AssertFileIsExecutable= - AssertNeedsUpdate= - AssertFirstBoot= - AssertKernelCommandLine= - AssertArchitecture= - AssertVirtualization= - AssertSecurity= - AssertCapability= - AssertHost= - AssertACPower= - AssertUser= - AssertGroup= +✓ RebootArgument=STRING +✓ ConditionPathExists= +✓ ConditionPathExistsGlob= +✓ ConditionPathIsDirectory= +✓ ConditionPathIsSymbolicLink= +✓ ConditionPathIsMountPoint= +✓ ConditionPathIsReadWrite= +✓ ConditionDirectoryNotEmpty= +✓ ConditionFileNotEmpty= +✓ ConditionFileIsExecutable= +✓ ConditionNeedsUpdate= +✓ ConditionFirstBoot= +✓ ConditionKernelCommandLine= +✓ ConditionKernelVersion= +✓ ConditionArchitecture= +✓ ConditionVirtualization= +✓ ConditionSecurity= +✓ ConditionCapability= +✓ ConditionHost= +✓ ConditionACPower= +✓ ConditionUser= +✓ ConditionGroup= +✓ ConditionControlGroupController= +✓ AssertPathExists= +✓ AssertPathExistsGlob= +✓ AssertPathIsDirectory= +✓ AssertPathIsSymbolicLink= +✓ AssertPathIsMountPoint= +✓ AssertPathIsReadWrite= +✓ AssertDirectoryNotEmpty= +✓ AssertFileNotEmpty= +✓ AssertFileIsExecutable= +✓ AssertNeedsUpdate= +✓ AssertFirstBoot= +✓ AssertKernelCommandLine= +✓ AssertKernelVersion= +✓ AssertArchitecture= +✓ AssertVirtualization= +✓ AssertSecurity= +✓ AssertCapability= +✓ AssertHost= +✓ AssertACPower= +✓ AssertUser= +✓ AssertGroup= +✓ AssertControlGroupController= ✓ CollectMode= ``` @@ -254,63 +257,63 @@ All process killing settings are available for transient units: ## Service Unit Settings -Only the most important service settings are available for transient units. +Most service unit settings are available for transient units. ``` - PIDFile= +✓ PIDFile= ✓ ExecStartPre= ✓ ExecStart= ✓ ExecStartPost= ✓ ExecReload= ✓ ExecStop= ✓ ExecStopPost= - RestartSec= - TimeoutStartSec= - TimeoutStopSec= - TimeoutSec= +✓ RestartSec= +✓ TimeoutStartSec= +✓ TimeoutStopSec= +✓ TimeoutSec= ✓ RuntimeMaxSec= - WatchdogSec= +✓ WatchdogSec= ✓ Type= ✓ Restart= - PermissionsStartOnly= - RootDirectoryStartOnly= +✓ PermissionsStartOnly= +✓ RootDirectoryStartOnly= ✓ RemainAfterExit= - GuessMainPID= - RestartPreventExitStatus= - RestartForceExitStatus= - SuccessExitStatus= +✓ GuessMainPID= +✓ RestartPreventExitStatus= +✓ RestartForceExitStatus= +✓ SuccessExitStatus= ✓ NonBlocking= - BusName= +✓ BusName= ✓ FileDescriptorStoreMax= ✓ NotifyAccess= Sockets= - USBFunctionDescriptors= - USBFunctionStrings= +✓ USBFunctionDescriptors= +✓ USBFunctionStrings= ``` ## Mount Unit Settings -Only the most important mount unit settings are currently available to transient units: +All mount unit settings are available to transient units: ``` ✓ What= - Where= +✓ Where= ✓ Options= ✓ Type= - TimeoutSec= - DirectoryMode= - SloppyOptions= - LazyUnmount= - ForceUnmount= +✓ TimeoutSec= +✓ DirectoryMode= +✓ SloppyOptions= +✓ LazyUnmount= +✓ ForceUnmount= ``` ## Automount Unit Settings -Only one automount unit setting is currently available to transient units: +All automount unit setting is available to transient units: ``` - Where= - DirectoryMode= +✓ Where= +✓ DirectoryMode= ✓ TimeoutIdleSec= ``` @@ -325,7 +328,7 @@ Most timer unit settings are available to transient units. ✓ OnStartupSec= ✓ OnUnitActiveSec= ✓ OnUnitInactiveSec= - Persistent= +✓ Persistent= ✓ WakeSystem= ✓ RemainAfterElapse= ✓ AccuracySec= @@ -341,71 +344,74 @@ of their own beyond the generic unit and resource control settings. ## Scope Unit Settings Scope units are fully supported as transient units (in fact they only exist as -such), but they have no settings of their own beyond the generic unit and -resource control settings. +such). + +``` +✓ TimeoutStopSec= +``` ## Socket Unit Settings -Socket units are currently not available at all as transient units: +Most socket unit settings are available to transient units. ``` - ListenStream= - ListenDatagram= - ListenSequentialPacket= - ListenFIFO= - ListenNetlink= - ListenSpecial= - ListenMessageQueue= - ListenUSBFunction= - SocketProtocol= - BindIPv6Only= - Backlog= - BindToDevice= - ExecStartPre= - ExecStartPost= - ExecStopPre= - ExecStopPost= - TimeoutSec= - SocketUser= - SocketGroup= - SocketMode= - DirectoryMode= - Accept= - Writable= - MaxConnections= - MaxConnectionsPerSource= - KeepAlive= - KeepAliveTimeSec= - KeepAliveIntervalSec= - KeepAliveProbes= - DeferAcceptSec= - NoDelay= - Priority= - ReceiveBuffer= - SendBuffer= - IPTOS= - IPTTL= - Mark= - PipeSize= - FreeBind= - Transparent= - Broadcast= - PassCredentials= - PassSecurity= - TCPCongestion= - ReusePort= - MessageQueueMaxMessages= - MessageQueueMessageSize= - RemoveOnStop= - Symlinks= - FileDescriptorName= +✓ ListenStream= +✓ ListenDatagram= +✓ ListenSequentialPacket= +✓ ListenFIFO= +✓ ListenNetlink= +✓ ListenSpecial= +✓ ListenMessageQueue= +✓ ListenUSBFunction= +✓ SocketProtocol= +✓ BindIPv6Only= +✓ Backlog= +✓ BindToDevice= +✓ ExecStartPre= +✓ ExecStartPost= +✓ ExecStopPre= +✓ ExecStopPost= +✓ TimeoutSec= +✓ SocketUser= +✓ SocketGroup= +✓ SocketMode= +✓ DirectoryMode= +✓ Accept= +✓ Writable= +✓ MaxConnections= +✓ MaxConnectionsPerSource= +✓ KeepAlive= +✓ KeepAliveTimeSec= +✓ KeepAliveIntervalSec= +✓ KeepAliveProbes= +✓ DeferAcceptSec= +✓ NoDelay= +✓ Priority= +✓ ReceiveBuffer= +✓ SendBuffer= +✓ IPTOS= +✓ IPTTL= +✓ Mark= +✓ PipeSize= +✓ FreeBind= +✓ Transparent= +✓ Broadcast= +✓ PassCredentials= +✓ PassSecurity= +✓ TCPCongestion= +✓ ReusePort= +✓ MessageQueueMaxMessages= +✓ MessageQueueMessageSize= +✓ RemoveOnStop= +✓ Symlinks= +✓ FileDescriptorName= Service= - TriggerLimitIntervalSec= - TriggerLimitBurst= - SmackLabel= - SmackLabelIPIn= - SmackLabelIPOut= - SELinuxContextFromNet= +✓ TriggerLimitIntervalSec= +✓ TriggerLimitBurst= +✓ SmackLabel= +✓ SmackLabelIPIn= +✓ SmackLabelIPOut= +✓ SELinuxContextFromNet= ``` ## Swap Unit Settings @@ -421,17 +427,17 @@ Swap units are currently not available at all as transient units: ## Path Unit Settings -Path units are currently not available at all as transient units: +Most path unit settings are available to transient units. ``` - PathExists= - PathExistsGlob= - PathChanged= - PathModified= - DirectoryNotEmpty= +✓ PathExists= +✓ PathExistsGlob= +✓ PathChanged= +✓ PathModified= +✓ DirectoryNotEmpty= Unit= - MakeDirectory= - DirectoryMode= +✓ MakeDirectory= +✓ DirectoryMode= ``` ## Install Section diff --git a/UIDS-GIDS.md b/UIDS-GIDS.md index d44d93d144..e19cc88162 100644 --- a/UIDS-GIDS.md +++ b/UIDS-GIDS.md @@ -17,22 +17,23 @@ i.e. 0…4294967295. However, four UIDs are special on Linux: 1. 0 → The `root` super-user 2. 65534 → The `nobody` UID, also called the "overflow" UID or similar. It's - where various subsystems map unmappable users to, for example NFS or user - namespacing. (The latter can be changed with a sysctl during runtime, but - that's not supported on `systemd`. If you do change it you void your - warranty.) Because Fedora is a bit confused the `nobody` user is called - `nfsnobody` there (and they have a different `nobody` user at UID 99). I - hope this will be corrected eventually though. (Also, some distributions - call the `nobody` group `nogroup`. I wish they didn't.) + where various subsystems map unmappable users to, for example file systems + only supporting 16bit UIDs, NFS or user namespacing. (The latter can be + changed with a sysctl during runtime, but that's not supported on + `systemd`. If you do change it you void your warranty.) Because Fedora is a + bit confused the `nobody` user is called `nfsnobody` there (and they have a + different `nobody` user at UID 99). I hope this will be corrected eventually + though. (Also, some distributions call the `nobody` group `nogroup`. I wish + they didn't.) 3. 4294967295, aka "32bit `(uid_t) -1`" → This UID is not a valid user ID, as - setresuid(), chown() and friends treat -1 as a special request to not change - the UID of the process/file. This UID is hence not available for assignment - to users in the user database. + `setresuid()`, `chown()` and friends treat -1 as a special request to not + change the UID of the process/file. This UID is hence not available for + assignment to users in the user database. -4. 65535, aka "16bit `(uid_t) -1`" → Once upon a time `uid_t` used to be 16bit, and - programs compiled for that would hence assume that `(uid_t) -1` is 65535. This - UID is hence not usable either. +4. 65535, aka "16bit `(uid_t) -1`" → Before Linux kernel 2.4 `uid_t` used to be + 16bit, and programs compiled for that would hence assume that `(uid_t) -1` + is 65535. This UID is hence not usable either. The `nss-systemd` glibc NSS module will synthesize user database records for the UIDs 0 and 65534 if the system user database doesn't list them. This means diff --git a/catalog/systemd.fr.catalog.in b/catalog/systemd.fr.catalog.in index 36c87147a7..6df3b00f3d 100644 --- a/catalog/systemd.fr.catalog.in +++ b/catalog/systemd.fr.catalog.in @@ -346,3 +346,21 @@ Defined-By: systemd Support: %SUPPORT_URL% L'unité (unit) @UNIT@ s'est arrêtée et a consommé les ressources indiquées. + +-- 50876a9db00f4c40bde1a2ad381c3a1b +Subject: Le système est configuré d'une manière qui pourrait causer des problèmes +Defined-By: systemd +Support: %SUPPORT_URL% + +Les étiquettes suivantes sont possibles : +- "split-usr" — /usr est un système de fichiers séparé et nétait pas + monté quand systemd a été démarré +- "cgroups-missing" — le noyau a été compilé sans le support des groupes + de contrôle (cgroups) ou l'accès aux fichiers d'interface est restreint +- "var-run-bad" — /var/run n'est pas un lien symbolique vers /run +- "overflowuid-not-65534" — l'ID utilisé par le noyau pour l'utilisateur + "unknown" (avec NFS ou l'espace de noms utilisateurs) n'est pas 65534 +- "overflowgid-not-65534" — l'ID utilisé par le noyau pour le groupe + "unknown" (avec NFS ou l'espace de noms utilisateurs) n'est pas 65534 + +Le présent système est étiqueté @TAINT@. diff --git a/catalog/systemd.pl.catalog.in b/catalog/systemd.pl.catalog.in index 3641db2e66..3352a59a27 100644 --- a/catalog/systemd.pl.catalog.in +++ b/catalog/systemd.pl.catalog.in @@ -49,7 +49,7 @@ Support: %SUPPORT_URL% @JOURNAL_NAME@ (@JOURNAL_PATH@) obecnie używa @CURRENT_USE_PRETTY@. Maksymalnie może używać @MAX_USE_PRETTY@. -Zostawianie co najmniej @DISK_KEEP_FREE_PRETTY@ wolnego (z obecnie dostępnego @DISK_AVAILABLE_PRETTY@ miejsca na dysku). +Zostawianie co najmniej @DISK_KEEP_FREE_PRETTY@ wolnego (z obecnie dostępnego @DISK_AVAILABLE_PRETTY@ miejsca na dysku). Wymuszone ograniczenie użycia wynosi więc @LIMIT_PRETTY@, z czego @AVAILABLE_PRETTY@ jest nadal dostępne. Ograniczenia kontrolujące ilość miejsca na dysku używanego przez dziennik @@ -94,13 +94,13 @@ Zwykle wskazuje to na błąd programistyczny w danym programie i powinno zosta zgłoszone jego producentowi jako błąd. -- 5aadd8e954dc4b1a8c954d63fd9e1137 -Subject: Plik core został skrócony do @SIZE_LIMIT@ B. +Subject: Plik core został skrócony do @SIZE_LIMIT@ B. Defined-By: systemd Support: %SUPPORT_URL% Documentation: man:coredump.conf(5) Proces miał więcej zmapowanej pamięci niż maksimum dla przetwarzania i miejsca -skonfigurowane przez systemd-coredump(8). Tylko pierwsze @SIZE_LIMIT@ B +skonfigurowane przez systemd-coredump(8). Tylko pierwsze @SIZE_LIMIT@ B zostało zapisanych. Ten plik core może nadal być używalny, ale narzędzia typu gdb(1) będą ostrzegały o skróceniu pliku. @@ -144,7 +144,7 @@ Subject: Zmiana czasu Defined-By: systemd Support: %SUPPORT_URL% -Zegar systemowy został zmieniony na @REALTIME@ μs po 1 stycznia 1970. +Zegar systemowy został zmieniony na @REALTIME@ μs po 1 stycznia 1970. -- 45f82f4aef7a4bbf942ce861d1f20990 Subject: Zmiana strefy czasowej na @TIMEZONE@ @@ -163,11 +163,11 @@ uruchamiania systemu zostały uruchomione. Proszę zauważyć, że nie oznacza to, że komputer jest bezczynny, jako że usługi mogą wciąż kończyć proces uruchamiania. -Uruchamianie jądra zajęło @KERNEL_USEC@ μs. +Uruchamianie jądra zajęło @KERNEL_USEC@ μs. -Uruchamianie początkowego dysku RAM zajęło @INITRD_USEC@ μs. +Uruchamianie początkowego dysku RAM zajęło @INITRD_USEC@ μs. -Uruchamianie przestrzeni użytkownika zajęło @USERSPACE_USEC@ μs. +Uruchamianie przestrzeni użytkownika zajęło @USERSPACE_USEC@ μs. -- eed00a68ffd84e31882105fd973abdd1 Subject: Ukończono uruchamianie menedżera użytkownika @@ -179,7 +179,7 @@ Wszystkie usługi zakolejkowane do włączenia zostały uruchomione. Proszę zauważyć, że inne usługi mogą być nadal uruchamiane lub zostać uruchomione później. -Uruchamianie menedżera zajęło @USERSPACE_USEC@ μs. +Uruchamianie menedżera zajęło @USERSPACE_USEC@ μs. -- 6bbd95ee977941e497c48be27c254128 Subject: Przejście do stanu uśpienia @SLEEP@ @@ -200,7 +200,7 @@ Subject: Zainicjowano wyłączenie systemu Defined-By: systemd Support: %SUPPORT_URL% -Zainicjowano wyłączenie systemd. Wyłączenie zostało rozpoczęte i wszystkie +Zainicjowano wyłączenie systemu. Wyłączenie zostało rozpoczęte i wszystkie usługi systemowe zostały zakończone, a wszystkie systemy plików odmontowane. -- 7d4958e842da4a758f6c1cdc7b36dcc5 @@ -353,3 +353,22 @@ Defined-By: systemd Support: %SUPPORT_URL% Jednostka @UNIT@ została ukończona, zużywając wskazane zasoby. + +-- 50876a9db00f4c40bde1a2ad381c3a1b +Subject: System jest skonfigurowany w sposób, który może powodować problemy +Defined-By: systemd +Support: %SUPPORT_URL% + +Możliwe są następujące „etykiety”: +• „split-usr” — /usr jest oddzielnym systemem plików, który nie był + zamontowany w czasie uruchomienia systemd, +• „cgroups-missing” — jądro zostało skompilowane bez obsługi cgroups + lub dostęp do oczekiwanych plików interfejsu jest ograniczony, +• „var-run-bad” — /var/run nie jest dowiązaniem symbolicznym do /run, +• „overflowuid-not-65534” — identyfikator użytkownika dla „nieznanych” + użytkowników (przy wykorzystaniu przestrzeni nazw użytkowników lub NFS) + nie wynosi 65534, +• „overflowgid-not-65534” — identyfikator grupy dla „nieznanych” + użytkowników (przy wykorzystaniu przestrzeni nazw użytkowników lub NFS) + nie wynosi 65534. +Obecny system ma etykietę „@TAINT@”. diff --git a/catalog/systemd.ru.catalog.in b/catalog/systemd.ru.catalog.in index 25ee6acfba..be6410b508 100644 --- a/catalog/systemd.ru.catalog.in +++ b/catalog/systemd.ru.catalog.in @@ -396,3 +396,24 @@ Defined-By: systemd Support: %SUPPORT_URL% Юнит @UNIT@ завершен. Приводится статистика по потребленным им ресурсам. + +# Subject: The system is configured in a way that might cause problems +-- 50876a9db00f4c40bde1a2ad381c3a1b +Subject: Выявлены потенциальные проблемы в конфигурации системы +Defined-By: systemd +Support: %SUPPORT_URL% + +Перечень всех возможных меток, указывающих на проблемы конфигурации: +- "split-usr" — каталог /usr расположен на отдельной файловой системе, + которая не была смонтирована на момент запуска systemd +- "cgroups-missing" — ядро собрано без поддержки контрольных групп, либо + отсутствуют права для доступа к интерфейсным файлам контрольных групп +- "var-run-bad" — /var/run не является символьной ссылкой на /run +- "overflowuid-not-65534" — используемый ядром UID для "неизвестных" + пользователей (применяется в NFS и пространствах имен пользователей) + не равен 65534 +- "overflowgid-not-65534" — используемый ядром GID для "неизвестных" + пользователей (применяется в NFS и пространствах имен пользователей) + не равен 65534 + +В вашей системе присутствуют следующие проблемы: @TAINT@. diff --git a/coccinelle/debug-logging.cocci b/coccinelle/debug-logging.cocci new file mode 100644 index 0000000000..9084cf773b --- /dev/null +++ b/coccinelle/debug-logging.cocci @@ -0,0 +1,8 @@ +@@ +@@ +- _unlikely_(log_get_max_level() >= LOG_DEBUG) ++ DEBUG_LOGGING +@@ +@@ +- log_get_max_level() >= LOG_DEBUG ++ DEBUG_LOGGING diff --git a/coccinelle/enotsup.cocci b/coccinelle/enotsup.cocci new file mode 100644 index 0000000000..c65734d382 --- /dev/null +++ b/coccinelle/enotsup.cocci @@ -0,0 +1,4 @@ +@@ +@@ +- ENOTSUP ++ EOPNOTSUPP diff --git a/coccinelle/exit-0.cocci b/coccinelle/exit-0.cocci new file mode 100644 index 0000000000..8b81600579 --- /dev/null +++ b/coccinelle/exit-0.cocci @@ -0,0 +1,16 @@ +@@ +@@ +- exit(0); ++ exit(EXIT_SUCCESS); +@@ +@@ +- _exit(0); ++ _exit(EXIT_SUCCESS); +@@ +@@ +- exit(1); ++ exit(EXIT_FAILURE); +@@ +@@ +- _exit(1); ++ _exit(EXIT_FAILURE); diff --git a/coccinelle/isempty.cocci b/coccinelle/isempty.cocci index 1374ee40d7..d8d5275889 100644 --- a/coccinelle/isempty.cocci +++ b/coccinelle/isempty.cocci @@ -6,10 +6,55 @@ expression s; @@ expression s; @@ +- strv_length(s) <= 0 ++ strv_isempty(s) +@@ +expression s; +@@ +- strv_length(s) > 0 ++ !strv_isempty(s) +@@ +expression s; +@@ +- strv_length(s) != 0 ++ !strv_isempty(s) +@@ +expression s; +@@ - strlen(s) == 0 + isempty(s) @@ expression s; @@ +- strlen(s) <= 0 ++ isempty(s) +@@ +expression s; +@@ +- strlen(s) > 0 ++ !isempty(s) +@@ +expression s; +@@ +- strlen(s) != 0 ++ !isempty(s) +@@ +expression s; +@@ - strlen_ptr(s) == 0 + isempty(s) +@@ +expression s; +@@ +- strlen_ptr(s) <= 0 ++ isempty(s) +@@ +expression s; +@@ +- strlen_ptr(s) > 0 ++ !isempty(s) +@@ +expression s; +@@ +- strlen_ptr(s) != 0 ++ !isempty(s) diff --git a/coccinelle/memzero.cocci b/coccinelle/memzero.cocci new file mode 100644 index 0000000000..ebdc3f6a2a --- /dev/null +++ b/coccinelle/memzero.cocci @@ -0,0 +1,30 @@ +@@ +expression s; +@@ +- memset(&s, 0, sizeof(s)) ++ zero(s) +@@ +expression s; +@@ +- memset(s, 0, sizeof(*s)) ++ zero(*s) +@@ +expression s; +@@ +- bzero(&s, sizeof(s)) ++ zero(s) +@@ +expression s; +@@ +- bzero(s, sizeof(*s)) ++ zero(*s) +@@ +expression a, b; +@@ +- memset(a, 0, b) ++ memzero(a, b) +@@ +expression a, b; +@@ +- bzero(a, b) ++ memzero(a, b) diff --git a/coccinelle/o-ndelay.occi b/coccinelle/o-ndelay.occi new file mode 100644 index 0000000000..669424a054 --- /dev/null +++ b/coccinelle/o-ndelay.occi @@ -0,0 +1,4 @@ +@@ +@@ +- O_NDELAY ++ O_NONBLOCK diff --git a/coccinelle/strempty.cocci b/coccinelle/strempty.cocci index e3bd0a1f56..13ceb338f1 100644 --- a/coccinelle/strempty.cocci +++ b/coccinelle/strempty.cocci @@ -8,3 +8,41 @@ expression s; @@ - s ? s : "" + strempty(s) +@@ +expression s; +@@ +- if (!s) +- s = ""; ++ s = strempty(s); +@@ +expression s; +@@ +- s ?: "(null)" ++ strnull(s) +@@ +expression s; +@@ +- s ? s : "(null)" ++ strnull(s) +@@ +expression s; +@@ +- if (!s) +- s = "(null)"; ++ s = strnull(s); +@@ +expression s; +@@ +- s ?: "n/a" ++ strna(s) +@@ +expression s; +@@ +- s ? s : "n/a" ++ strna(s) +@@ +expression s; +@@ +- if (!s) +- s = "n/a"; ++ s = strna(s); diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb index 20d168c488..294101ff0b 100644 --- a/hwdb/20-OUI.hwdb +++ b/hwdb/20-OUI.hwdb @@ -510,7 +510,7 @@ OUI:0000A7* ID_OUI_FROM_DATABASE=NETWORK COMPUTING DEVICES INC. OUI:0000A8* - ID_OUI_FROM_DATABASE=STRATUS COMPUTER INC. + ID_OUI_FROM_DATABASE=Stratus Technologies OUI:0000A9* ID_OUI_FROM_DATABASE=NETWORK SYSTEMS CORP. @@ -3834,7 +3834,7 @@ OUI:0004FB* ID_OUI_FROM_DATABASE=Commtech, Inc. OUI:0004FC* - ID_OUI_FROM_DATABASE=Stratus Computer (DE), Inc. + ID_OUI_FROM_DATABASE=Stratus Technologies OUI:0004FD* ID_OUI_FROM_DATABASE=Japan Control Engineering Co., Ltd. @@ -5886,7 +5886,7 @@ OUI:0007A7* ID_OUI_FROM_DATABASE=A-Z Inc. OUI:0007A8* - ID_OUI_FROM_DATABASE=Haier Group Technologies Ltd. + ID_OUI_FROM_DATABASE=Haier Group Technologies Ltd OUI:0007A9* ID_OUI_FROM_DATABASE=Novasonics @@ -17094,7 +17094,7 @@ OUI:00165B* ID_OUI_FROM_DATABASE=Grip Audio OUI:00165C* - ID_OUI_FROM_DATABASE=Trackflow Ltd + ID_OUI_FROM_DATABASE=Trackflow Ltd. OUI:00165D* ID_OUI_FROM_DATABASE=AirDefense, Inc. @@ -25140,7 +25140,7 @@ OUI:00200D* ID_OUI_FROM_DATABASE=CARL ZEISS OUI:00200E* - ID_OUI_FROM_DATABASE=SATELLITE TECHNOLOGY MGMT, INC + ID_OUI_FROM_DATABASE=NSSLGlobal Technologies AS OUI:00200F* ID_OUI_FROM_DATABASE=EBRAINS Inc @@ -26706,7 +26706,7 @@ OUI:002217* ID_OUI_FROM_DATABASE=Neat Electronics OUI:002218* - ID_OUI_FROM_DATABASE=Verivue Inc. + ID_OUI_FROM_DATABASE=AKAMAI TECHNOLOGIES INC OUI:002219* ID_OUI_FROM_DATABASE=Dell Inc. @@ -27585,7 +27585,7 @@ OUI:00233C* ID_OUI_FROM_DATABASE=Alflex OUI:00233D* - ID_OUI_FROM_DATABASE=Novero holding B.V. + ID_OUI_FROM_DATABASE=Laird Technologies OUI:00233E* ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD @@ -28965,7 +28965,7 @@ OUI:00250B* ID_OUI_FROM_DATABASE=CENTROFACTOR INC OUI:00250C* - ID_OUI_FROM_DATABASE=Enertrac + ID_OUI_FROM_DATABASE=Senet Inc OUI:00250D* ID_OUI_FROM_DATABASE=GZT Telkom-Telmor sp. z o.o. @@ -33035,6 +33035,9 @@ OUI:0056CD* OUI:0057D2* ID_OUI_FROM_DATABASE=Cisco Systems, Inc +OUI:00583F* + ID_OUI_FROM_DATABASE=PC Aquarius + OUI:005907* ID_OUI_FROM_DATABASE=LenovoEMC Products USA, LLC @@ -33899,6 +33902,9 @@ OUI:0071CC* OUI:007263* ID_OUI_FROM_DATABASE=Netcore Technology Inc. +OUI:007278* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + OUI:00738D* ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. @@ -35670,7 +35676,7 @@ OUI:00A020* ID_OUI_FROM_DATABASE=CITICORP/TTI OUI:00A021* - ID_OUI_FROM_DATABASE=General Dynamics + ID_OUI_FROM_DATABASE=General Dynamics Mission Systems OUI:00A022* ID_OUI_FROM_DATABASE=CENTRE FOR DEVELOPMENT OF ADVANCED COMPUTING @@ -36563,6 +36569,9 @@ OUI:00BD3A* OUI:00BD82* ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd +OUI:00BE3B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:00BE75* ID_OUI_FROM_DATABASE=Cisco Systems, Inc @@ -37373,6 +37382,9 @@ OUI:00CAE5* OUI:00CB00* ID_OUI_FROM_DATABASE=Private +OUI:00CBB4* + ID_OUI_FROM_DATABASE=SHENZHEN ATEKO PHOTOELECTRICITY CO.,LTD + OUI:00CBBD* ID_OUI_FROM_DATABASE=Cambridge Broadband Networks Ltd. @@ -37388,6 +37400,9 @@ OUI:00CDFE* OUI:00CF1C* ID_OUI_FROM_DATABASE=Communication Machinery Corporation +OUI:00CFC0* + ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. + OUI:00D000* ID_OUI_FROM_DATABASE=FERRAN SCIENTIFIC, INC. @@ -38268,7 +38283,7 @@ OUI:00E008* ID_OUI_FROM_DATABASE=AMAZING CONTROLS! INC. OUI:00E009* - ID_OUI_FROM_DATABASE=MARATHON TECHNOLOGIES CORP. + ID_OUI_FROM_DATABASE=Stratus Technologies OUI:00E00A* ID_OUI_FROM_DATABASE=DIBA, INC. @@ -39374,6 +39389,9 @@ OUI:046785* OUI:0469F8* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:046B1B* + ID_OUI_FROM_DATABASE=SYSDINE Co., Ltd. + OUI:046C9D* ID_OUI_FROM_DATABASE=Cisco Systems, Inc @@ -39476,6 +39494,9 @@ OUI:0488E2* OUI:048A15* ID_OUI_FROM_DATABASE=Avaya Inc +OUI:048AE1* + ID_OUI_FROM_DATABASE=FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD. + OUI:048B42* ID_OUI_FROM_DATABASE=Skspruce Technologies @@ -39620,6 +39641,9 @@ OUI:04CF25* OUI:04D13A* ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd +OUI:04D3B0* + ID_OUI_FROM_DATABASE=Intel Corporate + OUI:04D3CF* ID_OUI_FROM_DATABASE=Apple, Inc. @@ -39662,6 +39686,9 @@ OUI:04E0C4* OUI:04E1C8* ID_OUI_FROM_DATABASE=IMS Soluções em Energia Ltda. +OUI:04E229* + ID_OUI_FROM_DATABASE=Qingdao Haier Technology Co.,Ltd + OUI:04E2F8* ID_OUI_FROM_DATABASE=AEP Ticketing solutions srl @@ -39716,6 +39743,9 @@ OUI:04F938* OUI:04FA3F* ID_OUI_FROM_DATABASE=Opticore Inc. +OUI:04FA83* + ID_OUI_FROM_DATABASE=Qingdao Haier Technology Co.,Ltd + OUI:04FE31* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -40472,6 +40502,9 @@ OUI:0896AD* OUI:0896D7* ID_OUI_FROM_DATABASE=AVM GmbH +OUI:089734* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + OUI:089758* ID_OUI_FROM_DATABASE=Shenzhen Strong Rising Electronics Co.,Ltd DongGuan Subsidiary @@ -40589,6 +40622,9 @@ OUI:08D833* OUI:08DF1F* ID_OUI_FROM_DATABASE=Bose Corporation +OUI:08DFCB* + ID_OUI_FROM_DATABASE=Systrome Networks + OUI:08E5DA* ID_OUI_FROM_DATABASE=NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD. @@ -40685,6 +40721,9 @@ OUI:08F2F4* OUI:08F4AB* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:08F69C* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:08F6F8* ID_OUI_FROM_DATABASE=GET Engineering @@ -40757,6 +40796,9 @@ OUI:0C1DC2* OUI:0C2026* ID_OUI_FROM_DATABASE=noax Technologies AG +OUI:0C2138* + ID_OUI_FROM_DATABASE=Hengstler GmbH + OUI:0C2369* ID_OUI_FROM_DATABASE=Honeywell SPS @@ -40775,6 +40817,9 @@ OUI:0C2A69* OUI:0C2AE7* ID_OUI_FROM_DATABASE=Beijing General Research Institute of Mining and Metallurgy +OUI:0C2C54* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:0C2D89* ID_OUI_FROM_DATABASE=QiiQ Communications Inc. @@ -40928,6 +40973,51 @@ OUI:0C72D9* OUI:0C73BE* ID_OUI_FROM_DATABASE=Dongguan Haimai Electronie Technology Co.,Ltd +OUI:0C73EB0* + ID_OUI_FROM_DATABASE=Gemini Data Loggers (UK) Limited + +OUI:0C73EB1* + ID_OUI_FROM_DATABASE=EVERSEC TECHNOLOGY CORPORATION + +OUI:0C73EB2* + ID_OUI_FROM_DATABASE=Deltapath, Inc. + +OUI:0C73EB3* + ID_OUI_FROM_DATABASE=Tiinlab Acoustic Technology (Shenzhen) Co., Ltd. + +OUI:0C73EB4* + ID_OUI_FROM_DATABASE=U-PASS.CO.,LTD + +OUI:0C73EB5* + ID_OUI_FROM_DATABASE=Husty M.Styczen J.Hupert Sp.J. + +OUI:0C73EB6* + ID_OUI_FROM_DATABASE=Green Fox Electro AS + +OUI:0C73EB7* + ID_OUI_FROM_DATABASE=Dinkle Enterprise Co., Ltd. + +OUI:0C73EB8* + ID_OUI_FROM_DATABASE=Beijing Miiiw Technology Co., Ltd + +OUI:0C73EB9* + ID_OUI_FROM_DATABASE=Beijing L&S Lancom Platform Tech. Co., Ltd. + +OUI:0C73EBA* + ID_OUI_FROM_DATABASE=Pi Innovo LLC + +OUI:0C73EBB* + ID_OUI_FROM_DATABASE=Synaccess Networks + +OUI:0C73EBC* + ID_OUI_FROM_DATABASE=Shenzhen Samchung Video Technology Co., Ltd. + +OUI:0C73EBD* + ID_OUI_FROM_DATABASE=D-Link (Shanghai)Limited Corp. + +OUI:0C73EBE* + ID_OUI_FROM_DATABASE=Taiwan Pulse Motion Co., Ltd. + OUI:0C74C2* ID_OUI_FROM_DATABASE=Apple, Inc. @@ -40946,6 +41036,9 @@ OUI:0C771A* OUI:0C7D7C* ID_OUI_FROM_DATABASE=Kexiang Information Technology Co, Ltd. +OUI:0C8063* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + OUI:0C8112* ID_OUI_FROM_DATABASE=Private @@ -41060,6 +41153,9 @@ OUI:0CB2B7* OUI:0CB319* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:0CB34F* + ID_OUI_FROM_DATABASE=Shenzhen Xiaoqi Intelligent Technology Co., Ltd. + OUI:0CB459* ID_OUI_FROM_DATABASE=Marketech International Corp. @@ -41430,7 +41526,7 @@ OUI:101C0C* ID_OUI_FROM_DATABASE=Apple, Inc. OUI:101D51* - ID_OUI_FROM_DATABASE=8Mesh Networks + ID_OUI_FROM_DATABASE=8Mesh Networks Limited OUI:101DC0* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -41573,6 +41669,9 @@ OUI:1062EB* OUI:1064E2* ID_OUI_FROM_DATABASE=ADFweb.com s.r.l. +OUI:106530* + ID_OUI_FROM_DATABASE=Dell Inc. + OUI:1065A3* ID_OUI_FROM_DATABASE=Core Brands LLC @@ -41654,6 +41753,9 @@ OUI:109266* OUI:1093E9* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:1094BB* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:10954B* ID_OUI_FROM_DATABASE=Megabyte Ltd. @@ -41702,6 +41804,9 @@ OUI:10B1F8* OUI:10B26B* ID_OUI_FROM_DATABASE=base Co.,Ltd. +OUI:10B36F* + ID_OUI_FROM_DATABASE=Bowei Technology Company Limited + OUI:10B713* ID_OUI_FROM_DATABASE=Private @@ -41900,6 +42005,9 @@ OUI:140708* OUI:1407E0* ID_OUI_FROM_DATABASE=Abrantix AG +OUI:1409DC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:140C5B* ID_OUI_FROM_DATABASE=PLNetworks @@ -41993,6 +42101,9 @@ OUI:141FBAE* OUI:141FBAF* ID_OUI_FROM_DATABASE=Private +OUI:14205E* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:1422DB* ID_OUI_FROM_DATABASE=eero inc. @@ -42266,6 +42377,9 @@ OUI:1499E2* OUI:149A10* ID_OUI_FROM_DATABASE=Microsoft Corporation +OUI:149B2F* + ID_OUI_FROM_DATABASE=JiangSu ZhongXie Intelligent Technology co., LTD + OUI:149D09* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -43022,6 +43136,9 @@ OUI:18F0E4* OUI:18F145* ID_OUI_FROM_DATABASE=NetComm Wireless Limited +OUI:18F1D8* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:18F292* ID_OUI_FROM_DATABASE=Shannon Systems @@ -43058,6 +43175,9 @@ OUI:18FF0F* OUI:18FF2E* ID_OUI_FROM_DATABASE=Shenzhen Rui Ying Da Technology Co., Ltd +OUI:1C0042* + ID_OUI_FROM_DATABASE=NARI Technology Co., Ltd. + OUI:1C0656* ID_OUI_FROM_DATABASE=IDY Corporation @@ -43985,6 +44105,9 @@ OUI:2012D5* OUI:2013E0* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:2016B9* + ID_OUI_FROM_DATABASE=Intel Corporate + OUI:2016D8* ID_OUI_FROM_DATABASE=Liteon Technology Corporation @@ -44069,6 +44192,9 @@ OUI:2046F9* OUI:204747* ID_OUI_FROM_DATABASE=Dell Inc. +OUI:2047DA* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + OUI:2047ED* ID_OUI_FROM_DATABASE=BSkyB Ltd @@ -44555,6 +44681,9 @@ OUI:242642* OUI:2429FE* ID_OUI_FROM_DATABASE=KYOCERA Corporation +OUI:242E02* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:242FFA* ID_OUI_FROM_DATABASE=Toshiba Global Commerce Solutions @@ -44883,7 +45012,7 @@ OUI:24C696* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd OUI:24C848* - ID_OUI_FROM_DATABASE=mywerk system GmbH + ID_OUI_FROM_DATABASE=mywerk Portal GmbH OUI:24C86E* ID_OUI_FROM_DATABASE=Chaney Instrument Co. @@ -44981,6 +45110,9 @@ OUI:24F094* OUI:24F0FF* ID_OUI_FROM_DATABASE=GHT Co., Ltd. +OUI:24F128* + ID_OUI_FROM_DATABASE=Telstra + OUI:24F27F* ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise @@ -45047,6 +45179,9 @@ OUI:281471* OUI:28162E* ID_OUI_FROM_DATABASE=2Wire Inc +OUI:2816A8* + ID_OUI_FROM_DATABASE=Microsoft Corporation + OUI:2816AD* ID_OUI_FROM_DATABASE=Intel Corporate @@ -45437,6 +45572,9 @@ OUI:28A6DB* OUI:28AC67* ID_OUI_FROM_DATABASE=Mach Power, Rappresentanze Internazionali s.r.l. +OUI:28AC9E* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + OUI:28AD3E* ID_OUI_FROM_DATABASE=Shenzhen TONG BO WEI Technology CO.,LTD @@ -45749,6 +45887,12 @@ OUI:28FD80F* OUI:28FECD* ID_OUI_FROM_DATABASE=Lemobile Information Technology (Beijing) Co., Ltd. +OUI:28FEDE* + ID_OUI_FROM_DATABASE=COMESTA, Inc. + +OUI:28FF3C* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:28FF3E* ID_OUI_FROM_DATABASE=zte corporation @@ -45935,6 +46079,9 @@ OUI:2C27D7* OUI:2C282D* ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD. +OUI:2C28B7* + ID_OUI_FROM_DATABASE=Hangzhou Ruiying technology co., LTD + OUI:2C2997* ID_OUI_FROM_DATABASE=Microsoft Corporation @@ -46322,6 +46469,9 @@ OUI:2CB693* OUI:2CB69D* ID_OUI_FROM_DATABASE=RED Digital Cinema +OUI:2CB8ED* + ID_OUI_FROM_DATABASE=SonicWall + OUI:2CBABA* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -46493,6 +46643,9 @@ OUI:30055C* OUI:30074D* ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) +OUI:300AC5* + ID_OUI_FROM_DATABASE=Ruio telecommunication technologies Co., Limited + OUI:300B9C* ID_OUI_FROM_DATABASE=Delta Mobile Systems, Inc. @@ -46541,8 +46694,50 @@ OUI:301966* OUI:301A28* ID_OUI_FROM_DATABASE=Mako Networks Ltd -OUI:301F9A* - ID_OUI_FROM_DATABASE=IEEE Registration Authority +OUI:301F9A0* + ID_OUI_FROM_DATABASE=ILSAN ELECTRONICS + +OUI:301F9A1* + ID_OUI_FROM_DATABASE=Dewesoft d.o.o. + +OUI:301F9A2* + ID_OUI_FROM_DATABASE=CHISON Medical Technologies Co., Ltd. + +OUI:301F9A3* + ID_OUI_FROM_DATABASE=MICOMSOFT CO.,LTD. + +OUI:301F9A4* + ID_OUI_FROM_DATABASE=NCM Supplies, Inc. + +OUI:301F9A5* + ID_OUI_FROM_DATABASE=Beijing Surestar Technology Co. Ltd, + +OUI:301F9A6* + ID_OUI_FROM_DATABASE=YiSheng technology co.,LTD + +OUI:301F9A7* + ID_OUI_FROM_DATABASE=Triax A/S + +OUI:301F9A8* + ID_OUI_FROM_DATABASE=FINE TRIUMPH TECHNOLOGY CORP.,LTD. + +OUI:301F9A9* + ID_OUI_FROM_DATABASE=Private + +OUI:301F9AA* + ID_OUI_FROM_DATABASE=HUNAN CHANGSHA HENGJIAN TECHNOLDGY DEVELPMENT CO.,LTD. + +OUI:301F9AB* + ID_OUI_FROM_DATABASE=Smart Component Technologies LTD + +OUI:301F9AC* + ID_OUI_FROM_DATABASE=Origami Group Limited + +OUI:301F9AD* + ID_OUI_FROM_DATABASE=OLIMEX Ltd + +OUI:301F9AE* + ID_OUI_FROM_DATABASE=Shenzhen Fengliyuan Energy Conservating Technology Co. Ltd OUI:30215B* ID_OUI_FROM_DATABASE=Shenzhen Ostar Display Electronic Co.,Ltd @@ -46707,7 +46902,7 @@ OUI:30786B* ID_OUI_FROM_DATABASE=TIANJIN Golden Pentagon Electronics Co., Ltd. OUI:3078C2* - ID_OUI_FROM_DATABASE=Innowireless, Co. Ltd. + ID_OUI_FROM_DATABASE=Innowireless / QUCELL Networks OUI:307BAC* ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd @@ -46877,6 +47072,9 @@ OUI:30D587* OUI:30D6C9* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:30D9D9* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:30DE86* ID_OUI_FROM_DATABASE=Cedac Software S.r.l. @@ -47312,6 +47510,9 @@ OUI:346987* OUI:346AC2* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +OUI:346B46* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + OUI:346BD3* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -47399,6 +47600,9 @@ OUI:348A7B* OUI:348AAE* ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS +OUI:348B75* + ID_OUI_FROM_DATABASE=LAVA INTERNATIONAL(H.K) LIMITED + OUI:348F27* ID_OUI_FROM_DATABASE=Ruckus Wireless @@ -47681,6 +47885,9 @@ OUI:34E70B* OUI:34E71C* ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd +OUI:34E894* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + OUI:34E911* ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. @@ -47864,6 +48071,9 @@ OUI:382DE8* OUI:3831AC* ID_OUI_FROM_DATABASE=WEG +OUI:3835FB* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + OUI:38378B* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -48089,6 +48299,9 @@ OUI:388345* OUI:388602* ID_OUI_FROM_DATABASE=Flexoptix GmbH +OUI:38892C* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:3889DC* ID_OUI_FROM_DATABASE=Opticon Sensors Europe B.V. @@ -48173,6 +48386,9 @@ OUI:38AD8E* OUI:38ADBE* ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd +OUI:38AF29* + ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. + OUI:38AFD7* ID_OUI_FROM_DATABASE=FUJITSU LIMITED @@ -48239,6 +48455,9 @@ OUI:38B8EBD* OUI:38B8EBE* ID_OUI_FROM_DATABASE=Wyres SAS +OUI:38BAF8* + ID_OUI_FROM_DATABASE=Intel Corporate + OUI:38BB23* ID_OUI_FROM_DATABASE=OzVision America LLC @@ -48512,6 +48731,9 @@ OUI:3C15C2* OUI:3C15EA* ID_OUI_FROM_DATABASE=TESCOM CO., LTD. +OUI:3C15FB* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:3C1710* ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS @@ -48545,6 +48767,39 @@ OUI:3C1E04* OUI:3C1E13* ID_OUI_FROM_DATABASE=HANGZHOU SUNRISE TECHNOLOGY CO., LTD +OUI:3C24F00* + ID_OUI_FROM_DATABASE=SHENZHEN PINSIDA TECHNOLOGY CO.,LTD. + +OUI:3C24F01* + ID_OUI_FROM_DATABASE=Abrites Ltd. + +OUI:3C24F03* + ID_OUI_FROM_DATABASE=Wisycom + +OUI:3C24F04* + ID_OUI_FROM_DATABASE=Inter-Coastal Electronics + +OUI:3C24F06* + ID_OUI_FROM_DATABASE=Inter Action Corporation + +OUI:3C24F07* + ID_OUI_FROM_DATABASE=Swissdotnet SA + +OUI:3C24F09* + ID_OUI_FROM_DATABASE=Siemens AG - Siemens Deutschland Mobility + +OUI:3C24F0A* + ID_OUI_FROM_DATABASE=Shenzhen Bestway Technology Co., Ltd + +OUI:3C24F0B* + ID_OUI_FROM_DATABASE=COMATIS + +OUI:3C24F0C* + ID_OUI_FROM_DATABASE=Authentico Technologies + +OUI:3C24F0D* + ID_OUI_FROM_DATABASE=Travis Holding B.V. + OUI:3C25D7* ID_OUI_FROM_DATABASE=Nokia Corporation @@ -48965,6 +49220,9 @@ OUI:3CCB7C* OUI:3CCD5A* ID_OUI_FROM_DATABASE=Technische Alternative GmbH +OUI:3CCD5D* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:3CCD93* ID_OUI_FROM_DATABASE=LG ELECTRONICS INC @@ -49016,6 +49274,9 @@ OUI:3CDFBD* OUI:3CE072* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:3CE1A1* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + OUI:3CE5A6* ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited @@ -49031,6 +49292,9 @@ OUI:3CE824* OUI:3CEA4F* ID_OUI_FROM_DATABASE=2Wire Inc +OUI:3CEAF9* + ID_OUI_FROM_DATABASE=JUBIXCOLTD + OUI:3CEAFB* ID_OUI_FROM_DATABASE=NSE AG @@ -49271,6 +49535,9 @@ OUI:404E36* OUI:404EEB* ID_OUI_FROM_DATABASE=Higher Way Electronic Co., Ltd. +OUI:4050B5* + ID_OUI_FROM_DATABASE=Shenzhen New Species Technology Co., Ltd. + OUI:4050E0* ID_OUI_FROM_DATABASE=Milton Security Group LLC @@ -49319,6 +49586,9 @@ OUI:406186* OUI:40618E* ID_OUI_FROM_DATABASE=Stella-Green Co +OUI:406231* + ID_OUI_FROM_DATABASE=GIFA + OUI:4062B6* ID_OUI_FROM_DATABASE=Tele system communication @@ -49385,6 +49655,9 @@ OUI:407FE0* OUI:408256* ID_OUI_FROM_DATABASE=Continental Automotive GmbH +OUI:40831D* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:4083DE* ID_OUI_FROM_DATABASE=Zebra Technologies Inc @@ -49610,6 +49883,9 @@ OUI:40CBC0* OUI:40CD3A* ID_OUI_FROM_DATABASE=Z3 Technology +OUI:40CD7A* + ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd. + OUI:40CE24* ID_OUI_FROM_DATABASE=Cisco Systems, Inc @@ -49706,6 +49982,9 @@ OUI:40EF4C* OUI:40F02F* ID_OUI_FROM_DATABASE=Liteon Technology Corporation +OUI:40F04E* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + OUI:40F14C* ID_OUI_FROM_DATABASE=ISE Europe SPRL @@ -49829,6 +50108,9 @@ OUI:441CA8* OUI:441E91* ID_OUI_FROM_DATABASE=ARVIDA Intelligent Electronics Technology Co.,Ltd. +OUI:441E98* + ID_OUI_FROM_DATABASE=Ruckus Wireless + OUI:441EA1* ID_OUI_FROM_DATABASE=Hewlett Packard @@ -49868,6 +50150,9 @@ OUI:44334C* OUI:44348F* ID_OUI_FROM_DATABASE=MXT INDUSTRIAL LTDA +OUI:4434A7* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + OUI:44356F* ID_OUI_FROM_DATABASE=Neterix @@ -49979,6 +50264,9 @@ OUI:44656A* OUI:44666E* ID_OUI_FROM_DATABASE=IP-LINE +OUI:4466FC* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + OUI:446755* ID_OUI_FROM_DATABASE=Orbit Irrigation @@ -50312,6 +50600,51 @@ OUI:480362* OUI:48066A* ID_OUI_FROM_DATABASE=Tempered Networks, Inc. +OUI:480BB20* + ID_OUI_FROM_DATABASE=Ridango AS + +OUI:480BB21* + ID_OUI_FROM_DATABASE=BAJA ELECTRONICS TECHNOLOGY LIMITED + +OUI:480BB22* + ID_OUI_FROM_DATABASE=Thales CETCA Avionics CO., Ltd + +OUI:480BB23* + ID_OUI_FROM_DATABASE=shanghai Rinlink Intelligent Technology Co., Ltd. + +OUI:480BB24* + ID_OUI_FROM_DATABASE=Hangzhou Freely Communication Co., Ltd. + +OUI:480BB25* + ID_OUI_FROM_DATABASE=Solaredge LTD. + +OUI:480BB26* + ID_OUI_FROM_DATABASE=annapurnalabs + +OUI:480BB27* + ID_OUI_FROM_DATABASE=Beijing Dragon Resources Limited. + +OUI:480BB28* + ID_OUI_FROM_DATABASE=BravoCom(xiamen)TechCo.Ltd + +OUI:480BB29* + ID_OUI_FROM_DATABASE=Microprogram Information Co., Ltd + +OUI:480BB2A* + ID_OUI_FROM_DATABASE=XIAMEN RONGTA TECHNOLOGY CO.,LTD. + +OUI:480BB2B* + ID_OUI_FROM_DATABASE=Popit Oy + +OUI:480BB2C* + ID_OUI_FROM_DATABASE=SHENZHEN TOPWELL TECHNOLOGY CO..LTD + +OUI:480BB2D* + ID_OUI_FROM_DATABASE=M2Lab Ltd. + +OUI:480BB2E* + ID_OUI_FROM_DATABASE=Beijing MFOX technology Co., Ltd. + OUI:480C49* ID_OUI_FROM_DATABASE=NAKAYO Inc @@ -50456,6 +50789,9 @@ OUI:485D36* OUI:485D60* ID_OUI_FROM_DATABASE=AzureWave Technology Inc. +OUI:48605F* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + OUI:4860BC* ID_OUI_FROM_DATABASE=Apple, Inc. @@ -50615,6 +50951,9 @@ OUI:48A6D2* OUI:48A74E* ID_OUI_FROM_DATABASE=zte corporation +OUI:48A91C* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:48A9D2* ID_OUI_FROM_DATABASE=Wistron Neweb Corporation @@ -50732,6 +51071,9 @@ OUI:48DB50* OUI:48DCFB* ID_OUI_FROM_DATABASE=Nokia Corporation +OUI:48DD9D* + ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED + OUI:48DF1C* ID_OUI_FROM_DATABASE=Wuhan NEC Fibre Optic Communications industry Co. Ltd @@ -51233,6 +51575,9 @@ OUI:4CBCA5* OUI:4CBD8F* ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. +OUI:4CC00A* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + OUI:4CC206* ID_OUI_FROM_DATABASE=Somfy @@ -51263,6 +51608,9 @@ OUI:4CCC6A* OUI:4CD08A* ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. +OUI:4CD0CB* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:4CD637* ID_OUI_FROM_DATABASE=Qsono Electronics Co., Ltd @@ -51488,6 +51836,9 @@ OUI:501CB0* OUI:501CBF* ID_OUI_FROM_DATABASE=Cisco Systems, Inc +OUI:501D93* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:501E2D* ID_OUI_FROM_DATABASE=StreamUnlimited Engineering GmbH @@ -51611,6 +51962,9 @@ OUI:50502A* OUI:505065* ID_OUI_FROM_DATABASE=TAKT Corporation +OUI:5050CE* + ID_OUI_FROM_DATABASE=Hangzhou Dianyixia Communication Technology Co. Ltd. + OUI:5052D2* ID_OUI_FROM_DATABASE=Hangzhou Telin Technologies Co., Limited @@ -51638,6 +51992,12 @@ OUI:50584F* OUI:505AC6* ID_OUI_FROM_DATABASE=GUANGDONG SUPER TELECOM CO.,LTD. +OUI:505BC2* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:505DAC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:506028* ID_OUI_FROM_DATABASE=Xirrus Inc. @@ -51797,6 +52157,9 @@ OUI:509F27* OUI:509F3B* ID_OUI_FROM_DATABASE=OI ELECTRIC CO.,LTD +OUI:50A009* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + OUI:50A054* ID_OUI_FROM_DATABASE=Actineon @@ -51851,6 +52214,9 @@ OUI:50A4D0D* OUI:50A4D0E* ID_OUI_FROM_DATABASE=Sagetech Corporation +OUI:50A67F* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:50A6E3* ID_OUI_FROM_DATABASE=David Clark Company @@ -51896,6 +52262,9 @@ OUI:50B888* OUI:50B8A2* ID_OUI_FROM_DATABASE=ImTech Technologies LLC, +OUI:50BC96* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:50BD5F* ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. @@ -52361,6 +52730,9 @@ OUI:549359* OUI:549478* ID_OUI_FROM_DATABASE=Silvershore Technology Partners +OUI:549963* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:549A110* ID_OUI_FROM_DATABASE=Shenzhen Excera Technology Co.,Ltd. @@ -52994,6 +53366,9 @@ OUI:58B961* OUI:58B9E1* ID_OUI_FROM_DATABASE=Crystalfontz America, Inc. +OUI:58BAD4* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:58BC27* ID_OUI_FROM_DATABASE=Cisco Systems, Inc @@ -53048,6 +53423,9 @@ OUI:58D759* OUI:58D9D5* ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch +OUI:58DB15* + ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED + OUI:58DB8D* ID_OUI_FROM_DATABASE=Fast Co., Ltd. @@ -53153,6 +53531,9 @@ OUI:58F67B* OUI:58F6BF* ID_OUI_FROM_DATABASE=Kyoto University +OUI:58F987* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:58F98E* ID_OUI_FROM_DATABASE=SECUDOS GmbH @@ -53225,6 +53606,9 @@ OUI:5C0339* OUI:5C076F* ID_OUI_FROM_DATABASE=Thought Creator +OUI:5C0947* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:5C0979* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -53267,6 +53651,9 @@ OUI:5C18B5* OUI:5C1A6F* ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. +OUI:5C1DD9* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:5C20D0* ID_OUI_FROM_DATABASE=Asoni Communication Co., Ltd. @@ -53885,6 +54272,9 @@ OUI:602AD0* OUI:602E20* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +OUI:6030D4* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:60313B* ID_OUI_FROM_DATABASE=Sunnovo International Limited @@ -54314,6 +54704,9 @@ OUI:60DB2A* OUI:60DE44* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +OUI:60DEF3* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:60E00E* ID_OUI_FROM_DATABASE=SHINSEI ELECTRONICS CO LTD @@ -54473,6 +54866,9 @@ OUI:641A22* OUI:641C67* ID_OUI_FROM_DATABASE=DIGIBRAS INDUSTRIA DO BRASILS/A +OUI:641CAE* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + OUI:641CB0* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -54584,6 +54980,9 @@ OUI:6459F8* OUI:645A04* ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd. +OUI:645AED* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:645D92* ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD @@ -54641,6 +55040,9 @@ OUI:646EEA* OUI:647002* ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. +OUI:647033* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:6472D8* ID_OUI_FROM_DATABASE=GooWi Technology Co.,Limited @@ -55082,6 +55484,9 @@ OUI:6828BA* OUI:6828F6* ID_OUI_FROM_DATABASE=Vubiq Networks, Inc. +OUI:682C7B* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + OUI:682DDC* ID_OUI_FROM_DATABASE=Wuhan Changjiang Electro-Communication Equipment CO.,LTD @@ -55241,6 +55646,9 @@ OUI:6886E7* OUI:68876B* ID_OUI_FROM_DATABASE=INQ Mobile Limited +OUI:688975* + ID_OUI_FROM_DATABASE=nuoxc + OUI:6889C1* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -55421,6 +55829,9 @@ OUI:68C90B* OUI:68CA00* ID_OUI_FROM_DATABASE=Octopus Systems Limited +OUI:68CAE4* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + OUI:68CC6E* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -55433,6 +55844,9 @@ OUI:68CD0F* OUI:68CE4E* ID_OUI_FROM_DATABASE=L-3 Communications Infrared Products +OUI:68D1BA* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + OUI:68D1FD* ID_OUI_FROM_DATABASE=Shenzhen Trimax Technology Co.,Ltd @@ -55532,6 +55946,9 @@ OUI:68FCB3* OUI:68FEDA* ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD +OUI:68FEF7* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:6C0273* ID_OUI_FROM_DATABASE=Shenzhen Jin Yun Video Equipment Co., Ltd. @@ -55586,6 +56003,9 @@ OUI:6C1E90* OUI:6C2056* ID_OUI_FROM_DATABASE=Cisco Systems, Inc +OUI:6C21A2* + ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. + OUI:6C22AB* ID_OUI_FROM_DATABASE=Ainsworth Game Technology @@ -55628,6 +56048,9 @@ OUI:6C32DE* OUI:6C33A9* ID_OUI_FROM_DATABASE=Magicjack LP +OUI:6C3838* + ID_OUI_FROM_DATABASE=Marking System Technology Co., Ltd. + OUI:6C38A1* ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited @@ -55883,6 +56306,9 @@ OUI:6CADF8* OUI:6CAE8B* ID_OUI_FROM_DATABASE=IBM Corporation +OUI:6CAF15* + ID_OUI_FROM_DATABASE=Webasto SE + OUI:6CB0CE* ID_OUI_FROM_DATABASE=NETGEAR @@ -56033,6 +56459,9 @@ OUI:6CFFBE* OUI:700136* ID_OUI_FROM_DATABASE=FATEK Automation Corporation +OUI:7001B5* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + OUI:700258* ID_OUI_FROM_DATABASE=01DB-METRAVIB @@ -56084,6 +56513,9 @@ OUI:701AED* OUI:701CE7* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:701D08* + ID_OUI_FROM_DATABASE=99IOT Shenzhen co.,ltd + OUI:701D7F* ID_OUI_FROM_DATABASE=Comtech Technology Co., Ltd. @@ -56366,6 +56798,9 @@ OUI:707938* OUI:707990* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +OUI:7079B3* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + OUI:707BE8* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -56588,6 +57023,12 @@ OUI:70B3D501F* OUI:70B3D5022* ID_OUI_FROM_DATABASE=Ravelin Ltd +OUI:70B3D5023* + ID_OUI_FROM_DATABASE=Cambridge Pixel + +OUI:70B3D5024* + ID_OUI_FROM_DATABASE=G+D Mobile Security + OUI:70B3D5025* ID_OUI_FROM_DATABASE=Elsuhd Net Ltd Co. @@ -56654,6 +57095,9 @@ OUI:70B3D5044* OUI:70B3D5046* ID_OUI_FROM_DATABASE=Shenzhen Rihuida Electronics Co,. Ltd +OUI:70B3D5049* + ID_OUI_FROM_DATABASE=APP Engineering, Inc. + OUI:70B3D504A* ID_OUI_FROM_DATABASE=Gecko Robotics Inc @@ -56900,6 +57344,9 @@ OUI:70B3D50D2* OUI:70B3D50D3* ID_OUI_FROM_DATABASE=TSAT AS +OUI:70B3D50D4* + ID_OUI_FROM_DATABASE=Guangzhou Male Industrial Animation Technology Co.,Ltd. + OUI:70B3D50D6* ID_OUI_FROM_DATABASE=TATTILE SRL @@ -56999,6 +57446,9 @@ OUI:70B3D510A* OUI:70B3D510C* ID_OUI_FROM_DATABASE=Vocality International Ltd +OUI:70B3D510E* + ID_OUI_FROM_DATABASE=Colorimetry Research, Inc + OUI:70B3D510F* ID_OUI_FROM_DATABASE=neQis @@ -57098,12 +57548,18 @@ OUI:70B3D513F* OUI:70B3D5140* ID_OUI_FROM_DATABASE=Virta Laboratories, Inc. +OUI:70B3D5141* + ID_OUI_FROM_DATABASE=M.T. S.R.L. + OUI:70B3D5142* ID_OUI_FROM_DATABASE=DAVE SRL OUI:70B3D5144* ID_OUI_FROM_DATABASE=GS Elektromedizinsiche Geräte G. Stemple GmbH +OUI:70B3D5145* + ID_OUI_FROM_DATABASE=Sicon srl + OUI:70B3D5146* ID_OUI_FROM_DATABASE=3City Electronics @@ -57137,6 +57593,9 @@ OUI:70B3D5152* OUI:70B3D5153* ID_OUI_FROM_DATABASE=Schneider Electric Motion USA +OUI:70B3D5154* + ID_OUI_FROM_DATABASE=Walk Horizon Technology (Beijing) Co., Ltd. + OUI:70B3D515C* ID_OUI_FROM_DATABASE=Woods Hole Oceanographic Institution @@ -57281,6 +57740,9 @@ OUI:70B3D51A3* OUI:70B3D51A5* ID_OUI_FROM_DATABASE=METRONIC APARATURA KONTROLNO - POMIAROWA +OUI:70B3D51A6* + ID_OUI_FROM_DATABASE=Robotelf Technologies (Chengdu) Co., Ltd. + OUI:70B3D51A8* ID_OUI_FROM_DATABASE=STC Rainbow Ltd. @@ -57332,6 +57794,9 @@ OUI:70B3D51C8* OUI:70B3D51CB* ID_OUI_FROM_DATABASE=MatchX GmbH +OUI:70B3D51CD* + ID_OUI_FROM_DATABASE=ELEUSI GmbH + OUI:70B3D51D0* ID_OUI_FROM_DATABASE=Shenzhen INVT Electric Co.,Ltd @@ -57431,6 +57896,9 @@ OUI:70B3D520F* OUI:70B3D5211* ID_OUI_FROM_DATABASE=Fracarro srl +OUI:70B3D5213* + ID_OUI_FROM_DATABASE=ETON Deutschland Electro Acoustic GmbH + OUI:70B3D5214* ID_OUI_FROM_DATABASE=signalparser @@ -57458,6 +57926,9 @@ OUI:70B3D5220* OUI:70B3D5222* ID_OUI_FROM_DATABASE=Marioff Corporation Oy +OUI:70B3D5224* + ID_OUI_FROM_DATABASE=Urbana Smart Solutions Pte Ltd + OUI:70B3D5226* ID_OUI_FROM_DATABASE=Yaviar @@ -57491,9 +57962,15 @@ OUI:70B3D5231* OUI:70B3D5232* ID_OUI_FROM_DATABASE=UCONSYS +OUI:70B3D5236* + ID_OUI_FROM_DATABASE=Monnit Corporation + OUI:70B3D5238* ID_OUI_FROM_DATABASE=Arete Associates +OUI:70B3D523A* + ID_OUI_FROM_DATABASE=Mesa Labs, Inc. + OUI:70B3D523C* ID_OUI_FROM_DATABASE=Quasonix, LLC @@ -57518,6 +57995,9 @@ OUI:70B3D524B* OUI:70B3D524D* ID_OUI_FROM_DATABASE=INFO CREATIVE (HK) LTD +OUI:70B3D524E* + ID_OUI_FROM_DATABASE=Chengdu Cove Technology CO.,LTD + OUI:70B3D524F* ID_OUI_FROM_DATABASE=ELBIT SYSTEMS BMD AND LAND EW - ELISRA LTD @@ -57527,12 +58007,18 @@ OUI:70B3D5250* OUI:70B3D5252* ID_OUI_FROM_DATABASE=Sierra Nevada Corporation +OUI:70B3D5253* + ID_OUI_FROM_DATABASE=Wimate Technology Solutions Private Limited + OUI:70B3D5254* ID_OUI_FROM_DATABASE=Spectrum Brands OUI:70B3D5255* ID_OUI_FROM_DATABASE=Asystems Corporation +OUI:70B3D5257* + ID_OUI_FROM_DATABASE=LG Electronics + OUI:70B3D5259* ID_OUI_FROM_DATABASE=Zebra Elektronik A.S. @@ -57599,6 +58085,9 @@ OUI:70B3D527D* OUI:70B3D527E* ID_OUI_FROM_DATABASE=Mettler Toledo Hi Speed +OUI:70B3D527F* + ID_OUI_FROM_DATABASE=ST Aerospace Systems + OUI:70B3D5283* ID_OUI_FROM_DATABASE=TextNinja Co. @@ -57647,6 +58136,9 @@ OUI:70B3D5297* OUI:70B3D529B* ID_OUI_FROM_DATABASE=DermaLumics S.L. +OUI:70B3D529C* + ID_OUI_FROM_DATABASE=Teko Telecom Srl + OUI:70B3D529D* ID_OUI_FROM_DATABASE=XTech2 SIA @@ -57659,6 +58151,9 @@ OUI:70B3D52A1* OUI:70B3D52A2* ID_OUI_FROM_DATABASE=Visualware, Inc. +OUI:70B3D52A4* + ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH + OUI:70B3D52A5* ID_OUI_FROM_DATABASE=Taitotekniikka @@ -57713,12 +58208,21 @@ OUI:70B3D52BD* OUI:70B3D52BE* ID_OUI_FROM_DATABASE=Coherent Logix, Inc. +OUI:70B3D52BF* + ID_OUI_FROM_DATABASE=FOSHAN VOHOM + OUI:70B3D52C2* ID_OUI_FROM_DATABASE=Quantum Detectors OUI:70B3D52C3* ID_OUI_FROM_DATABASE=Proterra +OUI:70B3D52C9* + ID_OUI_FROM_DATABASE=SEASON DESIGN TECHNOLOGY + +OUI:70B3D52CA* + ID_OUI_FROM_DATABASE=TATTILE SRL + OUI:70B3D52CC* ID_OUI_FROM_DATABASE=WeWork Companies, Inc. @@ -57812,6 +58316,9 @@ OUI:70B3D52FA* OUI:70B3D52FD* ID_OUI_FROM_DATABASE=Special Projects Group, Inc +OUI:70B3D52FE* + ID_OUI_FROM_DATABASE=Yaham Optoelectronics Co., Ltd + OUI:70B3D5300* ID_OUI_FROM_DATABASE=Novo DR Ltd. @@ -58097,6 +58604,9 @@ OUI:70B3D53A9* OUI:70B3D53AA* ID_OUI_FROM_DATABASE=RCATSONE +OUI:70B3D53AD* + ID_OUI_FROM_DATABASE=CT Company + OUI:70B3D53AE* ID_OUI_FROM_DATABASE=Exicom Technologies fze @@ -58115,6 +58625,9 @@ OUI:70B3D53B7* OUI:70B3D53B8* ID_OUI_FROM_DATABASE=nVideon, Inc. +OUI:70B3D53BA* + ID_OUI_FROM_DATABASE=Silex Inside + OUI:70B3D53BB* ID_OUI_FROM_DATABASE=A-M Systems @@ -58313,6 +58826,9 @@ OUI:70B3D5433* OUI:70B3D5435* ID_OUI_FROM_DATABASE=Wuhan Xingtuxinke ELectronic Co.,Ltd +OUI:70B3D5436* + ID_OUI_FROM_DATABASE=Henrich Electronics Corporation + OUI:70B3D5439* ID_OUI_FROM_DATABASE=TriLED @@ -58376,6 +58892,9 @@ OUI:70B3D5462* OUI:70B3D5465* ID_OUI_FROM_DATABASE=ENERGISME +OUI:70B3D5469* + ID_OUI_FROM_DATABASE=Gentec Systems Co. + OUI:70B3D546B* ID_OUI_FROM_DATABASE=Airborne Engineering Limited @@ -58475,6 +58994,9 @@ OUI:70B3D54A1* OUI:70B3D54A5* ID_OUI_FROM_DATABASE=Intermind Inc. +OUI:70B3D54A6* + ID_OUI_FROM_DATABASE=HZHY TECHNOLOGY + OUI:70B3D54A7* ID_OUI_FROM_DATABASE=aelettronica group srl @@ -58490,6 +59012,9 @@ OUI:70B3D54AD* OUI:70B3D54AE* ID_OUI_FROM_DATABASE=Reinhardt System- und Messelectronic GmbH +OUI:70B3D54AF* + ID_OUI_FROM_DATABASE=Agramkow Fluid Systems A/S + OUI:70B3D54B0* ID_OUI_FROM_DATABASE=Tecogen Inc. @@ -58499,6 +59024,9 @@ OUI:70B3D54B1* OUI:70B3D54B2* ID_OUI_FROM_DATABASE=Certus Operations Ltd +OUI:70B3D54B4* + ID_OUI_FROM_DATABASE=Hi Tech Systems Ltd + OUI:70B3D54B6* ID_OUI_FROM_DATABASE=VEILUX INC. @@ -58673,6 +59201,9 @@ OUI:70B3D5524* OUI:70B3D5525* ID_OUI_FROM_DATABASE=Plantiga Technologies Inc +OUI:70B3D5526* + ID_OUI_FROM_DATABASE=FlowNet LLC + OUI:70B3D5528* ID_OUI_FROM_DATABASE=Aplex Technology Inc. @@ -58694,6 +59225,9 @@ OUI:70B3D5530* OUI:70B3D5531* ID_OUI_FROM_DATABASE=ATEME +OUI:70B3D5532* + ID_OUI_FROM_DATABASE=Talleres de Escoriaza SA + OUI:70B3D5538* ID_OUI_FROM_DATABASE=sydetion UG (h.b.) @@ -58718,6 +59252,9 @@ OUI:70B3D5548* OUI:70B3D5549* ID_OUI_FROM_DATABASE=Procon automatic systems GmbH +OUI:70B3D554B* + ID_OUI_FROM_DATABASE=Brakels IT + OUI:70B3D554C* ID_OUI_FROM_DATABASE=Husty M.Styczen J.Hupert Sp.J. @@ -58739,6 +59276,9 @@ OUI:70B3D5551* OUI:70B3D5554* ID_OUI_FROM_DATABASE=Teletypes Manufacturing Plant +OUI:70B3D5555* + ID_OUI_FROM_DATABASE=SoftLab-NSK + OUI:70B3D5557* ID_OUI_FROM_DATABASE=HEITEC AG @@ -58778,6 +59318,9 @@ OUI:70B3D5570* OUI:70B3D5572* ID_OUI_FROM_DATABASE=CRDE +OUI:70B3D5576* + ID_OUI_FROM_DATABASE=Shandong Hospot IOT Technology Co.,Ltd. + OUI:70B3D5578* ID_OUI_FROM_DATABASE=IMAGE TECH CO.,LTD @@ -58946,6 +59489,9 @@ OUI:70B3D55DB* OUI:70B3D55DC* ID_OUI_FROM_DATABASE=FactoryLab B.V. +OUI:70B3D55DE* + ID_OUI_FROM_DATABASE=Hangzhou AwareTec Technology Co., Ltd + OUI:70B3D55E0* ID_OUI_FROM_DATABASE=Hexagon Metrology SAS @@ -58979,6 +59525,9 @@ OUI:70B3D55ED* OUI:70B3D55EE* ID_OUI_FROM_DATABASE=Mikrotron Mikrocomputer, Digital- und Analogtechnik GmbH +OUI:70B3D55EF* + ID_OUI_FROM_DATABASE=Star Systems International + OUI:70B3D55F0* ID_OUI_FROM_DATABASE=managee GmbH & Co KG @@ -59138,9 +59687,15 @@ OUI:70B3D564A* OUI:70B3D564C* ID_OUI_FROM_DATABASE=ACEMIS FRANCE +OUI:70B3D564E* + ID_OUI_FROM_DATABASE=BigStuff3, Inc. + OUI:70B3D5650* ID_OUI_FROM_DATABASE=GIFAS-ELECTRIC GmbH +OUI:70B3D5651* + ID_OUI_FROM_DATABASE=Roxford + OUI:70B3D5652* ID_OUI_FROM_DATABASE=Robert Bosch, LLC @@ -59153,6 +59708,9 @@ OUI:70B3D5654* OUI:70B3D5655* ID_OUI_FROM_DATABASE=AOT System GmbH +OUI:70B3D5656* + ID_OUI_FROM_DATABASE=SonoSound ApS + OUI:70B3D5658* ID_OUI_FROM_DATABASE=emperor brands @@ -59303,6 +59861,9 @@ OUI:70B3D56BE* OUI:70B3D56BF* ID_OUI_FROM_DATABASE=Otto Bihler Maschinenfabrik GmbH & Co. KG +OUI:70B3D56C1* + ID_OUI_FROM_DATABASE=Labtronik s.r.l. + OUI:70B3D56C5* ID_OUI_FROM_DATABASE=CJSC «Russian telecom equipment company» (CJSC RTEC) @@ -59327,6 +59888,9 @@ OUI:70B3D56D3* OUI:70B3D56D6* ID_OUI_FROM_DATABASE=KMtronic Ltd. +OUI:70B3D56D8* + ID_OUI_FROM_DATABASE=Shanghai YuanAn Environmental Protection Technology Co.,Ltd + OUI:70B3D56D9* ID_OUI_FROM_DATABASE=VECTARE Inc @@ -59423,6 +59987,9 @@ OUI:70B3D5708* OUI:70B3D5709* ID_OUI_FROM_DATABASE=AML +OUI:70B3D570A* + ID_OUI_FROM_DATABASE=PULLNET TECHNOLOGY, SA DE CV SSC1012302S73 + OUI:70B3D570F* ID_OUI_FROM_DATABASE=Alion Science & Technology @@ -59468,6 +60035,9 @@ OUI:70B3D5724* OUI:70B3D5727* ID_OUI_FROM_DATABASE=LP Technologies Inc. +OUI:70B3D5728* + ID_OUI_FROM_DATABASE=BCD Audio + OUI:70B3D5729* ID_OUI_FROM_DATABASE=EMAC, Inc. @@ -59501,6 +60071,9 @@ OUI:70B3D5735* OUI:70B3D5737* ID_OUI_FROM_DATABASE=SD Biosensor +OUI:70B3D5739* + ID_OUI_FROM_DATABASE=Zigencorp, Inc + OUI:70B3D573A* ID_OUI_FROM_DATABASE=Private @@ -59531,6 +60104,9 @@ OUI:70B3D5745* OUI:70B3D5747* ID_OUI_FROM_DATABASE=Eva Automation +OUI:70B3D5749* + ID_OUI_FROM_DATABASE=Granite River Labs Inc + OUI:70B3D574A* ID_OUI_FROM_DATABASE=Mettler Toledo Hi Speed @@ -59654,6 +60230,9 @@ OUI:70B3D5785* OUI:70B3D5789* ID_OUI_FROM_DATABASE=SEMEX-EngCon GmbH +OUI:70B3D578A* + ID_OUI_FROM_DATABASE=Hills Health Solutions + OUI:70B3D578B* ID_OUI_FROM_DATABASE=Jingtu Printing Systems Co., Ltd @@ -59699,6 +60278,9 @@ OUI:70B3D57A3* OUI:70B3D57A4* ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC +OUI:70B3D57A5* + ID_OUI_FROM_DATABASE=Triton Electronics Ltd + OUI:70B3D57A6* ID_OUI_FROM_DATABASE=Electrolux @@ -59717,6 +60299,9 @@ OUI:70B3D57AA* OUI:70B3D57AB* ID_OUI_FROM_DATABASE=Microgate Srl +OUI:70B3D57AC* + ID_OUI_FROM_DATABASE=Verity Studios AG + OUI:70B3D57AD* ID_OUI_FROM_DATABASE=Insitu, Inc @@ -59780,6 +60365,9 @@ OUI:70B3D57CE* OUI:70B3D57CF* ID_OUI_FROM_DATABASE=ORCA Technologies, LLC +OUI:70B3D57D0* + ID_OUI_FROM_DATABASE=Cubitech + OUI:70B3D57D1* ID_OUI_FROM_DATABASE=Schneider Electric Motion USA @@ -59789,6 +60377,9 @@ OUI:70B3D57D2* OUI:70B3D57D5* ID_OUI_FROM_DATABASE=SICS Swedish ICT +OUI:70B3D57D7* + ID_OUI_FROM_DATABASE=Gedomo GmbH + OUI:70B3D57D9* ID_OUI_FROM_DATABASE=ATOM GIKEN Co.,Ltd. @@ -59897,6 +60488,9 @@ OUI:70B3D580D* OUI:70B3D580F* ID_OUI_FROM_DATABASE=Quickware Eng & Des LLC +OUI:70B3D5810* + ID_OUI_FROM_DATABASE=Advice + OUI:70B3D5811* ID_OUI_FROM_DATABASE=CJSC «INTERSET» @@ -60080,6 +60674,9 @@ OUI:70B3D5879* OUI:70B3D587B* ID_OUI_FROM_DATABASE=Liquid Instruments Pty Ltd +OUI:70B3D587C* + ID_OUI_FROM_DATABASE=Nautel Limited + OUI:70B3D587E* ID_OUI_FROM_DATABASE=Septentrio NV @@ -60170,6 +60767,12 @@ OUI:70B3D58B2* OUI:70B3D58B3* ID_OUI_FROM_DATABASE=Firefly RFID Solutions +OUI:70B3D58B4* + ID_OUI_FROM_DATABASE=Scenario Automation + +OUI:70B3D58B7* + ID_OUI_FROM_DATABASE=Contec DTx + OUI:70B3D58B9* ID_OUI_FROM_DATABASE=Toptech Systems, Inc. @@ -60212,6 +60815,9 @@ OUI:70B3D58D3* OUI:70B3D58D8* ID_OUI_FROM_DATABASE=VNG Corporation +OUI:70B3D58D9* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + OUI:70B3D58DB* ID_OUI_FROM_DATABASE=Kratos Analytical Ltd @@ -60224,6 +60830,9 @@ OUI:70B3D58E0* OUI:70B3D58E1* ID_OUI_FROM_DATABASE=WoKa-Elektronik GmbH +OUI:70B3D58E3* + ID_OUI_FROM_DATABASE=DORLET SAU + OUI:70B3D58E4* ID_OUI_FROM_DATABASE=Aplex Technology Inc. @@ -60269,6 +60878,9 @@ OUI:70B3D5902* OUI:70B3D5903* ID_OUI_FROM_DATABASE=Cymtec Ltd +OUI:70B3D5904* + ID_OUI_FROM_DATABASE=PHB Eletronica Ltda. + OUI:70B3D5906* ID_OUI_FROM_DATABASE=Aplex Technology Inc. @@ -60287,6 +60899,9 @@ OUI:70B3D590C* OUI:70B3D590D* ID_OUI_FROM_DATABASE=Modtronix Engineering +OUI:70B3D590E* + ID_OUI_FROM_DATABASE=Private + OUI:70B3D590F* ID_OUI_FROM_DATABASE=DTRON Communications (Pty) Ltd @@ -60365,6 +60980,9 @@ OUI:70B3D5938* OUI:70B3D5939* ID_OUI_FROM_DATABASE=Invertek Drives Ltd +OUI:70B3D593E* + ID_OUI_FROM_DATABASE=Systems With Intelligence Inc. + OUI:70B3D5940* ID_OUI_FROM_DATABASE=Paradigm Technology Services B.V. @@ -60491,6 +61109,9 @@ OUI:70B3D598F* OUI:70B3D5991* ID_OUI_FROM_DATABASE=Javasparrow Inc. +OUI:70B3D5993* + ID_OUI_FROM_DATABASE=ioThings + OUI:70B3D5994* ID_OUI_FROM_DATABASE=KeFF Networks @@ -60710,6 +61331,9 @@ OUI:70B3D5A10* OUI:70B3D5A12* ID_OUI_FROM_DATABASE=QUERCUS TECHNOLOGIES, S.L. +OUI:70B3D5A13* + ID_OUI_FROM_DATABASE=Uplevel Systems Inc + OUI:70B3D5A15* ID_OUI_FROM_DATABASE=Intercore GmbH @@ -60917,6 +61541,9 @@ OUI:70B3D5A8B* OUI:70B3D5A8E* ID_OUI_FROM_DATABASE=OMESH CITY GROUP +OUI:70B3D5A90* + ID_OUI_FROM_DATABASE=ERA a.s. + OUI:70B3D5A91* ID_OUI_FROM_DATABASE=IDEAL INDUSTRIES Ltd t/a Casella @@ -60980,6 +61607,9 @@ OUI:70B3D5AAD* OUI:70B3D5AAE* ID_OUI_FROM_DATABASE=Nuviz Oy +OUI:70B3D5AAF* + ID_OUI_FROM_DATABASE=Exi Flow Measurement Ltd + OUI:70B3D5AB0* ID_OUI_FROM_DATABASE=OSR R&D ISRAEL LTD @@ -61046,6 +61676,9 @@ OUI:70B3D5AD5* OUI:70B3D5AD6* ID_OUI_FROM_DATABASE=Lemonade Lab Inc +OUI:70B3D5AD8* + ID_OUI_FROM_DATABASE=Euklis by GSG International + OUI:70B3D5ADA* ID_OUI_FROM_DATABASE=Private @@ -61247,6 +61880,9 @@ OUI:70B3D5B3F* OUI:70B3D5B40* ID_OUI_FROM_DATABASE=Wuhan Xingtuxinke ELectronic Co.,Ltd +OUI:70B3D5B43* + ID_OUI_FROM_DATABASE=ZAO ZEO + OUI:70B3D5B44* ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. @@ -61295,6 +61931,9 @@ OUI:70B3D5B6D* OUI:70B3D5B72* ID_OUI_FROM_DATABASE=UB330.net d.o.o. +OUI:70B3D5B74* + ID_OUI_FROM_DATABASE=OnYield Inc Ltd + OUI:70B3D5B77* ID_OUI_FROM_DATABASE=Motec Pty Ltd @@ -61370,6 +62009,9 @@ OUI:70B3D5BA1* OUI:70B3D5BA2* ID_OUI_FROM_DATABASE=MAMAC Systems, Inc. +OUI:70B3D5BA3* + ID_OUI_FROM_DATABASE=TIAMA + OUI:70B3D5BA4* ID_OUI_FROM_DATABASE=EIWA GIKEN INC. @@ -61535,6 +62177,9 @@ OUI:70B3D5C0E* OUI:70B3D5C0F* ID_OUI_FROM_DATABASE=Honeywell Safety Products USA, Inc +OUI:70B3D5C11* + ID_OUI_FROM_DATABASE=Ariston Thermo s.p.a. + OUI:70B3D5C12* ID_OUI_FROM_DATABASE=Beijing Wisetone Information Technology Co.,Ltd. @@ -61553,6 +62198,9 @@ OUI:70B3D5C17* OUI:70B3D5C1B* ID_OUI_FROM_DATABASE=Labinvent JSC +OUI:70B3D5C1C* + ID_OUI_FROM_DATABASE=D.E.M. SPA + OUI:70B3D5C1D* ID_OUI_FROM_DATABASE=Kranze Technology Solutions @@ -61775,6 +62423,9 @@ OUI:70B3D5C9D* OUI:70B3D5C9F* ID_OUI_FROM_DATABASE=Triax A/S +OUI:70B3D5CA2* + ID_OUI_FROM_DATABASE=De Haardt bv + OUI:70B3D5CA4* ID_OUI_FROM_DATABASE=Netemera Sp. z o.o. @@ -62036,6 +62687,12 @@ OUI:70B3D5D47* OUI:70B3D5D48* ID_OUI_FROM_DATABASE=HEADROOM Broadcast GmbH +OUI:70B3D5D4A* + ID_OUI_FROM_DATABASE=OÜ ELIKO Tehnoloogia Arenduskeskus + +OUI:70B3D5D4B* + ID_OUI_FROM_DATABASE=Hermann Lümmen GmbH + OUI:70B3D5D4C* ID_OUI_FROM_DATABASE=Elystec Technology Co., Ltd @@ -62072,6 +62729,9 @@ OUI:70B3D5D5B* OUI:70B3D5D5C* ID_OUI_FROM_DATABASE=Critical Link LLC +OUI:70B3D5D5F* + ID_OUI_FROM_DATABASE=Core Balance Co., Ltd. + OUI:70B3D5D60* ID_OUI_FROM_DATABASE=Flintab AB @@ -62099,6 +62759,9 @@ OUI:70B3D5D6B* OUI:70B3D5D6C* ID_OUI_FROM_DATABASE=GP Systems GmbH +OUI:70B3D5D6F* + ID_OUI_FROM_DATABASE=X-SPEX GmbH + OUI:70B3D5D70* ID_OUI_FROM_DATABASE=Rational Production srl Unipersonale @@ -62144,6 +62807,9 @@ OUI:70B3D5D86* OUI:70B3D5D87* ID_OUI_FROM_DATABASE=Zigen Corp +OUI:70B3D5D89* + ID_OUI_FROM_DATABASE=Resolution Systems + OUI:70B3D5D8B* ID_OUI_FROM_DATABASE=Lenoxi Automation s.r.o. @@ -62216,6 +62882,9 @@ OUI:70B3D5DAD* OUI:70B3D5DB0* ID_OUI_FROM_DATABASE=Arnouse Digital Devices Corp +OUI:70B3D5DB1* + ID_OUI_FROM_DATABASE=Biovigil Hygiene Technologies + OUI:70B3D5DB2* ID_OUI_FROM_DATABASE=Micro Electroninc Products @@ -62306,6 +62975,9 @@ OUI:70B3D5DEE* OUI:70B3D5DF0* ID_OUI_FROM_DATABASE=astozi consulting Tomasz Zieba +OUI:70B3D5DF1* + ID_OUI_FROM_DATABASE=CoXlab Inc. + OUI:70B3D5DF2* ID_OUI_FROM_DATABASE=AML @@ -62351,6 +63023,9 @@ OUI:70B3D5E08* OUI:70B3D5E09* ID_OUI_FROM_DATABASE=L-3 communications ComCept Division +OUI:70B3D5E0B* + ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. + OUI:70B3D5E0D* ID_OUI_FROM_DATABASE=Sigma Connectivity AB @@ -62702,6 +63377,9 @@ OUI:70B3D5EF2* OUI:70B3D5EF3* ID_OUI_FROM_DATABASE=octoScope +OUI:70B3D5EF5* + ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH + OUI:70B3D5EF6* ID_OUI_FROM_DATABASE=CHARGELIB @@ -62735,6 +63413,9 @@ OUI:70B3D5F03* OUI:70B3D5F05* ID_OUI_FROM_DATABASE=Motomuto Aps +OUI:70B3D5F06* + ID_OUI_FROM_DATABASE=WARECUBE,INC + OUI:70B3D5F07* ID_OUI_FROM_DATABASE=DUVAL MESSIEN @@ -62765,6 +63446,9 @@ OUI:70B3D5F13* OUI:70B3D5F17* ID_OUI_FROM_DATABASE=VITEC +OUI:70B3D5F19* + ID_OUI_FROM_DATABASE=Vitro Technology Corporation + OUI:70B3D5F1A* ID_OUI_FROM_DATABASE=Sator Controls s.r.o. @@ -63017,6 +63701,9 @@ OUI:70B3D5FB5* OUI:70B3D5FB6* ID_OUI_FROM_DATABASE=KRONOTECH SRL +OUI:70B3D5FB7* + ID_OUI_FROM_DATABASE=SAICE + OUI:70B3D5FBA* ID_OUI_FROM_DATABASE=Apogee Applied Research, Inc. @@ -63119,6 +63806,9 @@ OUI:70B3D5FEC* OUI:70B3D5FEF* ID_OUI_FROM_DATABASE=HANGZHOU HUALAN MICROELECTRONIQUE CO.,LTD +OUI:70B3D5FF0* + ID_OUI_FROM_DATABASE=E-MetroTel + OUI:70B3D5FF1* ID_OUI_FROM_DATABASE=Data Strategy Limited @@ -63170,6 +63860,9 @@ OUI:70C6AC* OUI:70C76F* ID_OUI_FROM_DATABASE=INNO S +OUI:70C833* + ID_OUI_FROM_DATABASE=Wirepas Oy + OUI:70C94E* ID_OUI_FROM_DATABASE=Liteon Technology Corporation @@ -63365,6 +64058,9 @@ OUI:740ABC* OUI:740EDB* ID_OUI_FROM_DATABASE=Optowiz Co., Ltd +OUI:7412BB* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + OUI:741489* ID_OUI_FROM_DATABASE=SRT Wireless @@ -63755,6 +64451,9 @@ OUI:749D8F* OUI:749DDC* ID_OUI_FROM_DATABASE=2Wire Inc +OUI:749EAF* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:74A02F* ID_OUI_FROM_DATABASE=Cisco Systems, Inc @@ -64139,6 +64838,9 @@ OUI:7819F7* OUI:781C5A* ID_OUI_FROM_DATABASE=SHARP Corporation +OUI:781D4A* + ID_OUI_FROM_DATABASE=zte corporation + OUI:781DBA* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -64202,6 +64904,9 @@ OUI:78324F* OUI:783690* ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd +OUI:7836CC* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + OUI:783A84* ID_OUI_FROM_DATABASE=Apple, Inc. @@ -64514,6 +65219,9 @@ OUI:78B5D2* OUI:78B6C1* ID_OUI_FROM_DATABASE=AOBO Telecom Co.,Ltd +OUI:78B6EC* + ID_OUI_FROM_DATABASE=Scuf Gaming International LLC + OUI:78B81A* ID_OUI_FROM_DATABASE=INTER SALES A/S @@ -64820,6 +65528,9 @@ OUI:78F882* OUI:78F944* ID_OUI_FROM_DATABASE=Private +OUI:78F9B4* + ID_OUI_FROM_DATABASE=Nokia + OUI:78FC14* ID_OUI_FROM_DATABASE=Family Zone Cyber Safety Ltd @@ -65219,6 +65930,9 @@ OUI:7C7630* OUI:7C7635* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:7C7668* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:7C7673* ID_OUI_FROM_DATABASE=ENMAS GmbH @@ -65285,6 +65999,9 @@ OUI:7C9A9B* OUI:7CA15D* ID_OUI_FROM_DATABASE=GN ReSound A/S +OUI:7CA177* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:7CA237* ID_OUI_FROM_DATABASE=King Slide Technology CO., LTD. @@ -65624,6 +66341,9 @@ OUI:800184* OUI:8002DF* ID_OUI_FROM_DATABASE=ORA Inc. +OUI:800588* + ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD + OUI:8005DF* ID_OUI_FROM_DATABASE=Montage Technology Group Limited @@ -65744,6 +66464,9 @@ OUI:8030DC* OUI:803457* ID_OUI_FROM_DATABASE=OT Systems Limited +OUI:8035C1* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + OUI:803773* ID_OUI_FROM_DATABASE=NETGEAR @@ -66098,6 +66821,9 @@ OUI:80C6CA* OUI:80C755* ID_OUI_FROM_DATABASE=Panasonic Appliances Company +OUI:80C7C5* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + OUI:80C862* ID_OUI_FROM_DATABASE=Openpeak, Inc @@ -66254,6 +66980,9 @@ OUI:8404D2* OUI:840B2D* ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. +OUI:840D8E* + ID_OUI_FROM_DATABASE=Espressif Inc. + OUI:840F45* ID_OUI_FROM_DATABASE=Shanghai GMT Digital Technologies Co., Ltd @@ -66488,6 +67217,9 @@ OUI:8463D6* OUI:84683E* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:846878* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:846AED* ID_OUI_FROM_DATABASE=Wireless Tsukamoto.,co.LTD @@ -66845,6 +67577,9 @@ OUI:84EF18* OUI:84F129* ID_OUI_FROM_DATABASE=Metrascale Inc. +OUI:84F3EB* + ID_OUI_FROM_DATABASE=Espressif Inc. + OUI:84F493* ID_OUI_FROM_DATABASE=OMS spol. s.r.o. @@ -66890,6 +67625,9 @@ OUI:880FB6* OUI:881036* ID_OUI_FROM_DATABASE=Panodic(ShenZhen) Electronics Limted +OUI:881196* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:88124E* ID_OUI_FROM_DATABASE=Qualcomm Inc. @@ -66905,6 +67643,9 @@ OUI:8817A3* OUI:8818AE* ID_OUI_FROM_DATABASE=Tamron Co., Ltd +OUI:881908* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:881B99* ID_OUI_FROM_DATABASE=SHENZHEN XIN FEI JIA ELECTRONIC CO. LTD. @@ -66977,6 +67718,9 @@ OUI:883C1C* OUI:883D24* ID_OUI_FROM_DATABASE=Google, Inc. +OUI:883F4A* + ID_OUI_FROM_DATABASE=Texas Instruments + OUI:883FD3* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -67091,8 +67835,50 @@ OUI:885D90F* OUI:885DFB* ID_OUI_FROM_DATABASE=zte corporation -OUI:885FE8* - ID_OUI_FROM_DATABASE=IEEE Registration Authority +OUI:885FE80* + ID_OUI_FROM_DATABASE=Jungheinrich Norderstedt AG & Co. KG + +OUI:885FE81* + ID_OUI_FROM_DATABASE=Apoidea Technology Co., Ltd. + +OUI:885FE82* + ID_OUI_FROM_DATABASE=Opto Engineering + +OUI:885FE83* + ID_OUI_FROM_DATABASE=Sonnet Labs Inc. + +OUI:885FE84* + ID_OUI_FROM_DATABASE=Beijing laiwei Technology Co.,Ltd + +OUI:885FE85* + ID_OUI_FROM_DATABASE=Hauch & Bach ApS + +OUI:885FE86* + ID_OUI_FROM_DATABASE=Shenzhen Xin Kingbrand Enterprises Co.,Ltd + +OUI:885FE87* + ID_OUI_FROM_DATABASE=Red Technologies, LLC. + +OUI:885FE88* + ID_OUI_FROM_DATABASE=Changsha Xiangji-Haidun Technology Co., Ltd + +OUI:885FE89* + ID_OUI_FROM_DATABASE=Sowee + +OUI:885FE8A* + ID_OUI_FROM_DATABASE=Lisle Design Ltd + +OUI:885FE8B* + ID_OUI_FROM_DATABASE=Shenzhen ORVIBO Technology Co., Ltd + +OUI:885FE8C* + ID_OUI_FROM_DATABASE=Inor Process AB + +OUI:885FE8D* + ID_OUI_FROM_DATABASE=zhejiang yuanwang communication technolgy co.,ltd + +OUI:885FE8E* + ID_OUI_FROM_DATABASE=Unicom Global, Inc. OUI:88615A* ID_OUI_FROM_DATABASE=Siano Mobile Silicon Ltd. @@ -67226,6 +68012,9 @@ OUI:8894F9* OUI:8895B9* ID_OUI_FROM_DATABASE=Unified Packet Systems Crop +OUI:88964E* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + OUI:889676* ID_OUI_FROM_DATABASE=TTC MARCONI s.r.o. @@ -67325,6 +68114,9 @@ OUI:88AD43* OUI:88ADD2* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:88AE07* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:88AE1D* ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. @@ -67415,6 +68207,9 @@ OUI:88D37B* OUI:88D50C* ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD +OUI:88D652* + ID_OUI_FROM_DATABASE=AMERGINT Technologies + OUI:88D7BC* ID_OUI_FROM_DATABASE=DEP Company @@ -67433,6 +68228,9 @@ OUI:88DC96* OUI:88DD79* ID_OUI_FROM_DATABASE=Voltaire +OUI:88DE7C* + ID_OUI_FROM_DATABASE=Askey Computer Corp. + OUI:88DEA9* ID_OUI_FROM_DATABASE=Roku, Inc. @@ -67472,6 +68270,9 @@ OUI:88E90F* OUI:88E917* ID_OUI_FROM_DATABASE=Tamaggo +OUI:88E9FE* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:88ED1C* ID_OUI_FROM_DATABASE=Cudo Communication Co., Ltd. @@ -68276,6 +69077,9 @@ OUI:903CAE* OUI:903D5A* ID_OUI_FROM_DATABASE=Shenzhen Wision Technology Holding Limited +OUI:903D68* + ID_OUI_FROM_DATABASE=G-Printec, Inc. + OUI:903D6B* ID_OUI_FROM_DATABASE=Zicon Technology Corp. @@ -68720,6 +69524,9 @@ OUI:90DA6A* OUI:90DB46* ID_OUI_FROM_DATABASE=E-LEAD ELECTRONIC CO., LTD +OUI:90DD5D* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:90DFB7* ID_OUI_FROM_DATABASE=s.m.s smart microwave sensors GmbH @@ -69023,6 +69830,9 @@ OUI:9486D4* OUI:94877C* ID_OUI_FROM_DATABASE=ARRIS Group, Inc. +OUI:9487E0* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + OUI:948815* ID_OUI_FROM_DATABASE=Infinique Worldwide Inc @@ -69065,6 +69875,9 @@ OUI:9498A2* OUI:949901* ID_OUI_FROM_DATABASE=Shenzhen YITOA Digital Appliance CO.,LTD +OUI:949990* + ID_OUI_FROM_DATABASE=VTC Telecommunications + OUI:949AA9* ID_OUI_FROM_DATABASE=Microsoft Corporation @@ -69074,6 +69887,9 @@ OUI:949BFD* OUI:949C55* ID_OUI_FROM_DATABASE=Alta Data Technologies +OUI:949D57* + ID_OUI_FROM_DATABASE=Panasonic do Brasil Limitada + OUI:949F3E* ID_OUI_FROM_DATABASE=Sonos, Inc. @@ -69143,6 +69959,9 @@ OUI:94BBAE* OUI:94BF1E* ID_OUI_FROM_DATABASE=eflow Inc. / Smart Device Planning and Development Division +OUI:94BF2D* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:94BF95* ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd @@ -69248,6 +70067,9 @@ OUI:94DF58* OUI:94E0D0* ID_OUI_FROM_DATABASE=HealthStream Taiwan Inc. +OUI:94E1AC* + ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. + OUI:94E226* ID_OUI_FROM_DATABASE=D. ORtiz Consulting, LLC @@ -69422,6 +70244,9 @@ OUI:9810E8* OUI:981333* ID_OUI_FROM_DATABASE=zte corporation +OUI:9814D2* + ID_OUI_FROM_DATABASE=Avonic + OUI:9816EC* ID_OUI_FROM_DATABASE=IC Intracom @@ -70016,6 +70841,12 @@ OUI:9C2A70* OUI:9C2A83* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:9C2EA1* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +OUI:9C2F73* + ID_OUI_FROM_DATABASE=Universal Tiancheng Technology (Beijing) Co., Ltd. + OUI:9C305B* ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. @@ -70241,6 +71072,9 @@ OUI:9C7BD2* OUI:9C7DA3* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +OUI:9C7F57* + ID_OUI_FROM_DATABASE=DERA Co. Ltd + OUI:9C807D* ID_OUI_FROM_DATABASE=SYSCABLE Korea Inc. @@ -70334,6 +71168,9 @@ OUI:9CA577* OUI:9CA5C0* ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. +OUI:9CA615* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + OUI:9CA69D* ID_OUI_FROM_DATABASE=Whaley Technology Co.Ltd @@ -70478,12 +71315,21 @@ OUI:9CE374* OUI:9CE635* ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. +OUI:9CE65E* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:9CE6E7* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd OUI:9CE7BD* ID_OUI_FROM_DATABASE=Winduskorea co., Ltd +OUI:9CE82B* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + +OUI:9CE895* + ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd + OUI:9CE951* ID_OUI_FROM_DATABASE=Shenzhen Sang Fei Consumer Communications Ltd., Co. @@ -70523,6 +71369,9 @@ OUI:9CFC01* OUI:9CFCD1* ID_OUI_FROM_DATABASE=Aetheris Technology (Shanghai) Co., Ltd. +OUI:9CFEA1* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + OUI:9CFFBE* ID_OUI_FROM_DATABASE=OTSL Inc. @@ -70769,6 +71618,9 @@ OUI:A055DE* OUI:A056B2* ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH +OUI:A056F3* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:A057E3* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -70850,6 +71702,9 @@ OUI:A073FC* OUI:A07591* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:A075EA* + ID_OUI_FROM_DATABASE=BoxLock, Inc. + OUI:A07771* ID_OUI_FROM_DATABASE=Vialis BV @@ -70982,6 +71837,9 @@ OUI:A0ADA1* OUI:A0AFBD* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:A0B045* + ID_OUI_FROM_DATABASE=Halong Mining + OUI:A0B100* ID_OUI_FROM_DATABASE=ShenZhen Cando Electronics Co.,Ltd @@ -71201,6 +72059,9 @@ OUI:A0E534* OUI:A0E5E9* ID_OUI_FROM_DATABASE=enimai Inc +OUI:A0E617* + ID_OUI_FROM_DATABASE=MATIS + OUI:A0E6F8* ID_OUI_FROM_DATABASE=Texas Instruments @@ -71759,6 +72620,9 @@ OUI:A49005* OUI:A491B1* ID_OUI_FROM_DATABASE=Technicolor +OUI:A4933F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:A4934C* ID_OUI_FROM_DATABASE=Cisco Systems, Inc @@ -72485,6 +73349,9 @@ OUI:A8F274* OUI:A8F470* ID_OUI_FROM_DATABASE=Fujian Newland Communication Science Technologies Co.,Ltd. +OUI:A8F5AC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:A8F7E0* ID_OUI_FROM_DATABASE=PLANET Technology Corporation @@ -72668,6 +73535,9 @@ OUI:AC319D* OUI:AC34CB* ID_OUI_FROM_DATABASE=Shanhai GBCOM Communication Technology Co. Ltd +OUI:AC35EE* + ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED + OUI:AC3613* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -73316,6 +74186,9 @@ OUI:B04089* OUI:B0411D* ID_OUI_FROM_DATABASE=ITTIM Technologies +OUI:B0416F* + ID_OUI_FROM_DATABASE=Shenzhen Maxtang Computer Co.,Ltd + OUI:B0435D* ID_OUI_FROM_DATABASE=NuLEDs, Inc. @@ -73460,6 +74333,9 @@ OUI:B0808C* OUI:B081D8* ID_OUI_FROM_DATABASE=I-sys Corp +OUI:B083D6* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + OUI:B083FE* ID_OUI_FROM_DATABASE=Dell Inc. @@ -73533,7 +74409,7 @@ OUI:B0A2E7* ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. OUI:B0A37E* - ID_OUI_FROM_DATABASE=Qingdao Haier Telecom Co.,Ltd + ID_OUI_FROM_DATABASE=QING DAO HAIER TELECOM CO.,LTD. OUI:B0A72A* ID_OUI_FROM_DATABASE=Ensemble Designs, Inc. @@ -74204,6 +75080,9 @@ OUI:B4B88D* OUI:B4BFF6* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:B4C0F5* + ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. + OUI:B4C170* ID_OUI_FROM_DATABASE=Yi chip Microelectronics (Hangzhou) Co., Ltd @@ -74222,6 +75101,9 @@ OUI:B4C810* OUI:B4CCE9* ID_OUI_FROM_DATABASE=PROSYST +OUI:B4CD27* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:B4CEF6* ID_OUI_FROM_DATABASE=HTC Corporation @@ -74258,6 +75140,9 @@ OUI:B4DF3B* OUI:B4DFFA* ID_OUI_FROM_DATABASE=Litemax Electronics Inc. +OUI:B4E01D* + ID_OUI_FROM_DATABASE=CONCEPTION ELECTRONIQUE + OUI:B4E0CD* ID_OUI_FROM_DATABASE=Fusion-io, Inc @@ -74465,6 +75350,9 @@ OUI:B83E59* OUI:B8415F* ID_OUI_FROM_DATABASE=ASP AG +OUI:B841A4* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:B843E4* ID_OUI_FROM_DATABASE=Vlatacom @@ -74996,6 +75884,9 @@ OUI:BC25F0* OUI:BC261D* ID_OUI_FROM_DATABASE=HONG KONG TECON TECHNOLOGY +OUI:BC2643* + ID_OUI_FROM_DATABASE=Elprotronic Inc. + OUI:BC282C* ID_OUI_FROM_DATABASE=e-Smart Systems Pvt. Ltd @@ -75032,6 +75923,9 @@ OUI:BC307D* OUI:BC307E* ID_OUI_FROM_DATABASE=Wistron Neweb Corporation +OUI:BC325F* + ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. + OUI:BC34000* ID_OUI_FROM_DATABASE=Redvision CCTV @@ -75494,6 +76388,9 @@ OUI:BCDDC2* OUI:BCE09D* ID_OUI_FROM_DATABASE=Eoslink +OUI:BCE143* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:BCE59F* ID_OUI_FROM_DATABASE=WATERWORLD Technology Co.,LTD @@ -75872,6 +76769,9 @@ OUI:C0B339* OUI:C0B357* ID_OUI_FROM_DATABASE=Yoshiki Electronics Industry Ltd. +OUI:C0B658* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:C0B713* ID_OUI_FROM_DATABASE=Beijing Xiaoyuer Technology Co. Ltd. @@ -76010,6 +76910,9 @@ OUI:C0EAE4* OUI:C0EE40* ID_OUI_FROM_DATABASE=Laird Technologies +OUI:C0EEB5* + ID_OUI_FROM_DATABASE=Enice Network. + OUI:C0EEFB* ID_OUI_FROM_DATABASE=OnePlus Tech (Shenzhen) Ltd @@ -76451,6 +77354,9 @@ OUI:C495A2* OUI:C49805* ID_OUI_FROM_DATABASE=Minieum Networks, Inc +OUI:C49880* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:C49A02* ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) @@ -76922,6 +77828,9 @@ OUI:C88447* OUI:C88550* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:C88629* + ID_OUI_FROM_DATABASE=Shenzhen Duubee Intelligent Technologies Co.,LTD. + OUI:C88722* ID_OUI_FROM_DATABASE=Lumenpulse @@ -77114,6 +78023,9 @@ OUI:C8CD72* OUI:C8D019* ID_OUI_FROM_DATABASE=Shanghai Tigercel Communication Technology Co.,Ltd +OUI:C8D083* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:C8D10B* ID_OUI_FROM_DATABASE=Nokia Corporation @@ -77148,7 +78060,7 @@ OUI:C8D719* ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC OUI:C8D779* - ID_OUI_FROM_DATABASE=Qingdao Haier Telecom Co.,Ltd + ID_OUI_FROM_DATABASE=QING DAO HAIER TELECOM CO.,LTD. OUI:C8D7B0* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd @@ -77672,6 +78584,9 @@ OUI:CC90E8* OUI:CC912B* ID_OUI_FROM_DATABASE=TE Connectivity Touch Solutions +OUI:CC934A* + ID_OUI_FROM_DATABASE=Sierra Wireless + OUI:CC944A* ID_OUI_FROM_DATABASE=Pfeiffer Vacuum GmbH @@ -77771,9 +78686,15 @@ OUI:CCBE59* OUI:CCBE71* ID_OUI_FROM_DATABASE=OptiLogix BV +OUI:CCC079* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + OUI:CCC104* ID_OUI_FROM_DATABASE=Applied Technical Systems +OUI:CCC2E0* + ID_OUI_FROM_DATABASE=Raisecom Technology CO., LTD + OUI:CCC3EA* ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company @@ -78290,6 +79211,9 @@ OUI:D07650E* OUI:D07650F* ID_OUI_FROM_DATABASE=Private +OUI:D076E7* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + OUI:D07714* ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company @@ -78809,6 +79733,9 @@ OUI:D46132* OUI:D4619D* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:D461DA* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:D461FE* ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited @@ -78872,6 +79799,9 @@ OUI:D46F42* OUI:D47208* ID_OUI_FROM_DATABASE=Bragi GmbH +OUI:D47226* + ID_OUI_FROM_DATABASE=zte corporation + OUI:D476EA* ID_OUI_FROM_DATABASE=zte corporation @@ -79211,6 +80141,9 @@ OUI:D816C1* OUI:D8182B* ID_OUI_FROM_DATABASE=Conti Temic Microelectronic GmbH +OUI:D818D3* + ID_OUI_FROM_DATABASE=Juniper Networks + OUI:D8197A* ID_OUI_FROM_DATABASE=Nuheara Ltd @@ -79286,6 +80219,9 @@ OUI:D83214* OUI:D8325A* ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd +OUI:D832E3* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + OUI:D8337F* ID_OUI_FROM_DATABASE=Office FA.com Co.,Ltd. @@ -79823,6 +80759,9 @@ OUI:DC2008* OUI:DC2834* ID_OUI_FROM_DATABASE=HAKKO Corporation +OUI:DC2919* + ID_OUI_FROM_DATABASE=AltoBeam (Xiamen) Technology Ltd, Co. + OUI:DC293A* ID_OUI_FROM_DATABASE=Shenzhen Nuoshi Technology Co., LTD. @@ -79857,7 +80796,7 @@ OUI:DC309C* ID_OUI_FROM_DATABASE=Heyrex Limited OUI:DC330D* - ID_OUI_FROM_DATABASE=Qingdao Haier Telecom Co.,Ltd + ID_OUI_FROM_DATABASE=QING DAO HAIER TELECOM CO.,LTD. OUI:DC3350* ID_OUI_FROM_DATABASE=TechSAT GmbH @@ -80195,6 +81134,9 @@ OUI:DCD2FC* OUI:DCD321* ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. +OUI:DCD3A2* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:DCD52A* ID_OUI_FROM_DATABASE=Sunny Heart Limited @@ -80219,6 +81161,9 @@ OUI:DCDC07* OUI:DCDD24* ID_OUI_FROM_DATABASE=Energica Motor Company SpA +OUI:DCDE4F* + ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co Ltd + OUI:DCDECA* ID_OUI_FROM_DATABASE=Akyllor @@ -80366,6 +81311,9 @@ OUI:E01877* OUI:E0191D* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +OUI:E019D8* + ID_OUI_FROM_DATABASE=BH TECHNOLOGIES + OUI:E01AEA* ID_OUI_FROM_DATABASE=Allied Telesis, Inc. @@ -80432,6 +81380,9 @@ OUI:E0319E* OUI:E031D0* ID_OUI_FROM_DATABASE=SZ Telstar CO., LTD +OUI:E0338E* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:E034E4* ID_OUI_FROM_DATABASE=Feit Electric Company, Inc. @@ -80447,6 +81398,9 @@ OUI:E036E3* OUI:E037BF* ID_OUI_FROM_DATABASE=Wistron Neweb Corporation +OUI:E0383F* + ID_OUI_FROM_DATABASE=zte corporation + OUI:E039D7* ID_OUI_FROM_DATABASE=Plexxi, Inc. @@ -80570,6 +81524,9 @@ OUI:E07C13* OUI:E07C62* ID_OUI_FROM_DATABASE=Whistle Labs, Inc. +OUI:E07DEA* + ID_OUI_FROM_DATABASE=Texas Instruments + OUI:E07F53* ID_OUI_FROM_DATABASE=TECHBOARD SRL @@ -80918,6 +81875,9 @@ OUI:E4029B* OUI:E40439* ID_OUI_FROM_DATABASE=TomTom Software Ltd +OUI:E40EEE* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:E4115B* ID_OUI_FROM_DATABASE=Hewlett Packard @@ -81026,6 +81986,9 @@ OUI:E441E6* OUI:E442A6* ID_OUI_FROM_DATABASE=Intel Corporate +OUI:E4434B* + ID_OUI_FROM_DATABASE=Dell Inc. + OUI:E446BD* ID_OUI_FROM_DATABASE=C&C TECHNIC TAIWAN CO., LTD. @@ -81044,6 +82007,9 @@ OUI:E44C6C* OUI:E44E18* ID_OUI_FROM_DATABASE=Gardasoft VisionLimited +OUI:E44E76* + ID_OUI_FROM_DATABASE=CHAMPIONTECH ENTERPRISE (SHENZHEN) INC + OUI:E44F29* ID_OUI_FROM_DATABASE=MA Lighting Technology GmbH @@ -81083,6 +82049,9 @@ OUI:E45D52* OUI:E45D75* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:E46059* + ID_OUI_FROM_DATABASE=Pingtek Co., Ltd. + OUI:E46251* ID_OUI_FROM_DATABASE=HAO CHENG GROUP LIMITED @@ -81152,6 +82121,9 @@ OUI:E48184* OUI:E481B3* ID_OUI_FROM_DATABASE=Shenzhen ACT Industrial Co.,Ltd. +OUI:E482CC* + ID_OUI_FROM_DATABASE=Jumptronic GmbH + OUI:E48399* ID_OUI_FROM_DATABASE=ARRIS Group, Inc. @@ -81173,6 +82145,9 @@ OUI:E48D8C* OUI:E48F34* ID_OUI_FROM_DATABASE=Vodafone Italia S.p.A. +OUI:E48F65* + ID_OUI_FROM_DATABASE=Yelatma Instrument Making Enterprise, JSC + OUI:E49069* ID_OUI_FROM_DATABASE=Rockwell Automation @@ -81377,6 +82352,9 @@ OUI:E4E0A6* OUI:E4E0C5* ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +OUI:E4E130* + ID_OUI_FROM_DATABASE=TCT mobile ltd + OUI:E4E409* ID_OUI_FROM_DATABASE=LEIFHEIT AG @@ -81804,7 +82782,7 @@ OUI:E89A8F* ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. OUI:E89AFF* - ID_OUI_FROM_DATABASE=Fujian Landi Commercial Equipment Co.,Ltd + ID_OUI_FROM_DATABASE=Fujian LANDI Commercial Equipment Co.,Ltd OUI:E89D87* ID_OUI_FROM_DATABASE=Toshiba @@ -82001,6 +82979,9 @@ OUI:E8F724* OUI:E8F928* ID_OUI_FROM_DATABASE=RFTECH SRL +OUI:E8FAF7* + ID_OUI_FROM_DATABASE=Guangdong Uniteddata Holding Group Co., Ltd. + OUI:E8FC60* ID_OUI_FROM_DATABASE=ELCOM Innovations Private Limited @@ -82307,6 +83288,9 @@ OUI:EC9233* OUI:EC9327* ID_OUI_FROM_DATABASE=MEMMERT GmbH + Co. KG +OUI:EC9365* + ID_OUI_FROM_DATABASE=Mapper.ai, Inc. + OUI:EC93ED* ID_OUI_FROM_DATABASE=DDoS-Guard LTD @@ -82394,6 +83378,9 @@ OUI:ECAAA0* OUI:ECADB8* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:ECAF97* + ID_OUI_FROM_DATABASE=GIT + OUI:ECB0E1* ID_OUI_FROM_DATABASE=Ciena Corporation @@ -82574,6 +83561,9 @@ OUI:F008F1* OUI:F00D5C* ID_OUI_FROM_DATABASE=JinQianMao Technology Co.,Ltd. +OUI:F00E1D* + ID_OUI_FROM_DATABASE=Megafone Limited + OUI:F00FEC* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD @@ -82589,6 +83579,9 @@ OUI:F015B9* OUI:F0182B* ID_OUI_FROM_DATABASE=LG Chem +OUI:F01898* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:F01B6C* ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. @@ -82742,12 +83735,18 @@ OUI:F0407B* OUI:F041C80* ID_OUI_FROM_DATABASE=LINPA ACOUSTIC TECHNOLOGY CO.,LTD +OUI:F041C81* + ID_OUI_FROM_DATABASE=DongGuan Siyoto Electronics Co., Ltd + OUI:F041C82* ID_OUI_FROM_DATABASE=Shenzhen Medica Technology Development Co., Ltd. OUI:F041C83* ID_OUI_FROM_DATABASE=SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD +OUI:F041C84* + ID_OUI_FROM_DATABASE=Candelic Limited + OUI:F041C85* ID_OUI_FROM_DATABASE=XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd. @@ -82757,9 +83756,15 @@ OUI:F041C86* OUI:F041C87* ID_OUI_FROM_DATABASE=Nanchang BlackShark Co.,Ltd. +OUI:F041C88* + ID_OUI_FROM_DATABASE=POSTIUM KOREA CO., LTD. + OUI:F041C89* ID_OUI_FROM_DATABASE=Shenzhen Nufilo Electronic Technology Co., Ltd. +OUI:F041C8A* + ID_OUI_FROM_DATABASE=Telstra + OUI:F041C8B* ID_OUI_FROM_DATABASE=Powervault Ltd @@ -82769,6 +83774,9 @@ OUI:F041C8C* OUI:F041C8D* ID_OUI_FROM_DATABASE=ATN Media Group FZ LLC +OUI:F041C8E* + ID_OUI_FROM_DATABASE=Shenzhen Umind Technology Co., Ltd. + OUI:F0421C* ID_OUI_FROM_DATABASE=Intel Corporate @@ -82790,6 +83798,9 @@ OUI:F04B6A* OUI:F04BF2* ID_OUI_FROM_DATABASE=JTECH Communications, Inc. +OUI:F04CD5* + ID_OUI_FROM_DATABASE=Maxlinear, Inc + OUI:F04DA2* ID_OUI_FROM_DATABASE=Dell Inc. @@ -82946,6 +83957,9 @@ OUI:F09838* OUI:F0989D* ID_OUI_FROM_DATABASE=Apple, Inc. +OUI:F099B6* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:F099BF* ID_OUI_FROM_DATABASE=Apple, Inc. @@ -82955,6 +83969,9 @@ OUI:F09A51* OUI:F09CBB* ID_OUI_FROM_DATABASE=RaonThink Inc. +OUI:F09CD7* + ID_OUI_FROM_DATABASE=Guangzhou Blue Cheetah Intelligent Technology Co., Ltd. + OUI:F09CE9* ID_OUI_FROM_DATABASE=Aerohive Networks Inc. @@ -83027,6 +84044,9 @@ OUI:F0AD4E* OUI:F0AE51* ID_OUI_FROM_DATABASE=Xi3 Corp +OUI:F0AF50* + ID_OUI_FROM_DATABASE=Phantom Intelligence + OUI:F0B052* ID_OUI_FROM_DATABASE=Ruckus Wireless @@ -83045,6 +84065,9 @@ OUI:F0B479* OUI:F0B5B7* ID_OUI_FROM_DATABASE=Disruptive Technologies Research AS +OUI:F0B5D1* + ID_OUI_FROM_DATABASE=Texas Instruments + OUI:F0B6EB* ID_OUI_FROM_DATABASE=Poslab Technology Co., Ltd. @@ -83657,6 +84680,9 @@ OUI:F4B85E* OUI:F4B8A7* ID_OUI_FROM_DATABASE=zte corporation +OUI:F4BC97* + ID_OUI_FROM_DATABASE=Shenzhen Crave Communication Co., LTD + OUI:F4BD7C* ID_OUI_FROM_DATABASE=Chengdu jinshi communication Co., LTD @@ -84155,6 +85181,9 @@ OUI:F86ECF* OUI:F86EEE* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +OUI:F86FC1* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:F871FE* ID_OUI_FROM_DATABASE=The Goldman Sachs Group, Inc. @@ -84281,6 +85310,9 @@ OUI:F89550* OUI:F895C7* ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) +OUI:F895EA* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:F897CF* ID_OUI_FROM_DATABASE=DAESHIN-INFORMATION TECHNOLOGY CO., LTD. @@ -84290,6 +85322,9 @@ OUI:F8983A* OUI:F898B9* ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +OUI:F898EF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + OUI:F89955* ID_OUI_FROM_DATABASE=Fortress Technology Inc @@ -84500,6 +85535,9 @@ OUI:F8DFA8* OUI:F8E079* ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company +OUI:F8E44E* + ID_OUI_FROM_DATABASE=MCOT INC. + OUI:F8E4FB* ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc @@ -84548,6 +85586,9 @@ OUI:F8F25A* OUI:F8F464* ID_OUI_FROM_DATABASE=Rawe Electonic GmbH +OUI:F8F532* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + OUI:F8F7D3* ID_OUI_FROM_DATABASE=International Communications Corporation @@ -84674,6 +85715,9 @@ OUI:FC27A2* OUI:FC2A54* ID_OUI_FROM_DATABASE=Connected Data, Inc. +OUI:FC2A9C* + ID_OUI_FROM_DATABASE=Apple, Inc. + OUI:FC2D5E* ID_OUI_FROM_DATABASE=zte corporation @@ -84812,6 +85856,9 @@ OUI:FC65DE* OUI:FC683E* ID_OUI_FROM_DATABASE=Directed Perception, Inc +OUI:FC6947* + ID_OUI_FROM_DATABASE=Texas Instruments + OUI:FC6C31* ID_OUI_FROM_DATABASE=LXinstruments GmbH @@ -84860,6 +85907,9 @@ OUI:FC8F90* OUI:FC8FC4* ID_OUI_FROM_DATABASE=Intelligent Technology Inc. +OUI:FC90FA* + ID_OUI_FROM_DATABASE=Independent Technologies + OUI:FC9114* ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. @@ -84878,6 +85928,9 @@ OUI:FC9947* OUI:FC9AFA* ID_OUI_FROM_DATABASE=Motus Global Inc. +OUI:FC9BC6* + ID_OUI_FROM_DATABASE=Sumavision Technologies Co.,Ltd + OUI:FC9DD8* ID_OUI_FROM_DATABASE=Beijing TongTongYiLian Science and Technology Ltd. @@ -84938,6 +85991,9 @@ OUI:FCB58A* OUI:FCB698* ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. +OUI:FCB7F0* + ID_OUI_FROM_DATABASE=Idaho National Laboratory + OUI:FCBBA1* ID_OUI_FROM_DATABASE=Shenzhen Minicreate Technology Co.,Ltd @@ -85025,6 +86081,9 @@ OUI:FCE33C* OUI:FCE557* ID_OUI_FROM_DATABASE=Nokia Corporation +OUI:FCE66A* + ID_OUI_FROM_DATABASE=Industrial Software Co + OUI:FCE892* ID_OUI_FROM_DATABASE=Hangzhou Lancable Technology Co.,Ltd diff --git a/hwdb/20-acpi-vendor.hwdb.patch b/hwdb/20-acpi-vendor.hwdb.patch index 0d9be60539..e91e9eca1b 100644 --- a/hwdb/20-acpi-vendor.hwdb.patch +++ b/hwdb/20-acpi-vendor.hwdb.patch @@ -1,5 +1,5 @@ ---- 20-acpi-vendor.hwdb.base 2017-12-14 15:57:48.154005635 +0100 -+++ 20-acpi-vendor.hwdb 2017-12-14 15:57:48.160005689 +0100 +--- 20-acpi-vendor.hwdb.base 2018-01-25 13:07:40.178983802 +0100 ++++ 20-acpi-vendor.hwdb 2018-01-25 13:07:40.183983802 +0100 @@ -3,6 +3,8 @@ # Data imported from: # http://www.uefi.org/uefi-pnp-export diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb index e6ed2e377c..3d8ddf1f34 100644 --- a/hwdb/20-pci-vendor-model.hwdb +++ b/hwdb/20-pci-vendor-model.hwdb @@ -53,6 +53,9 @@ pci:v00000100* pci:v00000123* ID_VENDOR_FROM_DATABASE=General Dynamics +pci:v00000128* + ID_VENDOR_FROM_DATABASE=Dell (wrong ID) + pci:v0000018A* ID_VENDOR_FROM_DATABASE=LevelOne @@ -1664,6 +1667,9 @@ pci:v00001000d00000097* pci:v00001000d00000097sv00001000sd00003090* ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (SAS9311-8i) +pci:v00001000d00000097sv00001000sd000030A0* + ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (SAS9300-8e) + pci:v00001000d00000097sv00001000sd000030E0* ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (SAS9300-8i) @@ -2157,7 +2163,10 @@ pci:v00001002d0000131D* ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6 Graphics] pci:v00001002d000015DD* - ID_MODEL_FROM_DATABASE=Radeon Vega 8 Mobile + ID_MODEL_FROM_DATABASE=Vega [Radeon Vega 8 Mobile] + +pci:v00001002d000015FF* + ID_MODEL_FROM_DATABASE=Vega [Radeon Vega 28 Mobile] pci:v00001002d00001714* ID_MODEL_FROM_DATABASE=BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series] @@ -6683,6 +6692,9 @@ pci:v00001002d000067BE* pci:v00001002d000067C0* ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100] +pci:v00001002d000067C2* + ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro V7300X / V7350x2] + pci:v00001002d000067C4* ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100] @@ -6704,6 +6716,9 @@ pci:v00001002d000067CC* pci:v00001002d000067CF* ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10] +pci:v00001002d000067D0* + ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro V7300X / V7350x2] + pci:v00001002d000067DF* ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] @@ -6762,7 +6777,7 @@ pci:v00001002d000067DFsv00001DA2sd0000E353* ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Sapphire Radeon RX 580 Pulse 8GB) pci:v00001002d000067DFsv00001DA2sd0000E366* - ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 570) + ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Nitro+ Radeon RX 580 4GB) pci:v00001002d000067E0* ID_MODEL_FROM_DATABASE=Baffin [Polaris11] @@ -6780,7 +6795,7 @@ pci:v00001002d000067E9* ID_MODEL_FROM_DATABASE=Baffin [Polaris11] pci:v00001002d000067EB* - ID_MODEL_FROM_DATABASE=Baffin [Polaris11] + ID_MODEL_FROM_DATABASE=Baffin [Radeon Pro V5300X] pci:v00001002d000067EF* ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/560] @@ -6911,6 +6926,9 @@ pci:v00001002d00006818sv0000174Bsd00008B04* pci:v00001002d00006819* ID_MODEL_FROM_DATABASE=Pitcairn PRO [Radeon HD 7850 / R7 265 / R9 270 1024SP] +pci:v00001002d00006819sv00001043sd0000042C* + ID_MODEL_FROM_DATABASE=Pitcairn PRO [Radeon HD 7850 / R7 265 / R9 270 1024SP] (Radeon HD 7850) + pci:v00001002d00006819sv00001682sd00007269* ID_MODEL_FROM_DATABASE=Pitcairn PRO [Radeon HD 7850 / R7 265 / R9 270 1024SP] (Radeon R9 270 1024SP) @@ -7397,12 +7415,30 @@ pci:v00001002d00006842* pci:v00001002d00006843* ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7670M] +pci:v00001002d00006860* + ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Instinct MI25] + pci:v00001002d00006861* ID_MODEL_FROM_DATABASE=Vega 10 XT [Radeon PRO WX 9100] +pci:v00001002d00006862* + ID_MODEL_FROM_DATABASE=Vega 10 XT [Radeon PRO SSG] + pci:v00001002d00006863* ID_MODEL_FROM_DATABASE=Vega 10 XTX [Radeon Vega Frontier Edition] +pci:v00001002d00006864* + ID_MODEL_FROM_DATABASE=Vega + +pci:v00001002d00006867* + ID_MODEL_FROM_DATABASE=Vega + +pci:v00001002d00006868* + ID_MODEL_FROM_DATABASE=Vega + +pci:v00001002d0000686C* + ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Instinct MI25 MxGPU] + pci:v00001002d0000687F* ID_MODEL_FROM_DATABASE=Vega 10 XT [Radeon RX Vega 64] @@ -8918,6 +8954,9 @@ pci:v00001002d00006939sv0000148Csd00009380* pci:v00001002d00006939sv0000174Bsd0000E308* ID_MODEL_FROM_DATABASE=Tonga PRO [Radeon R9 285/380] (Radeon R9 380 Nitro 4G D5) +pci:v00001002d0000694C* + ID_MODEL_FROM_DATABASE=Vega [Radeon RX Vega M] + pci:v00001002d00006980* ID_MODEL_FROM_DATABASE=Polaris12 @@ -8931,7 +8970,7 @@ pci:v00001002d00006986* ID_MODEL_FROM_DATABASE=Polaris12 pci:v00001002d00006987* - ID_MODEL_FROM_DATABASE=Polaris12 + ID_MODEL_FROM_DATABASE=Lexa [Radeon E9171 MCM] pci:v00001002d00006995* ID_MODEL_FROM_DATABASE=Lexa XT [Radeon PRO WX 2100] @@ -11957,6 +11996,21 @@ pci:v00001022d00001424* pci:v00001022d00001426* ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Root Port +pci:v00001022d0000142E* + ID_MODEL_FROM_DATABASE=Liverpool Processor Function 0 + +pci:v00001022d0000142F* + ID_MODEL_FROM_DATABASE=Liverpool Processor Function 1 + +pci:v00001022d00001430* + ID_MODEL_FROM_DATABASE=Liverpool Processor Function 2 + +pci:v00001022d00001431* + ID_MODEL_FROM_DATABASE=Liverpool Processor Function 3 + +pci:v00001022d00001432* + ID_MODEL_FROM_DATABASE=Liverpool Processor Function 4 + pci:v00001022d00001436* ID_MODEL_FROM_DATABASE=Liverpool Processor Root Complex @@ -16119,22 +16173,25 @@ pci:v0000104Cd0000802Esv00001028sd0000018D* ID_MODEL_FROM_DATABASE=PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller (Inspiron 700m/710m) pci:v0000104Cd00008031* - ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11/PCIx515 PC Card Controller pci:v0000104Cd00008031sv00001025sd00000064* - ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller (Extensa 3000 series laptop) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11/PCIx515 PC Card Controller (Extensa 3000 series laptop) pci:v0000104Cd00008031sv00001025sd00000080* - ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller (Aspire 5024WLMi) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11/PCIx515 PC Card Controller (Aspire 5024WLMi) pci:v0000104Cd00008031sv0000103Csd00000934* - ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller (Compaq nw8240/nx8220) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11/PCIx515 PC Card Controller (Compaq nw8240/nx8220) + +pci:v0000104Cd00008031sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11/PCIx515 PC Card Controller (Compaq nc6220 Notebook PC) pci:v0000104Cd00008031sv0000103Csd0000099C* - ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller (NX6110/NC6120) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11/PCIx515 PC Card Controller (NX6110/NC6120) pci:v0000104Cd00008031sv0000103Csd0000308B* - ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller (MX6125) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11/PCIx515 PC Card Controller (MX6125) pci:v0000104Cd00008032* ID_MODEL_FROM_DATABASE=OHCI Compliant IEEE 1394 Host Controller @@ -16155,46 +16212,55 @@ pci:v0000104Cd00008032sv0000103Csd0000308B* ID_MODEL_FROM_DATABASE=OHCI Compliant IEEE 1394 Host Controller (MX6125) pci:v0000104Cd00008033* - ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Flash Media Controller pci:v0000104Cd00008033sv00001025sd00000064* - ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller (Extensa 3000 series laptop) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Flash Media Controller (Extensa 3000 series laptop) pci:v0000104Cd00008033sv00001025sd00000080* - ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller (Aspire 5024WLMi) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Flash Media Controller (Aspire 5024WLMi) pci:v0000104Cd00008033sv0000103Csd00000934* - ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller (Compaq nw8240/nx8220) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Flash Media Controller (Compaq nw8240/nx8220) + +pci:v0000104Cd00008033sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Flash Media Controller (Compaq nc6220 Notebook PC) pci:v0000104Cd00008033sv0000103Csd0000099C* - ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller (NX6110/NC6120) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Flash Media Controller (NX6110/NC6120) pci:v0000104Cd00008033sv0000103Csd0000308B* - ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller (MX6125) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Flash Media Controller (MX6125) pci:v0000104Cd00008034* - ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 SD Host Controller pci:v0000104Cd00008034sv00001025sd00000080* - ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller (Aspire 5024WLMi) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 SD Host Controller (Aspire 5024WLMi) pci:v0000104Cd00008034sv0000103Csd00000934* - ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller (Compaq nw8240/nx8220) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 SD Host Controller (Compaq nw8240/nx8220) + +pci:v0000104Cd00008034sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 SD Host Controller (Compaq nc6220 Notebook PC) pci:v0000104Cd00008034sv0000103Csd0000099C* - ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller (NX6110/NC6120) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 SD Host Controller (NX6110/NC6120) pci:v0000104Cd00008034sv0000103Csd0000308B* - ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller (MX6125) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 SD Host Controller (MX6125) pci:v0000104Cd00008035* - ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Smart Card Controller + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Smart Card Controller pci:v0000104Cd00008035sv0000103Csd00000934* - ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Smart Card Controller (Compaq nw8240/nx8220) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Smart Card Controller (Compaq nw8240/nx8220) + +pci:v0000104Cd00008035sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Smart Card Controller (Compaq nc6220 Notebook PC) pci:v0000104Cd00008035sv0000103Csd0000099C* - ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Smart Card Controller (NX6110/NC6120) + ID_MODEL_FROM_DATABASE=PCIxx21/PCIxx11 Smart Card Controller (NX6110/NC6120) pci:v0000104Cd00008036* ID_MODEL_FROM_DATABASE=PCI6515 Cardbus Controller @@ -16233,19 +16299,19 @@ pci:v0000104Cd0000803Asv0000104Dsd0000902D* ID_MODEL_FROM_DATABASE=PCIxx12 OHCI Compliant IEEE 1394 Host Controller (VAIO VGN-NR120E) pci:v0000104Cd0000803B* - ID_MODEL_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) + ID_MODEL_FROM_DATABASE=PCIxx12 Flash Media Controller pci:v0000104Cd0000803Bsv0000103Csd0000309F* - ID_MODEL_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) (nx9420) + ID_MODEL_FROM_DATABASE=PCIxx12 Flash Media Controller (nx9420) pci:v0000104Cd0000803Bsv0000103Csd000030A3* - ID_MODEL_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) (Compaq nw8440) + ID_MODEL_FROM_DATABASE=PCIxx12 Flash Media Controller (Compaq nw8440) pci:v0000104Cd0000803Bsv0000104Dsd00008212* - ID_MODEL_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) (VAIO VGN-N21E) + ID_MODEL_FROM_DATABASE=PCIxx12 Flash Media Controller (VAIO VGN-N21E) pci:v0000104Cd0000803Bsv0000104Dsd0000902D* - ID_MODEL_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) (VAIO VGN-NR120E) + ID_MODEL_FROM_DATABASE=PCIxx12 Flash Media Controller (VAIO VGN-NR120E) pci:v0000104Cd0000803C* ID_MODEL_FROM_DATABASE=PCIxx12 SDA Standard Compliant SD Host Controller @@ -16742,6 +16808,54 @@ pci:v0000104Dd000090A4* pci:v0000104Dd000090BC* ID_MODEL_FROM_DATABASE=SxS Pro+ memory card +pci:v0000104Dd000090C8* + ID_MODEL_FROM_DATABASE=Belize ACPI + +pci:v0000104Dd000090C9* + ID_MODEL_FROM_DATABASE=Belize Ethernet Controller + +pci:v0000104Dd000090CA* + ID_MODEL_FROM_DATABASE=Belize SATA AHCI Controller + +pci:v0000104Dd000090CB* + ID_MODEL_FROM_DATABASE=Belize SD/MMC Host Controller + +pci:v0000104Dd000090CC* + ID_MODEL_FROM_DATABASE=Belize PCI Express Glue and Miscellaneous Devices + +pci:v0000104Dd000090CD* + ID_MODEL_FROM_DATABASE=Belize DMA Controller + +pci:v0000104Dd000090CE* + ID_MODEL_FROM_DATABASE=Belize Memory (DDR3/SPM) + +pci:v0000104Dd000090CF* + ID_MODEL_FROM_DATABASE=Belize USB 3.0 xHCI Host Controller + +pci:v0000104Dd000090D7* + ID_MODEL_FROM_DATABASE=Baikal ACPI + +pci:v0000104Dd000090D8* + ID_MODEL_FROM_DATABASE=Baikal Ethernet Controller + +pci:v0000104Dd000090D9* + ID_MODEL_FROM_DATABASE=Baikal SATA AHCI Controller + +pci:v0000104Dd000090DA* + ID_MODEL_FROM_DATABASE=Baikal SD/MMC Host Controller + +pci:v0000104Dd000090DB* + ID_MODEL_FROM_DATABASE=Baikal PCI Express Glue and Miscellaneous Devices + +pci:v0000104Dd000090DC* + ID_MODEL_FROM_DATABASE=Baikal DMA Controller + +pci:v0000104Dd000090DD* + ID_MODEL_FROM_DATABASE=Baikal Memory (DDR3/SPM) + +pci:v0000104Dd000090DE* + ID_MODEL_FROM_DATABASE=Baikal USB 3.0 xHCI Host Controller + pci:v0000104E* ID_VENDOR_FROM_DATABASE=Oak Technology, Inc @@ -18476,6 +18590,18 @@ pci:v00001077d00008070sv00001077sd00000001* pci:v00001077d00008070sv00001077sd00000002* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GE 2P QL41112HxCU-DE Adapter) +pci:v00001077d00008070sv00001077sd00000005* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (QLogic 4x10GE QL41164HMRJ CNA) + +pci:v00001077d00008070sv00001077sd00000006* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (QLogic 4x10GE QL41164HMCU CNA) + +pci:v00001077d00008070sv00001077sd00000007* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (QLogic 2x1GE+2x10GE QL41264HMCU CNA) + +pci:v00001077d00008070sv00001077sd00000009* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (QLogic 2x1GE+2x10GE QL41162HMRJ CNA) + pci:v00001077d00008070sv00001077sd0000000B* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (25GE 2P QL41262HxCU-DE Adapter) @@ -18506,9 +18632,24 @@ pci:v00001077d00008080sv00001077sd00000001* pci:v00001077d00008080sv00001077sd00000002* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (10GE 2P QL41112HxCU-DE Adapter) +pci:v00001077d00008080sv00001077sd00000005* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (QLogic 4x10GE QL41164HMRJ CNA) + +pci:v00001077d00008080sv00001077sd00000006* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (QLogic 4x10GE QL41164HMCU CNA) + +pci:v00001077d00008080sv00001077sd00000007* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (QLogic 2x1GE+2x10GE QL41264HMCU CNA) + +pci:v00001077d00008080sv00001077sd00000009* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (QLogic 2x1GE+2x10GE QL41162HMRJ CNA) + pci:v00001077d00008080sv00001077sd0000000B* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (25GE 2P QL41262HxCU-DE Adapter) +pci:v00001077d00008080sv00001077sd0000000C* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (QLogic 2x25GE QL41262HMCU CNA) + pci:v00001077d00008080sv00001077sd0000000D* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (FastLinQ QL41262H 25GbE FCoE Adapter) @@ -18524,9 +18665,24 @@ pci:v00001077d00008084sv00001077sd00000001* pci:v00001077d00008084sv00001077sd00000002* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (10GE 2P QL41112HxCU-DE Adapter) +pci:v00001077d00008084sv00001077sd00000005* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (QLogic 4x10GE QL41164HMRJ CNA) + +pci:v00001077d00008084sv00001077sd00000006* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (QLogic 4x10GE QL41164HMCU CNA) + +pci:v00001077d00008084sv00001077sd00000007* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (QLogic 2x25GE QL41262HMCU CNA) + +pci:v00001077d00008084sv00001077sd00000009* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (QLogic 2x1GE+2x10GE QL41162HMRJ CNA) + pci:v00001077d00008084sv00001077sd0000000B* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (25GE 2P QL41262HxCU-DE Adapter) +pci:v00001077d00008084sv00001077sd0000000C* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (QLogic 2x25GE QL41262HMCU CNA) + pci:v00001077d00008084sv00001077sd0000000D* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (FastLinQ QL41262H 25GbE iSCSI Adapter) @@ -18542,9 +18698,24 @@ pci:v00001077d00008090sv00001077sd00000001* pci:v00001077d00008090sv00001077sd00000002* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10GE 2P QL41112HxCU-DE Adapter) +pci:v00001077d00008090sv00001077sd00000005* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 4x10GE QL41164HMRJ CNA) + +pci:v00001077d00008090sv00001077sd00000006* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 4x10GE QL41164HMCU CNA) + +pci:v00001077d00008090sv00001077sd00000007* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 2x1GE+2x10GE QL41264HMCU CNA) + +pci:v00001077d00008090sv00001077sd00000009* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 2x1GE+2x10GE QL41162HMRJ CNA) + pci:v00001077d00008090sv00001077sd0000000B* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (25GE 2P QL41262HxCU-DE Adapter) +pci:v00001077d00008090sv00001077sd0000000C* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 2x25GE QL41262HMCU CNA) + pci:v00001077d00008090sv00001077sd0000000D* ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41262H 25GbE FCoE Adapter (SR-IOV VF)) @@ -32154,7 +32325,7 @@ pci:v000010DEd000013DA* ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980 Mobile] pci:v000010DEd000013E7* - ID_MODEL_FROM_DATABASE=GM204 [GeForce GTX 980 Engineering Sample] + ID_MODEL_FROM_DATABASE=GM204GL [GeForce GTX 980 Engineering Sample] pci:v000010DEd000013F0* ID_MODEL_FROM_DATABASE=GM204GL [Quadro M5000] @@ -32168,6 +32339,9 @@ pci:v000010DEd000013F2* pci:v000010DEd000013F3* ID_MODEL_FROM_DATABASE=GM204GL [Tesla M6] +pci:v000010DEd000013F3sv000010DEsd00001184* + ID_MODEL_FROM_DATABASE=GM204GL [Tesla M6] (GRID M6-8Q) + pci:v000010DEd000013F8* ID_MODEL_FROM_DATABASE=GM204GLM [Quadro M5000M / M5000 SE] @@ -32357,6 +32531,9 @@ pci:v000010DEd00001BB7sv00001462sd000011E9* pci:v000010DEd00001BB8* ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P3000 Mobile] +pci:v000010DEd00001BC7* + ID_MODEL_FROM_DATABASE=GP104 [P104-101] + pci:v000010DEd00001BE0* ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1080 Mobile] @@ -32381,6 +32558,12 @@ pci:v000010DEd00001C02* pci:v000010DEd00001C03* ID_MODEL_FROM_DATABASE=GP106 [GeForce GTX 1060 6GB] +pci:v000010DEd00001C04* + ID_MODEL_FROM_DATABASE=GP106 [GeForce GTX 1060 5GB] + +pci:v000010DEd00001C06* + ID_MODEL_FROM_DATABASE=GP106 [GeForce GTX 1060 6GB Rev. 2] + pci:v000010DEd00001C07* ID_MODEL_FROM_DATABASE=GP106 [P106-100] @@ -32462,8 +32645,11 @@ pci:v000010DEd00001D01* pci:v000010DEd00001D10* ID_MODEL_FROM_DATABASE=GP108M [GeForce MX150] +pci:v000010DEd00001D33* + ID_MODEL_FROM_DATABASE=GP108GL [Quadro P500] + pci:v000010DEd00001D81* - ID_MODEL_FROM_DATABASE=GV100 + ID_MODEL_FROM_DATABASE=GV100 [TITAN V] pci:v000010DEd00001DB1* ID_MODEL_FROM_DATABASE=GV100 [Tesla V100 SXM2] @@ -32546,6 +32732,9 @@ pci:v000010DFd0000E200* pci:v000010DFd0000E200sv00001014sd000003F1* ID_MODEL_FROM_DATABASE=LightPulse LPe16002 (PCIe2 16 Gb 2-port Fibre Channel Adapter (FC EL5B; CCIN 577F)) +pci:v000010DFd0000E200sv000010DFsd0000E282* + ID_MODEL_FROM_DATABASE=LightPulse LPe16002 (Flex System FC5054 4-port 16Gb FC Adapter) + pci:v000010DFd0000E208* ID_MODEL_FROM_DATABASE=LightPulse 16Gb Fibre Channel Host Adapter (Lancer-VF) @@ -33063,25 +33252,28 @@ pci:v000010ECd00008129sv000011ECsd00008129* ID_MODEL_FROM_DATABASE=RTL-8129 (RTL8111/8168 PCIe Gigabit Ethernet (misconfigured)) pci:v000010ECd00008136* - ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller + ID_MODEL_FROM_DATABASE=RTL810xE PCI Express Fast Ethernet controller pci:v000010ECd00008136sv0000103Csd00001985* - ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (RTL8106E on Pavilion 17-e163sg Notebook PC) + ID_MODEL_FROM_DATABASE=RTL810xE PCI Express Fast Ethernet controller (RTL8106E on Pavilion 17-e163sg Notebook PC) pci:v000010ECd00008136sv0000103Csd00002A8C* - ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (Compaq 500B Microtower) + ID_MODEL_FROM_DATABASE=RTL810xE PCI Express Fast Ethernet controller (Compaq 500B Microtower) pci:v000010ECd00008136sv0000103Csd00002AB1* - ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (Pavilion p6774) + ID_MODEL_FROM_DATABASE=RTL810xE PCI Express Fast Ethernet controller (Pavilion p6774) pci:v000010ECd00008136sv0000103Csd000030CC* - ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (Pavilion dv6700) + ID_MODEL_FROM_DATABASE=RTL810xE PCI Express Fast Ethernet controller (Pavilion dv6700) pci:v000010ECd00008136sv00001179sd0000FF64* - ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (RTL8102E PCI-E Fast Ethernet NIC) + ID_MODEL_FROM_DATABASE=RTL810xE PCI Express Fast Ethernet controller (RTL8102E PCI-E Fast Ethernet NIC) pci:v000010ECd00008136sv000017C0sd00001053* - ID_MODEL_FROM_DATABASE=RTL8101/2/6E PCI Express Fast Ethernet controller (RTL8101e Medion WIM 2210 Notebook PC [MD96850]) + ID_MODEL_FROM_DATABASE=RTL810xE PCI Express Fast Ethernet controller (RTL8101e Medion WIM 2210 Notebook PC [MD96850]) + +pci:v000010ECd00008137* + ID_MODEL_FROM_DATABASE=RTL8104E PCIe Fast Ethernet Controller pci:v000010ECd00008138* ID_MODEL_FROM_DATABASE=RT8139 (B/C) Cardbus Fast Ethernet Adapter @@ -41738,47 +41930,131 @@ pci:v000011FEd00000044* pci:v000011FEd00000045* ID_MODEL_FROM_DATABASE=RocketPort Infinity Octa, 8port, DB +pci:v000011FEd00000046* + ID_MODEL_FROM_DATABASE=RocketPort INFINITY 4-port w/external I/F + pci:v000011FEd00000047* ID_MODEL_FROM_DATABASE=RocketPort Infinity 4port, RJ45 +pci:v000011FEd00000048* + ID_MODEL_FROM_DATABASE=RocketPort INFINITY 4J (4-port) w/RJ45 connectors + +pci:v000011FEd0000004A* + ID_MODEL_FROM_DATABASE=RocketPort INFINITY Plus 4-port + +pci:v000011FEd0000004B* + ID_MODEL_FROM_DATABASE=RocketPort INFINITY Plus 8-port + +pci:v000011FEd0000004C* + ID_MODEL_FROM_DATABASE=RocketModem INFINITY III 8-port + +pci:v000011FEd0000004D* + ID_MODEL_FROM_DATABASE=RocketModem INFINITY III 4-port + +pci:v000011FEd0000004E* + ID_MODEL_FROM_DATABASE=RocketPort INFINITY Plus 2-port + pci:v000011FEd0000004F* ID_MODEL_FROM_DATABASE=RocketPort Infinity 2port, SMPTE +pci:v000011FEd00000050* + ID_MODEL_FROM_DATABASE=RocketPort INFINITY Plus 4-port RJ45 + +pci:v000011FEd00000051* + ID_MODEL_FROM_DATABASE=RocketPort INFINITY Plus 8-port RJ11 + pci:v000011FEd00000052* ID_MODEL_FROM_DATABASE=RocketPort Infinity Octa, 8port, SMPTE +pci:v000011FEd00000060* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS 8-port w/Octa Cable + +pci:v000011FEd00000061* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS 32-port w/external I/F + +pci:v000011FEd00000062* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS 8-Port w/external I/F + +pci:v000011FEd00000063* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS 16-port w/external I/F + +pci:v000011FEd00000064* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS 4-port w/Quad Cable + +pci:v000011FEd00000065* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS 8-port w/Octa Cable + +pci:v000011FEd00000066* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS 4-port w/external I/F + +pci:v000011FEd00000067* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS 4J (4-port) w/RJ45 connectors + +pci:v000011FEd00000068* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS 8J (8-port) w/RJ11 connectors + +pci:v000011FEd0000006F* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS SMPTE 2-port + +pci:v000011FEd00000072* + ID_MODEL_FROM_DATABASE=RocketPort EXPRESS SMPTE 8-port w/external I/F + pci:v000011FEd00000801* - ID_MODEL_FROM_DATABASE=RocketPort UPCI 32 port w/external I/F + ID_MODEL_FROM_DATABASE=RocketPort uPCI 32-port w/external I/F pci:v000011FEd00000802* - ID_MODEL_FROM_DATABASE=RocketPort UPCI 8 port w/external I/F + ID_MODEL_FROM_DATABASE=RocketPort uPCI 8-port w/external I/F pci:v000011FEd00000803* - ID_MODEL_FROM_DATABASE=RocketPort UPCI 16 port w/external I/F + ID_MODEL_FROM_DATABASE=RocketPort uPCI 16-port w/external I/F pci:v000011FEd00000805* - ID_MODEL_FROM_DATABASE=RocketPort UPCI 8 port w/octa cable + ID_MODEL_FROM_DATABASE=RocketPort uPCI 8-port w/Octa Cable + +pci:v000011FEd0000080B* + ID_MODEL_FROM_DATABASE=RocketPort Plus uPCI 8-port w/Octa Cable pci:v000011FEd0000080C* - ID_MODEL_FROM_DATABASE=RocketModem III 8 port + ID_MODEL_FROM_DATABASE=RocketModem III 8-port pci:v000011FEd0000080D* - ID_MODEL_FROM_DATABASE=RocketModem III 4 port + ID_MODEL_FROM_DATABASE=RcoketModem III 4-port + +pci:v000011FEd0000080E* + ID_MODEL_FROM_DATABASE=RocketPort uPCI 2-port RS232 w/DB9 connectors + +pci:v000011FEd0000080F* + ID_MODEL_FROM_DATABASE=RocketPort uPCI SMPTE 2-port pci:v000011FEd00000810* - ID_MODEL_FROM_DATABASE=RocketPort UPCI Plus 4 port RS232 + ID_MODEL_FROM_DATABASE=RocketPort Plus uPCI 4J (4-port) w/RJ45 connectors pci:v000011FEd00000811* - ID_MODEL_FROM_DATABASE=RocketPort UPCI Plus 8 port RS232 + ID_MODEL_FROM_DATABASE=RocketPort Plus uPCI 8J (8-port) w/RJ11 connectors pci:v000011FEd00000812* - ID_MODEL_FROM_DATABASE=RocketPort UPCI Plus 8 port RS422 + ID_MODEL_FROM_DATABASE=RocketPort Plus uPCI 422 8-port + +pci:v000011FEd00000813* + ID_MODEL_FROM_DATABASE=RocketModem IV uPCI 8-port + +pci:v000011FEd00000814* + ID_MODEL_FROM_DATABASE=RocketModem IV uPCI 4-port pci:v000011FEd00000903* ID_MODEL_FROM_DATABASE=RocketPort Compact PCI 16 port w/external I/F pci:v000011FEd00008015* - ID_MODEL_FROM_DATABASE=RocketPort 4-port UART 16954 + ID_MODEL_FROM_DATABASE=RocketPort 550 4-port + +pci:v000011FEd00008805* + ID_MODEL_FROM_DATABASE=RocketPort uPCI 4-port w/Quad Cable + +pci:v000011FEd0000880B* + ID_MODEL_FROM_DATABASE=RocketPort Plus uPCI 4-port w/Quad Cable + +pci:v000011FEd00008812* + ID_MODEL_FROM_DATABASE=RocketPort Plus uPCI 4-port RS422 w/Quad Cable pci:v000011FF* ID_VENDOR_FROM_DATABASE=Scion Corporation @@ -46415,6 +46691,9 @@ pci:v000013A8d00000254* pci:v000013A8d00000258* ID_MODEL_FROM_DATABASE=XR17V258 Octal UART PCI controller +pci:v000013A8d00000352* + ID_MODEL_FROM_DATABASE=XR17V3521 Dual PCIe UART + pci:v000013A9* ID_VENDOR_FROM_DATABASE=Siemens Medical Systems, Ultrasound Group @@ -48368,6 +48647,9 @@ pci:v00001425d000050AA* pci:v00001425d000050AB* ID_MODEL_FROM_DATABASE=T520-50AB Unified Wire Ethernet Controller +pci:v00001425d000050AC* + ID_MODEL_FROM_DATABASE=T540-50AC Unified Wire Ethernet Controller + pci:v00001425d00005401* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller @@ -48554,6 +48836,9 @@ pci:v00001425d000054AA* pci:v00001425d000054AB* ID_MODEL_FROM_DATABASE=T520-50AB Unified Wire Ethernet Controller +pci:v00001425d000054AC* + ID_MODEL_FROM_DATABASE=T540-50AC Unified Wire Ethernet Controller + pci:v00001425d00005501* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller @@ -48734,6 +49019,15 @@ pci:v00001425d000055A8* pci:v00001425d000055A9* ID_MODEL_FROM_DATABASE=T580-50A9 Unified Wire Storage Controller +pci:v00001425d000055AA* + ID_MODEL_FROM_DATABASE=T580-50AA Unified Wire Storage Controller + +pci:v00001425d000055AB* + ID_MODEL_FROM_DATABASE=T520-50AB Unified Wire Storage Controller + +pci:v00001425d000055AC* + ID_MODEL_FROM_DATABASE=T540-50AC Unified Wire Storage Controller + pci:v00001425d00005601* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller @@ -48920,6 +49214,9 @@ pci:v00001425d000056AA* pci:v00001425d000056AB* ID_MODEL_FROM_DATABASE=T520-50AB Unified Wire Storage Controller +pci:v00001425d000056AC* + ID_MODEL_FROM_DATABASE=T540-50AC Unified Wire Storage Controller + pci:v00001425d00005701* ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller @@ -49223,6 +49520,9 @@ pci:v00001425d000058AA* pci:v00001425d000058AB* ID_MODEL_FROM_DATABASE=T520-50AB Unified Wire Ethernet Controller [VF] +pci:v00001425d000058AC* + ID_MODEL_FROM_DATABASE=T540-50AC Unified Wire Ethernet Controller [VF] + pci:v00001425d00006001* ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller @@ -49283,6 +49583,9 @@ pci:v00001425d00006085* pci:v00001425d00006086* ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Ethernet Controller +pci:v00001425d00006087* + ID_MODEL_FROM_DATABASE=T6225-6087 Unified Wire Ethernet Controller + pci:v00001425d00006401* ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller @@ -49343,6 +49646,9 @@ pci:v00001425d00006485* pci:v00001425d00006486* ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Ethernet Controller +pci:v00001425d00006487* + ID_MODEL_FROM_DATABASE=T6225-6087 Unified Wire Ethernet Controller + pci:v00001425d00006501* ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller @@ -49403,6 +49709,9 @@ pci:v00001425d00006585* pci:v00001425d00006586* ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Storage Controller +pci:v00001425d00006587* + ID_MODEL_FROM_DATABASE=T6225-6087 Unified Wire Storage Controller + pci:v00001425d00006601* ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller @@ -49463,6 +49772,9 @@ pci:v00001425d00006685* pci:v00001425d00006686* ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Storage Controller +pci:v00001425d00006687* + ID_MODEL_FROM_DATABASE=T6225-6087 Unified Wire Storage Controller + pci:v00001425d00006801* ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller [VF] @@ -49523,6 +49835,9 @@ pci:v00001425d00006885* pci:v00001425d00006886* ID_MODEL_FROM_DATABASE=T6225-6086 Unified Wire Ethernet Controller [VF] +pci:v00001425d00006887* + ID_MODEL_FROM_DATABASE=T6225-6087 Unified Wire Ethernet Controller [VF] + pci:v00001425d0000A000* ID_MODEL_FROM_DATABASE=PE10K Unified Wire Ethernet Controller @@ -51023,6 +51338,9 @@ pci:v000014E4d00001657sv0000103Csd000022BE* pci:v000014E4d00001657sv0000103Csd00003383* ID_MODEL_FROM_DATABASE=NetXtreme BCM5719 Gigabit Ethernet PCIe (Ethernet 1Gb 4-port 331T Adapter) +pci:v000014E4d00001657sv000014E4sd00001904* + ID_MODEL_FROM_DATABASE=NetXtreme BCM5719 Gigabit Ethernet PCIe (4-port 1Gb Ethernet Adapter) + pci:v000014E4d00001659* ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express @@ -51233,6 +51551,9 @@ pci:v000014E4d0000167Dsv0000103Csd00000934* pci:v000014E4d0000167Dsv0000103Csd00000940* ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (Compaq nw8240 Mobile Workstation) +pci:v000014E4d0000167Dsv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (Compaq nc6220 Notebook PC) + pci:v000014E4d0000167Dsv000017AAsd00002081* ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (ThinkPad R60e) @@ -54152,6 +54473,12 @@ pci:v00001556d00001100* pci:v00001556d0000110F* ID_MODEL_FROM_DATABASE=PCI Express Core Reference Design Virtual Function +pci:v00001556d00001110* + ID_MODEL_FROM_DATABASE=XpressRich Reference Design + +pci:v00001556d00001113* + ID_MODEL_FROM_DATABASE=XpressSwitch + pci:v00001557* ID_VENDOR_FROM_DATABASE=MEDIASTAR Co Ltd @@ -54614,6 +54941,9 @@ pci:v000015B3d0000020D* pci:v000015B3d0000020F* ID_MODEL_FROM_DATABASE=MT28908A0 Family [ConnectX-6 Flash Recovery] +pci:v000015B3d00000210* + ID_MODEL_FROM_DATABASE=MT28908A0 Family [ConnectX-6 Secure Flash Recovery] + pci:v000015B3d00000211* ID_MODEL_FROM_DATABASE=MT416842 Family [BlueField SoC Flash Recovery] @@ -54629,6 +54959,9 @@ pci:v000015B3d00000262* pci:v000015B3d00000263* ID_MODEL_FROM_DATABASE=MT27710 [ConnectX-4 Lx Programmable Virtual Function] EN +pci:v000015B3d00000264* + ID_MODEL_FROM_DATABASE=Innova-2 Flex Burn image + pci:v000015B3d00000281* ID_MODEL_FROM_DATABASE=NPS-600 Flash Recovery @@ -54638,6 +54971,9 @@ pci:v000015B3d00001002* pci:v000015B3d00001003* ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] +pci:v000015B3d00001003sv00001014sd000004B5* + ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (PCIe3 40GbE RoCE Converged Host Bus Adapter for Power) + pci:v000015B3d00001003sv0000103Csd00001777* ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (InfiniBand FDR/EN 10/40Gb Dual Port 544FLR-QSFP Adapter (Rev Cx)) @@ -54767,6 +55103,9 @@ pci:v000015B3d00001012* pci:v000015B3d00001013* ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] +pci:v000015B3d00001013sv00001014sd000004F7* + ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (PCIe3 2-port 100 GbE (NIC and RoCE) QSFP28 Adapter for Power) + pci:v000015B3d00001013sv000015B3sd00000003* ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (Mellanox Technologies ConnectX-4 Stand-up single-port 40GbE MCX413A-BCAT) @@ -54794,6 +55133,9 @@ pci:v000015B3d00001014* pci:v000015B3d00001015* ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] +pci:v000015B3d00001015sv000015B3sd00000004* + ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (ConnectX-4 Lx Stand-up dual-port 10GbE MCX4121A-XCAT) + pci:v000015B3d00001015sv000015B3sd00000005* ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (Mellanox Technologies ConnectX-4 Lx Stand-up single-port 40GbE MCX4131A-BCAT) @@ -54899,6 +55241,9 @@ pci:v000015B3d00006732* pci:v000015B3d0000673C* ID_MODEL_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE] +pci:v000015B3d0000673Csv00001014sd00000415* + ID_MODEL_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE] (PCIe2 2-port 4X InfiniBand QDR Adapter for Power) + pci:v000015B3d0000673Csv00001014sd00000487* ID_MODEL_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE] (GX++ 1-port 4X IB QDR Adapter for Power 795) @@ -54962,6 +55307,9 @@ pci:v000015B3d00007122* pci:v000015B3d00007123* ID_MODEL_FROM_DATABASE=NPS-600 network interface VF +pci:v000015B3d00008200* + ID_MODEL_FROM_DATABASE=Innova-2 Flex Shell Logic + pci:v000015B3d0000A2D0* ID_MODEL_FROM_DATABASE=MT416842 BlueField SoC Crypto enabled @@ -55064,6 +55412,9 @@ pci:v000015B7* pci:v000015B7d00002001* ID_MODEL_FROM_DATABASE=Skyhawk Series NVME SSD +pci:v000015B7d00005001* + ID_MODEL_FROM_DATABASE=WD Black NVMe SSD + pci:v000015B8* ID_VENDOR_FROM_DATABASE=ADDI-DATA GmbH @@ -55508,6 +55859,21 @@ pci:v00001629d00001007* pci:v00001629d00002002* ID_MODEL_FROM_DATABASE=Fast Universal Data Output +pci:v00001629d00003100* + ID_MODEL_FROM_DATABASE=IO31000 Frame Synchronizer and I/O + +pci:v00001629d00003200* + ID_MODEL_FROM_DATABASE=IO32000 Frame Synchronizer and I/O + +pci:v00001629d00004002* + ID_MODEL_FROM_DATABASE=High Rate Demodulator + +pci:v00001629d00005001* + ID_MODEL_FROM_DATABASE=High Rate FEC + +pci:v00001629d00006001* + ID_MODEL_FROM_DATABASE=High Rate Demodulator and FEC + pci:v00001631* ID_VENDOR_FROM_DATABASE=Packard Bell B.V. @@ -56402,6 +56768,9 @@ pci:v0000168Cd00000029sv00001186sd00003A7A* pci:v0000168Cd00000029sv00001186sd00003A7D* ID_MODEL_FROM_DATABASE=AR922X Wireless Network Adapter (DWA-552 802.11n Xtreme N Desktop Adapter (rev A3)) +pci:v0000168Cd00000029sv0000168Csd00000029* + ID_MODEL_FROM_DATABASE=AR922X Wireless Network Adapter + pci:v0000168Cd00000029sv0000168Csd00002096* ID_MODEL_FROM_DATABASE=AR922X Wireless Network Adapter (Compex WLM200NX / Wistron DNMA-92) @@ -56939,6 +57308,9 @@ pci:v000016D5d00007013* pci:v000016D5d00007014* ID_MODEL_FROM_DATABASE=AP445: 32-Channel Isolated Digital Output Module +pci:v000016D5d00007015* + ID_MODEL_FROM_DATABASE=AP471 48-Channel TTL Level Digital Input/Output Module + pci:v000016D5d00007016* ID_MODEL_FROM_DATABASE=AP470 48-Channel TTL Level Digital Input/Output Module @@ -56957,6 +57329,12 @@ pci:v000016D5d0000701A* pci:v000016D5d0000701B* ID_MODEL_FROM_DATABASE=AP231-16 16-Bit, 16-Channel Analog Output Module +pci:v000016D5d0000701C* + ID_MODEL_FROM_DATABASE=AP225 12-Bit, 16-Channel Analog Output Module with Waveform Memory + +pci:v000016D5d0000701D* + ID_MODEL_FROM_DATABASE=AP235 16-Bit, 16-Channel Analog Output Module with Waveform Memory + pci:v000016D5d00007021* ID_MODEL_FROM_DATABASE=APA7-201 Reconfigurable Artix-7 FPGA module 48 TTL channels @@ -56972,6 +57350,15 @@ pci:v000016D5d00007024* pci:v000016D5d00007027* ID_MODEL_FROM_DATABASE=AP418 16-Channel High Voltage Digital Input/Output Module +pci:v000016D5d00007029* + ID_MODEL_FROM_DATABASE=AP342 14-bit, 12-Channel Isolated Simultaneous Conversion Analog Input Module + +pci:v000016D5d0000702A* + ID_MODEL_FROM_DATABASE=AP226 12-Bit, 8-Channel Isolated Analog Output Module + +pci:v000016D5d0000702B* + ID_MODEL_FROM_DATABASE=AP236 16-Bit, 8-Channel Isolated Analog Output Module + pci:v000016D5d00007042* ID_MODEL_FROM_DATABASE=AP482 Counter Timer Module with TTL Level Input/Output @@ -59435,6 +59822,15 @@ pci:v00001924d00000A03sv00001924sd0000801A* pci:v00001924d00000A03sv00001924sd0000801B* ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R3 8000 Series 10G Adapter) +pci:v00001924d00000B03* + ID_MODEL_FROM_DATABASE=SFC9250 10/25/40/50/100G Ethernet Controller + +pci:v00001924d00000B03sv00001924sd0000801D* + ID_MODEL_FROM_DATABASE=SFC9250 10/25/40/50/100G Ethernet Controller (x2522-R1 2000 Series 10/25G Adapter) + +pci:v00001924d00000B03sv00001924sd0000801E* + ID_MODEL_FROM_DATABASE=SFC9250 10/25/40/50/100G Ethernet Controller (x2542-R1 2000 Series 40/100G Adapter) + pci:v00001924d00001803* ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Virtual Function) @@ -59450,6 +59846,9 @@ pci:v00001924d00001923* pci:v00001924d00001A03* ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (Virtual Function) +pci:v00001924d00001B03* + ID_MODEL_FROM_DATABASE=SFC9250 10/25/40/50/100G Ethernet Controller (Virtual Function) + pci:v00001924d00006703* ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] @@ -59510,6 +59909,9 @@ pci:v00001932* pci:v0000193C* ID_VENDOR_FROM_DATABASE=MAXIM Integrated Products +pci:v0000193D* + ID_VENDOR_FROM_DATABASE=Hangzhou H3C Technologies Co., Ltd. + pci:v0000193F* ID_VENDOR_FROM_DATABASE=AHA Products Group @@ -61340,6 +61742,12 @@ pci:v00001BBFd00000003* pci:v00001BBFd00000004* ID_MODEL_FROM_DATABASE=MAX4 +pci:v00001BCF* + ID_VENDOR_FROM_DATABASE=NEC Corporation + +pci:v00001BCFd0000001C* + ID_MODEL_FROM_DATABASE=Vector Engine 1.0 + pci:v00001BD0* ID_VENDOR_FROM_DATABASE=Astronics Corporation @@ -61871,9 +62279,27 @@ pci:v00001D65d000004DE* pci:v00001D6A* ID_VENDOR_FROM_DATABASE=Aquantia Corp. +pci:v00001D6Ad000007B1* + ID_MODEL_FROM_DATABASE=AQC107 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + +pci:v00001D6Ad000008B1* + ID_MODEL_FROM_DATABASE=AQC108 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + +pci:v00001D6Ad000011B1* + ID_MODEL_FROM_DATABASE=AQC111 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + +pci:v00001D6Ad000012B1* + ID_MODEL_FROM_DATABASE=AQC112 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + +pci:v00001D6Ad000087B1* + ID_MODEL_FROM_DATABASE=AQC107 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + pci:v00001D6Ad0000D107* ID_MODEL_FROM_DATABASE=AQC107 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] +pci:v00001D6Ad0000D108* + ID_MODEL_FROM_DATABASE=AQC108 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + pci:v00001D6C* ID_VENDOR_FROM_DATABASE=Atomic Rules LLC @@ -61940,6 +62366,96 @@ pci:v00001D87* pci:v00001D8F* ID_VENDOR_FROM_DATABASE=Enyx +pci:v00001D94* + ID_VENDOR_FROM_DATABASE=Chengdu Higon IC Design Co.Ltd + +pci:v00001D94d00001450* + ID_MODEL_FROM_DATABASE=Root Complex + +pci:v00001D94d00001451* + ID_MODEL_FROM_DATABASE=I/O Memory Management Unit + +pci:v00001D94d00001452* + ID_MODEL_FROM_DATABASE=PCIe Dummy Host Bridge + +pci:v00001D94d00001453* + ID_MODEL_FROM_DATABASE=PCIE GPP Bridge + +pci:v00001D94d00001454* + ID_MODEL_FROM_DATABASE=Internal PCIe GPP Bridge 0 to Bus B + +pci:v00001D94d00001455* + ID_MODEL_FROM_DATABASE=PCIe Dummy Function + +pci:v00001D94d00001456* + ID_MODEL_FROM_DATABASE=PSPCCP Command DMA Processor + +pci:v00001D94d00001458* + ID_MODEL_FROM_DATABASE=10 Gb Ethernet Controller Port 0/Port1 + +pci:v00001D94d00001459* + ID_MODEL_FROM_DATABASE=10 Gb Ethernet Controller Port 2/Port3 + +pci:v00001D94d0000145A* + ID_MODEL_FROM_DATABASE=PCIe Dummy Function + +pci:v00001D94d0000145B* + ID_MODEL_FROM_DATABASE=PCIE Non-Transparent Bridge + +pci:v00001D94d0000145C* + ID_MODEL_FROM_DATABASE=USB3 XHCI + +pci:v00001D94d0000145D* + ID_MODEL_FROM_DATABASE=Switch upstream in PCIe + +pci:v00001D94d0000145E* + ID_MODEL_FROM_DATABASE=Switch downstream in PCIe + +pci:v00001D94d0000145F* + ID_MODEL_FROM_DATABASE=USB 3.0 Host controller + +pci:v00001D94d00001460* + ID_MODEL_FROM_DATABASE=Data Fabric: Device 18h; Function 0 + +pci:v00001D94d00001461* + ID_MODEL_FROM_DATABASE=Data Fabric: Device 18h; Function 1 + +pci:v00001D94d00001462* + ID_MODEL_FROM_DATABASE=Data Fabric: Device 18h; Function 2 + +pci:v00001D94d00001463* + ID_MODEL_FROM_DATABASE=Data Fabric: Device 18h; Function 3 + +pci:v00001D94d00001464* + ID_MODEL_FROM_DATABASE=Data Fabric: Device 18h; Function 4 + +pci:v00001D94d00001465* + ID_MODEL_FROM_DATABASE=Data Fabric: Device 18h; Function 5 + +pci:v00001D94d00001466* + ID_MODEL_FROM_DATABASE=Data Fabric: Device 18h; Function 6 + +pci:v00001D94d00001467* + ID_MODEL_FROM_DATABASE=Data Fabric: Device 18h; Function 7 + +pci:v00001D94d00001468* + ID_MODEL_FROM_DATABASE=NTBCCP + +pci:v00001D94d00007901* + ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] + +pci:v00001D94d00007904* + ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] + +pci:v00001D94d00007906* + ID_MODEL_FROM_DATABASE=FCH SD Flash Controller + +pci:v00001D94d0000790B* + ID_MODEL_FROM_DATABASE=FCH SMBus Controller + +pci:v00001D94d0000790E* + ID_MODEL_FROM_DATABASE=FCH LPC Bridge + pci:v00001D95* ID_VENDOR_FROM_DATABASE=Graphcore Ltd @@ -61973,6 +62489,36 @@ pci:v00001DE5d00001000* pci:v00001DE5d00002000* ID_MODEL_FROM_DATABASE=NoLoad Hardware Development Kit +pci:v00001DEF* + ID_VENDOR_FROM_DATABASE=Ampere Computing, LLC + +pci:v00001DEFd0000E005* + ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 0 [X-Gene 3] + +pci:v00001DEFd0000E006* + ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 1 [X-Gene 3] + +pci:v00001DEFd0000E007* + ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 2 [X-Gene 3] + +pci:v00001DEFd0000E008* + ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 3 [X-Gene 3] + +pci:v00001DEFd0000E009* + ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 4 [X-Gene 3] + +pci:v00001DEFd0000E00A* + ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 5 [X-Gene 3] + +pci:v00001DEFd0000E00B* + ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 6 [X-Gene 3] + +pci:v00001DEFd0000E00C* + ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 7 [X-Gene 3] + +pci:v00001DF7* + ID_VENDOR_FROM_DATABASE=opencpi.org + pci:v00001FC0* ID_VENDOR_FROM_DATABASE=Ascom (Finland) Oy @@ -64088,6 +64634,12 @@ pci:v00007063d00005500* pci:v00007284* ID_VENDOR_FROM_DATABASE=HT OMEGA Inc. +pci:v00007357* + ID_VENDOR_FROM_DATABASE=IOxOS Technologies SA + +pci:v00007357d00007910* + ID_MODEL_FROM_DATABASE=7910 [Althea] + pci:v00007401* ID_VENDOR_FROM_DATABASE=EndRun Technologies @@ -69639,10 +70191,13 @@ pci:v00008086d000015CE* ID_MODEL_FROM_DATABASE=Ethernet Connection X553 10 GbE SFP+ pci:v00008086d000015D0* - ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-100GbE-QDA2 + ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter pci:v00008086d000015D0sv00008086sd00000001* - ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-100GbE-QDA2 + ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter (FM10420-100GbE-QDA2) + +pci:v00008086d000015D0sv00008086sd00000002* + ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter (FM10840-MTP2) pci:v00008086d000015D1* ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T @@ -69716,6 +70271,30 @@ pci:v00008086d000015E4* pci:v00008086d000015E5* ID_MODEL_FROM_DATABASE=Ethernet Connection X553 1GbE +pci:v00008086d000015E7* + ID_MODEL_FROM_DATABASE=JHL7540 Thunderbolt 3 Bridge [Titan Ridge 2C 2018] + +pci:v00008086d000015E8* + ID_MODEL_FROM_DATABASE=JHL7540 Thunderbolt 3 NHI [Titan Ridge 2C 2018] + +pci:v00008086d000015E9* + ID_MODEL_FROM_DATABASE=JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 2C 2018] + +pci:v00008086d000015EA* + ID_MODEL_FROM_DATABASE=JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] + +pci:v00008086d000015EB* + ID_MODEL_FROM_DATABASE=JHL7540 Thunderbolt 3 NHI [Titan Ridge 4C 2018] + +pci:v00008086d000015EC* + ID_MODEL_FROM_DATABASE=JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 4C 2018] + +pci:v00008086d000015EF* + ID_MODEL_FROM_DATABASE=JHL7540 Thunderbolt 3 Bridge [Titan Ridge DD 2018] + +pci:v00008086d000015F0* + ID_MODEL_FROM_DATABASE=JHL7540 Thunderbolt 3 USB Controller [Titan Ridge DD 2018] + pci:v00008086d00001600* ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge -OPI @@ -70991,6 +71570,9 @@ pci:v00008086d00001E2Dsv00001849sd00001E2D* pci:v00008086d00001E31* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller +pci:v00008086d00001E31sv0000103Csd0000179B* + ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (Elitebook 8470p) + pci:v00008086d00001E31sv0000103Csd000017AB* ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (ProBook 6570b) @@ -71918,6 +72500,9 @@ pci:v00008086d00002448sv00001028sd0000040B* pci:v00008086d00002448sv0000103Csd00000934* ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Compaq nw8240 Mobile Workstation) +pci:v00008086d00002448sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Compaq nc6220 Notebook PC) + pci:v00008086d00002448sv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (NX6110/NC6120) @@ -73904,6 +74489,9 @@ pci:v00008086d00002590sv00001028sd00000182* pci:v00008086d00002590sv0000103Csd00000934* ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Compaq nw8240/nx8220) +pci:v00008086d00002590sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Compaq nc6220 Notebook PC) + pci:v00008086d00002590sv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (NX6110/NC6120) @@ -74456,6 +75044,9 @@ pci:v00008086d00002641sv00001014sd00000568* pci:v00008086d00002641sv0000103Csd00000934* ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge (Compaq nw8240/nx8220) +pci:v00008086d00002641sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge (Compaq nc6220 Notebook PC) + pci:v00008086d00002641sv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge (NX6110/NC6120) @@ -74516,6 +75107,9 @@ pci:v00008086d00002658sv00001028sd00000179* pci:v00008086d00002658sv0000103Csd00000934* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (Compaq nw8240/nx8220) +pci:v00008086d00002658sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (Compaq nc6220 Notebook PC) + pci:v00008086d00002658sv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (NX6110/NC6120) @@ -74555,6 +75149,9 @@ pci:v00008086d00002659sv00001028sd00000179* pci:v00008086d00002659sv0000103Csd00000934* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (Compaq nw8240/nx8220) +pci:v00008086d00002659sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (Compaq nc6220 Notebook PC) + pci:v00008086d00002659sv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (NX6110/NC6120) @@ -74594,6 +75191,9 @@ pci:v00008086d0000265Asv00001028sd00000179* pci:v00008086d0000265Asv0000103Csd00000934* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (Compaq nw8240/nx8220) +pci:v00008086d0000265Asv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (Compaq nc6220 Notebook PC) + pci:v00008086d0000265Asv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (NX6110/NC6120) @@ -74669,6 +75269,9 @@ pci:v00008086d0000265Csv00001028sd00000179* pci:v00008086d0000265Csv0000103Csd00000934* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (Compaq nw8240/nx8220) +pci:v00008086d0000265Csv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (Compaq nc6220 Notebook PC) + pci:v00008086d0000265Csv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (NX6110/NC6120) @@ -74702,6 +75305,9 @@ pci:v00008086d00002660* pci:v00008086d00002660sv0000103Csd00000934* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 (Compaq nw8240 Mobile Workstation) +pci:v00008086d00002660sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 (Compaq nc6220 Notebook PC) + pci:v00008086d00002660sv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 (NX6110/NC6120) @@ -74720,6 +75326,9 @@ pci:v00008086d00002662* pci:v00008086d00002662sv0000103Csd00000934* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 (Compaq nw8240 Mobile Workstation) +pci:v00008086d00002662sv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 (Compaq nc6220 Notebook PC) + pci:v00008086d00002662sv0000E4BFsd00000CCD* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 (CCD-CALYPSO) @@ -74876,6 +75485,9 @@ pci:v00008086d0000266Fsv00001028sd00000177* pci:v00008086d0000266Fsv0000103Csd00000934* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (Compaq nw8240/nx8220) +pci:v00008086d0000266Fsv0000103Csd00000944* + ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (Compaq nc6220 Notebook PC) + pci:v00008086d0000266Fsv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (NX6110/NC6120) @@ -75092,6 +75704,24 @@ pci:v00008086d0000269Esv000015D9sd00008680* pci:v00008086d0000269Esv000015D9sd00009680* ID_MODEL_FROM_DATABASE=631xESB/632xESB IDE Controller (X7DBN Motherboard) +pci:v00008086d00002700* + ID_MODEL_FROM_DATABASE=Optane SSD 900P Series + +pci:v00008086d00002700sv00008086sd00003900* + ID_MODEL_FROM_DATABASE=Optane SSD 900P Series (900P Series [Add-in Card]) + +pci:v00008086d00002700sv00008086sd00003901* + ID_MODEL_FROM_DATABASE=Optane SSD 900P Series (900P Series [2.5" SFF]) + +pci:v00008086d00002701* + ID_MODEL_FROM_DATABASE=Optane DC P4800X Series SSD + +pci:v00008086d00002701sv00008086sd00003904* + ID_MODEL_FROM_DATABASE=Optane DC P4800X Series SSD (DC P4800X Series [Add-in Card]) + +pci:v00008086d00002701sv00008086sd00003905* + ID_MODEL_FROM_DATABASE=Optane DC P4800X Series SSD (DC P4800X Series [2.5" SFF]) + pci:v00008086d00002770* ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub @@ -75182,6 +75812,9 @@ pci:v00008086d00002792sv00001014sd00000582* pci:v00008086d00002792sv0000103Csd0000099C* ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (NX6110/NC6120) +pci:v00008086d00002792sv0000103Csd0000308A* + ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (Compaq nc6220 Notebook PC) + pci:v00008086d00002792sv00001043sd00001881* ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (GMA 900 915GM Integrated Graphics) @@ -81267,7 +81900,7 @@ pci:v00008086d00004220sv0000103Csd00000934* ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (Compaq nw8240/nx8220) pci:v00008086d00004220sv0000103Csd000012F6* - ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (nc6120/nx8220/nw8240) + ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (nc6120/nc6220/nw8240/nx8220) pci:v00008086d00004220sv00008086sd00002701* ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (WM3B2200BG Mini-PCI Card) @@ -81710,6 +82343,9 @@ pci:v00008086d00005910* pci:v00008086d00005912* ID_MODEL_FROM_DATABASE=HD Graphics 630 +pci:v00008086d00005914* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers + pci:v00008086d00005916* ID_MODEL_FROM_DATABASE=HD Graphics 620 @@ -81719,6 +82355,9 @@ pci:v00008086d00005916sv000017AAsd00002248* pci:v00008086d00005916sv000017AAsd0000224F* ID_MODEL_FROM_DATABASE=HD Graphics 620 (ThinkPad X1 Carbon 5th Gen) +pci:v00008086d00005917* + ID_MODEL_FROM_DATABASE=UHD Graphics 620 + pci:v00008086d0000591D* ID_MODEL_FROM_DATABASE=HD Graphics P630 @@ -82967,6 +83606,12 @@ pci:v00008086d00008C26sv0000103Csd00001909* pci:v00008086d00008C26sv000017AAsd0000220E* ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ThinkPad T440p) +pci:v00008086d00008C26sv000017AAsd00002210* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ThinkPad T540p) + +pci:v00008086d00008C26sv00002210sd000017AA* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ThinkPad T540p) + pci:v00008086d00008C2D* ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 @@ -85673,6 +86318,21 @@ pci:v00009005d0000028Fsv0000103Csd00001100* pci:v00009005d0000028Fsv0000103Csd00001101* ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P416ie-m SR G10) +pci:v00009005d0000028Fsv0000152Dsd00008A22* + ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8204-8i) + +pci:v00009005d0000028Fsv0000152Dsd00008A23* + ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8238-16i) + +pci:v00009005d0000028Fsv0000152Dsd00008A24* + ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8236-16i) + +pci:v00009005d0000028Fsv0000152Dsd00008A36* + ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8240-24i) + +pci:v00009005d0000028Fsv0000152Dsd00008A37* + ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8242-24i) + pci:v00009005d0000028Fsv00009005sd00000800* ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-8i) @@ -86253,10 +86913,10 @@ pci:v0000BDBDd0000A127* ID_MODEL_FROM_DATABASE=UltraStudio Express pci:v0000BDBDd0000A129* - ID_MODEL_FROM_DATABASE=UltraStudio Mini Monitor + ID_MODEL_FROM_DATABASE=UltraStudio Mini Recorder pci:v0000BDBDd0000A12A* - ID_MODEL_FROM_DATABASE=UltraStudio Mini Recorder + ID_MODEL_FROM_DATABASE=UltraStudio Mini Monitor pci:v0000BDBDd0000A12D* ID_MODEL_FROM_DATABASE=UltraStudio 4K @@ -86300,6 +86960,21 @@ pci:v0000BDBDd0000A13F* pci:v0000BDBDd0000A140* ID_MODEL_FROM_DATABASE=DeckLink Duo 2 +pci:v0000BDBDd0000A141* + ID_MODEL_FROM_DATABASE=UltraStudio 4K Extreme 3 + +pci:v0000BDBDd0000A142* + ID_MODEL_FROM_DATABASE=UltraStudio HD Mini + +pci:v0000BDBDd0000A143* + ID_MODEL_FROM_DATABASE=DeckLink Mini Recorder 4K + +pci:v0000BDBDd0000A144* + ID_MODEL_FROM_DATABASE=DeckLink Mini Monitor 4K + +pci:v0000BDBDd0000A14B* + ID_MODEL_FROM_DATABASE=DeckLink 8K Pro + pci:v0000C001* ID_VENDOR_FROM_DATABASE=TSI Telsys diff --git a/hwdb/20-usb-vendor-model.hwdb b/hwdb/20-usb-vendor-model.hwdb index 632c46f3bf..8458828ade 100644 --- a/hwdb/20-usb-vendor-model.hwdb +++ b/hwdb/20-usb-vendor-model.hwdb @@ -48422,6 +48422,93 @@ usb:v1519* usb:v1519p0020* ID_MODEL_FROM_DATABASE=HSIC Device +usb:v151F* + ID_VENDOR_FROM_DATABASE=Opal Kelly Incorporated + +usb:v151Fp0020* + ID_MODEL_FROM_DATABASE=XEM3001v1 + +usb:v151Fp0021* + ID_MODEL_FROM_DATABASE=XEM3001v2 + +usb:v151Fp0022* + ID_MODEL_FROM_DATABASE=XEM3010 + +usb:v151Fp0023* + ID_MODEL_FROM_DATABASE=XEM3005 + +usb:v151Fp0028* + ID_MODEL_FROM_DATABASE=XEM3050 + +usb:v151Fp002B* + ID_MODEL_FROM_DATABASE=XEM5010 + +usb:v151Fp002C* + ID_MODEL_FROM_DATABASE=XEM6001 + +usb:v151Fp002D* + ID_MODEL_FROM_DATABASE=XEM6010-LX45 + +usb:v151Fp002E* + ID_MODEL_FROM_DATABASE=XEM6010-LX150 + +usb:v151Fp0030* + ID_MODEL_FROM_DATABASE=XEM6006-LX16 + +usb:v151Fp0033* + ID_MODEL_FROM_DATABASE=XEM6002-LX9 + +usb:v151Fp0034* + ID_MODEL_FROM_DATABASE=XEM7001-A15 + +usb:v151Fp0036* + ID_MODEL_FROM_DATABASE=XEM7010-A50 + +usb:v151Fp0037* + ID_MODEL_FROM_DATABASE=XEM7010-A200 + +usb:v151Fp0120* + ID_MODEL_FROM_DATABASE=ZEM4310 + +usb:v151Fp0121* + ID_MODEL_FROM_DATABASE=XEM6310-LX45 + +usb:v151Fp0122* + ID_MODEL_FROM_DATABASE=XEM6310-LX150 + +usb:v151Fp0123* + ID_MODEL_FROM_DATABASE=XEM6310MT-LX45T + +usb:v151Fp0125* + ID_MODEL_FROM_DATABASE=XEM7350-K70T + +usb:v151Fp0126* + ID_MODEL_FROM_DATABASE=XEM7350-K160T + +usb:v151Fp0127* + ID_MODEL_FROM_DATABASE=XEM7350-K410T + +usb:v151Fp0128* + ID_MODEL_FROM_DATABASE=XEM6310MT-LX150T + +usb:v151Fp0129* + ID_MODEL_FROM_DATABASE=ZEM5305-A2 + +usb:v151Fp012B* + ID_MODEL_FROM_DATABASE=XEM7360-K160T + +usb:v151Fp012C* + ID_MODEL_FROM_DATABASE=XEM7360-K410T + +usb:v151Fp012D* + ID_MODEL_FROM_DATABASE=ZEM5310-A4 + +usb:v151Fp0130* + ID_MODEL_FROM_DATABASE=XEM7310-A75 + +usb:v151Fp0131* + ID_MODEL_FROM_DATABASE=XEM7310-A200 + usb:v1520* ID_VENDOR_FROM_DATABASE=Bitwire Corp. @@ -55958,6 +56045,45 @@ usb:v24E1p3001* usb:v24E1p3005* ID_MODEL_FROM_DATABASE=Radius +usb:v2516* + ID_VENDOR_FROM_DATABASE=Cooler Master Co., Ltd. + +usb:v2516p0003* + ID_MODEL_FROM_DATABASE=Storm Xornet + +usb:v2516p0004* + ID_MODEL_FROM_DATABASE=Storm QuickFire Rapid Mechanical Keyboard + +usb:v2516p0006* + ID_MODEL_FROM_DATABASE=Storm Recon + +usb:v2516p0007* + ID_MODEL_FROM_DATABASE=Storm Sentinel Advance II + +usb:v2516p0009* + ID_MODEL_FROM_DATABASE=Storm Quick Fire PRO + +usb:v2516p0011* + ID_MODEL_FROM_DATABASE=Storm Quick Fire TK + +usb:v2516p0017* + ID_MODEL_FROM_DATABASE=CM Storm Quick Fire Stealth + +usb:v2516p0020* + ID_MODEL_FROM_DATABASE=QuickFire Rapid-i Keyboard + +usb:v2516p0027* + ID_MODEL_FROM_DATABASE=CM Storm Coolermaster Novatouch TKL + +usb:v2516p002D* + ID_MODEL_FROM_DATABASE=Alcor mouse + +usb:v2516p0047* + ID_MODEL_FROM_DATABASE=MasterKeys Pro L + +usb:v2516p9494* + ID_MODEL_FROM_DATABASE=Sirus Headset + usb:v2632* ID_VENDOR_FROM_DATABASE=TwinMOS diff --git a/hwdb/60-evdev.hwdb b/hwdb/60-evdev.hwdb index eb04de6863..ff28b7e039 100644 --- a/hwdb/60-evdev.hwdb +++ b/hwdb/60-evdev.hwdb @@ -47,6 +47,7 @@ evdev:input:b0003v05ACp021B* # Macbook4,1 evdev:input:b0003v05ACp0229* +evdev:input:b0003v05ACp022A* EVDEV_ABS_00=256:1471:12 EVDEV_ABS_01=256:831:12 @@ -94,6 +95,11 @@ evdev:input:b0003v05ACp025B* # ASUS ######################################### +# Asus F3Sg +evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnASUSTeKComputerInc.:pnF3Sg:* + EVDEV_ABS_00=0:6143:136 + EVDEV_ABS_01=1103:5856:61 + # Asus VivoBook E402SA evdev:name:Elan Touchpad:dmi:*svnASUSTeKCOMPUTERINC.:pnE402SA* EVDEV_ABS_00=::29 diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 33895ed75e..a265f1223f 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -478,6 +478,10 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC: evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*13*x360*:pvr* KEYBOARD_KEY_d7=unknown +# Purism Librem 13 V2 +evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPurism*:pn*Librem13v2*:pvr* + KEYBOARD_KEY_56=backslash + # Elitebook evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*EliteBook*:pvr* @@ -557,6 +561,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*ProBook4*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHP*ProBook*4*:pvr* # HP ZBook evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook*:pvr* +evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPZBook*:pvr* KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute # HP Folio 1040g2 @@ -763,14 +768,14 @@ evdev:input:b0003v046DpC308* # Cordless Desktop S510 evdev:input:b0003v046DpC50C* - KEYBOARD_KEY_d4=zoomin - KEYBOARD_KEY_cc=zoomout + KEYBOARD_KEY_d4=up # zoomin + KEYBOARD_KEY_cc=down # zoomout # Wave cordless evdev:input:b0003v046DpC317* KEYBOARD_KEY_9001c=scale # expo - KEYBOARD_KEY_9001f=zoomout - KEYBOARD_KEY_90020=zoomin + KEYBOARD_KEY_9001f=down # zoomout + KEYBOARD_KEY_90020=up # zoomin KEYBOARD_KEY_9003d=prog1 # gadget KEYBOARD_KEY_90005=camera KEYBOARD_KEY_90018=media @@ -787,8 +792,8 @@ evdev:input:b0003v046DpC317* # Wave cordless evdev:input:b0003v046DpC517* - KEYBOARD_KEY_c101f=zoomout - KEYBOARD_KEY_c1020=zoomin + KEYBOARD_KEY_c101f=down # zoomout + KEYBOARD_KEY_c1020=up # zoomin KEYBOARD_KEY_c1005=camera KEYBOARD_KEY_c0183=media KEYBOARD_KEY_c1041=wordprocessor @@ -813,8 +818,8 @@ evdev:input:b0003v046DpC52[9B]* KEYBOARD_KEY_0c018a=mail KEYBOARD_KEY_0c0221=search KEYBOARD_KEY_0c00b8=ejectcd - KEYBOARD_KEY_0c022d=zoomin - KEYBOARD_KEY_0c022e=zoomout + KEYBOARD_KEY_0c022d=up # zoomin + KEYBOARD_KEY_0c022e=down # zoomout # Logitech Presenter R400 evdev:input:b0003v046DpC52D* @@ -889,8 +894,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMEDIONNB:pnA555*:pvr* # Microsoft Natural Ergonomic Keyboard 4000 evdev:input:b0003v045Ep00DB* - KEYBOARD_KEY_c022d=zoomin - KEYBOARD_KEY_c022e=zoomout + KEYBOARD_KEY_c022d=up # zoomin + KEYBOARD_KEY_c022e=down # zoomout ########################################################### # Micro Star @@ -925,6 +930,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U-100*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U100*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*N033:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*VR420*:pvr* +evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*PR200*:pvr* KEYBOARD_KEY_f7=reserved KEYBOARD_KEY_f8=reserved @@ -1182,8 +1188,8 @@ evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-Z21*:pvr* KEYBOARD_KEY_00=brightnessdown # Fn+F5 KEYBOARD_KEY_10=brightnessup # Fn+F6 KEYBOARD_KEY_11=switchvideomode # Fn+F7 - KEYBOARD_KEY_12=zoomout - KEYBOARD_KEY_14=zoomin + KEYBOARD_KEY_12=down # zoomout + KEYBOARD_KEY_14=up # zoomin KEYBOARD_KEY_15=suspend # Fn+F12 KEYBOARD_KEY_17=prog1 KEYBOARD_KEY_20=media @@ -1193,8 +1199,8 @@ evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-FW250*:pvr* evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:pvr* KEYBOARD_KEY_05=f21 # Fn+F1 -> KEY_F21 (The actual touchpad toggle) - KEYBOARD_KEY_0d=zoomout # Fn+F9 - KEYBOARD_KEY_0e=zoomin # Fn+F10 + KEYBOARD_KEY_0d=down # Fn+F9 zoomout + KEYBOARD_KEY_0e=up # Fn+F10 zoomin ########################################################### # Toshiba @@ -1283,6 +1289,68 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote*6615WD:* KEYBOARD_KEY_ae=! # volume down KEYBOARD_KEY_b0=! # volume up +########################################## +# Ideazon +########################################## + +# Ideazon Zboard Merc +evdev:input:b0003v1038p0210* + KEYBOARD_KEY_c0227=q + KEYBOARD_KEY_c0223=w + KEYBOARD_KEY_c0221=e + KEYBOARD_KEY_c0224=a + KEYBOARD_KEY_c0226=s + KEYBOARD_KEY_c0225=d + KEYBOARD_KEY_c0192=tab + KEYBOARD_KEY_c018a=leftalt + KEYBOARD_KEY_c022a=r + KEYBOARD_KEY_c0183=f10 + KEYBOARD_KEY_70059=1 + KEYBOARD_KEY_7005a=2 + KEYBOARD_KEY_7005b=3 + KEYBOARD_KEY_7005c=4 + KEYBOARD_KEY_7005d=5 + KEYBOARD_KEY_7005e=6 + KEYBOARD_KEY_7005f=7 + KEYBOARD_KEY_70060=8 + KEYBOARD_KEY_70061=9 + KEYBOARD_KEY_70062=0 + KEYBOARD_KEY_70057=equal + KEYBOARD_KEY_70077=capslock + KEYBOARD_KEY_70054=leftshift + KEYBOARD_KEY_70063=leftctrl + KEYBOARD_KEY_7006b=t + KEYBOARD_KEY_70067=f + KEYBOARD_KEY_7006c=g + KEYBOARD_KEY_7006d=v + KEYBOARD_KEY_7006e=b + KEYBOARD_KEY_70074=p + KEYBOARD_KEY_7006f=c + KEYBOARD_KEY_70055=space + KEYBOARD_KEY_70076=f9 + KEYBOARD_KEY_70046=f11 + KEYBOARD_KEY_70079=f6 + +# Ideazon Zboard Fang +evdev:input:b0003v1038p0310* + KEYBOARD_KEY_70059=1 + KEYBOARD_KEY_7005b=3 + KEYBOARD_KEY_70040=equal + KEYBOARD_KEY_70042=l + KEYBOARD_KEY_7002b=tab + KEYBOARD_KEY_7005e=capslock + KEYBOARD_KEY_700e2=leftalt + KEYBOARD_KEY_700e1=leftshift + KEYBOARD_KEY_700e0=leftctrl + KEYBOARD_KEY_70038=z + KEYBOARD_KEY_7003e=t + KEYBOARD_KEY_70015=r + KEYBOARD_KEY_70010=g + KEYBOARD_KEY_70050=n + KEYBOARD_KEY_70030=f9 + KEYBOARD_KEY_7002f=f11 + KEYBOARD_KEY_70046=f6 + ########################################################### # Other ########################################################### diff --git a/hwdb/60-sensor.hwdb b/hwdb/60-sensor.hwdb index b46e0564d7..2e67741c36 100644 --- a/hwdb/60-sensor.hwdb +++ b/hwdb/60-sensor.hwdb @@ -66,12 +66,21 @@ sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100CHI* sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100TA* ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 +sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:pnT200TA* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + +sensor:modalias:acpi:INVN6500*:dmi:*svn*ASUSTeK*:*pn*TP300LA* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + sensor:modalias:acpi:INVN6500*:dmi:*svn*ASUSTeK*:*pn*TP300LD* ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LJ* ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 +sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LB* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + ######################################### # Axxo ######################################### @@ -82,7 +91,11 @@ sensor:modalias:acpi:SMO8500*:dmi:*:svnStandard:pnWCBT1011:* # Chuwi ######################################### -# Chuwi Vi8 Plus +# Chuwi Vi8 (CWI506) +sensor:modalias:acpi:BMA250E*:dmi:bvnINSYDECorp.:bvrCHUWI.D86JLBNR*:svnInsyde:pni86:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + +# Chuwi Vi8 Plus (CWI519) sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnD2D3_Vi8A1:* ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 @@ -90,6 +103,10 @@ sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnD2D3_Vi8A1:* sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnX1D3_C806N:* ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 +# Chuwi Hi10 Pro +sensor:modalias:acpi:BOSC0200*:dmi:*:svn*CHUWIINNOVATIONANDTECHNOLOGY*:pnHi10protablet:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + # Chuwi Hi13 sensor:modalias:acpi:KIOX000A*:dmi:svnChuwi*:pnHi13 ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 @@ -99,7 +116,7 @@ sensor:modalias:acpi:KIOX000A*:dmi:svnChuwi*:pnHi13 # match the entire dmi-alias, assuming that the use of a BOSC0200 + # bios-version + bios-date combo is unique sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/07/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring: - ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ######################################### # Cube @@ -154,6 +171,10 @@ sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:*:svnTobefilledbyO. sensor:modalias:acpi:BOSC0200*:dmi:bvnINSYDECorp.:bvrjumperx.T87.KFBNEE* ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 +# EZpad 6 Pro +sensor:modalias:acpi:BOSC0200*:dmi:*:svnJumper:pnEZpad:*:rvr.A006:* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, 1 + ######################################### # Lamina ######################################### @@ -172,6 +193,14 @@ sensor:modalias:acpi:NCPE0388*:dmi:*:rnLenovoYOGA510-14IKB:* sensor:modalias:acpi:BOSC0200:BOSC0200:dmi:*ThinkPadYoga11e3rdGen* ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1 +# Miix3-1030 +sensor:modalias:acpi:BMA250E*:dmi:bvnLENOVO:*:pvrLenovoMIIX3-1030:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + +# IdeaPad Miix 320 +sensor:modalias:acpi:*BOSC0200*:dmi:*:svnLENOVO*:pn80XF:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + ######################################### # Peaq ######################################### @@ -201,9 +230,19 @@ sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr3BAIR1013:bd08/22 ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ######################################### +# Teclast +######################################### +sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnX80Pro:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + +sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnX98PlusII:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + +######################################### # Trekstor ######################################### sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnInsyde:pnST70416-6:* +sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnTrekStor:pnSurfTabwintron7.0ST70416-6:* ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ######################################### diff --git a/hwdb/70-mouse.hwdb b/hwdb/70-mouse.hwdb index 840fa4c9ac..48fb1eb4d7 100644 --- a/hwdb/70-mouse.hwdb +++ b/hwdb/70-mouse.hwdb @@ -548,6 +548,10 @@ mouse:usb:v045ep07b1:name:Microsoft Microsoft® Nano Transceiver v1.0: mouse:bluetooth:v045ep0702:name:Microsoft Wireless Laser Mouse 8000: MOUSE_DPI=1000@1000 +# Microsoft Sculpt Comfort Mouse +mouse:bluetooth:v045ep07a2:name:Microsoft Sculpt Comfort Mouse: + MOUSE_DPI=1000@2000 + # Microsoft Arc Touch Mouse SE: mouse:bluetooth:v045ep07f3:name:Arc Touch Mouse SE: MOUSE_DPI=1000@2000 diff --git a/hwdb/70-pointingstick.hwdb b/hwdb/70-pointingstick.hwdb index f1a86ff20b..3f070e09de 100644 --- a/hwdb/70-pointingstick.hwdb +++ b/hwdb/70-pointingstick.hwdb @@ -108,6 +108,9 @@ evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX220 evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX230:* # Lenovo Thinkpad X230 tablet evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX230Tablet:* +# Lenovo ThinkPad *30 series +evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??30:* +evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??30?:* # Lenovo Thinkpad *40 series evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??40:* evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??40?:* diff --git a/hwdb/ma-large.txt b/hwdb/ma-large.txt index f05f35a4b2..04dc45a4a2 100644 --- a/hwdb/ma-large.txt +++ b/hwdb/ma-large.txt @@ -2720,12 +2720,6 @@ D8DD5F (base 16) BALMUDA Inc. Moffett Field CALIFORNIA 94035
US
-24-C8-48 (hex) mywerk system GmbH
-24C848 (base 16) mywerk system GmbH
- Dennis-Gabor-Str. 2
- Potsdam Brandenburg 14469
- DE
-
2C-18-AE (hex) Trend Electronics Co., Ltd.
2C18AE (base 16) Trend Electronics Co., Ltd.
4F-3, No 17, Lane 77, Sec. 2
@@ -8894,12 +8888,6 @@ A8CE90 (base 16) CVC London SW20 0JW
GB
-00-22-18 (hex) Verivue Inc.
-002218 (base 16) Verivue Inc.
- 3 Carlisle Road
- Westford MA 01886
- US
-
00-22-12 (hex) CAI Networks, Inc.
002212 (base 16) CAI Networks, Inc.
4790 Irvine Blvd
@@ -11846,12 +11834,6 @@ A8CE90 (base 16) CVC Gdansk 80299
PL
-00-15-C4 (hex) FLOVEL CO., LTD.
-0015C4 (base 16) FLOVEL CO., LTD.
- The Tachihi building No,3 hall, 6-1, Sakae-cho,
- Tokyo 190-0003
- US
-
00-15-C9 (hex) Gumstix, Inc
0015C9 (base 16) Gumstix, Inc
3130 Alpine Road
@@ -18212,12 +18194,6 @@ A8CE90 (base 16) CVC HSIN-CHU
TW
-00-50-89 (hex) SAFETY MANAGEMENT SYSTEMS
-005089 (base 16) SAFETY MANAGEMENT SYSTEMS
- BRANDERIJSTRAAT 6
- 5223 AS 'S-HERTOGENBOSCH'
- NL
-
00-50-66 (hex) AtecoM GmbH advanced telecomunication modules
005066 (base 16) AtecoM GmbH advanced telecomunication modules
KAISERSTR. 100
@@ -26108,330 +26084,12 @@ D4258B (base 16) Intel Corporate Kulim Kedah 09000
MY
-B4-F2-E8 (hex) ARRIS Group, Inc.
-B4F2E8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-D0-E5-4D (hex) ARRIS Group, Inc.
-D0E54D (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-70-85-C6 (hex) ARRIS Group, Inc.
-7085C6 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-44-AA-F5 (hex) ARRIS Group, Inc.
-44AAF5 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-50-94 (hex) ARRIS Group, Inc.
-005094 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-FC-8E-7E (hex) ARRIS Group, Inc.
-FC8E7E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
00-E1-8C (hex) Intel Corporate
00E18C (base 16) Intel Corporate
Lot 8, Jalan Hi-Tech 2/3
Kulim Kedah 09000
MY
-90-3E-AB (hex) ARRIS Group, Inc.
-903EAB (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-14-CF-E2 (hex) ARRIS Group, Inc.
-14CFE2 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-90-0D-CB (hex) ARRIS Group, Inc.
-900DCB (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-20-73-55 (hex) ARRIS Group, Inc.
-207355 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-C8-3F-B4 (hex) ARRIS Group, Inc.
-C83FB4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E0-B7-0A (hex) ARRIS Group, Inc.
-E0B70A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-78-71-9C (hex) ARRIS Group, Inc.
-78719C (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-D4-05-98 (hex) ARRIS Group, Inc.
-D40598 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-94-62-69 (hex) ARRIS Group, Inc.
-946269 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-8C-7F-3B (hex) ARRIS Group, Inc.
-8C7F3B (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-40-B7-F3 (hex) ARRIS Group, Inc.
-40B7F3 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-20-E5-64 (hex) ARRIS Group, Inc.
-20E564 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-90-B1-34 (hex) ARRIS Group, Inc.
-90B134 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-3C-43-8E (hex) ARRIS Group, Inc.
-3C438E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E8-6D-52 (hex) ARRIS Group, Inc.
-E86D52 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-D0 (hex) ARRIS Group, Inc.
-0015D0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-CE (hex) ARRIS Group, Inc.
-001DCE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-D4 (hex) ARRIS Group, Inc.
-001DD4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-CD (hex) ARRIS Group, Inc.
-001DCD (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-CC-A4-62 (hex) ARRIS Group, Inc.
-CCA462 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-D0-39-B3 (hex) ARRIS Group, Inc.
-D039B3 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-00-C5 (hex) ARRIS Group, Inc.
-0000C5 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-3C-36-E4 (hex) ARRIS Group, Inc.
-3C36E4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-AC-E0 (hex) ARRIS Group, Inc.
-00ACE0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-38-4C-90 (hex) ARRIS Group, Inc.
-384C90 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-D4-0A-A9 (hex) ARRIS Group, Inc.
-D40AA9 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-48-D3-43 (hex) ARRIS Group, Inc.
-48D343 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E0-22-02 (hex) ARRIS Group, Inc.
-E02202 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-2C-1D-B8 (hex) ARRIS Group, Inc.
-2C1DB8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E4-57-40 (hex) ARRIS Group, Inc.
-E45740 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-23-A3 (hex) ARRIS Group, Inc.
-0023A3 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-64-ED-57 (hex) ARRIS Group, Inc.
-64ED57 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-23-EE (hex) ARRIS Group, Inc.
-0023EE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-21-43 (hex) ARRIS Group, Inc.
-002143 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-23-AF (hex) ARRIS Group, Inc.
-0023AF (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1A-DE (hex) ARRIS Group, Inc.
-001ADE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-9A (hex) ARRIS Group, Inc.
-00159A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-08-0E (hex) ARRIS Group, Inc.
-00080E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-50-E3 (hex) ARRIS Group, Inc.
-0050E3 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-94-CC-B9 (hex) ARRIS Group, Inc.
-94CCB9 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1E-46 (hex) ARRIS Group, Inc.
-001E46 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-18-C0 (hex) ARRIS Group, Inc.
-0018C0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1A-66 (hex) ARRIS Group, Inc.
-001A66 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-19-2C (hex) ARRIS Group, Inc.
-00192C (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-25-F1 (hex) ARRIS Group, Inc.
-0025F1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-F8-7B-7A (hex) ARRIS Group, Inc.
-F87B7A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-58-56-E8 (hex) ARRIS Group, Inc.
-5856E8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
14-5E-45 (hex) Kaleao Limited
145E45 (base 16) Kaleao Limited
Sheraton House, Castle Park
@@ -27761,18 +27419,6 @@ F417B8 (base 16) AirTies Wireless Networks Augsburg Bayern 86199
DE
-EC-70-97 (hex) ARRIS Group, Inc.
-EC7097 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-C0-A0-0D (hex) ARRIS Group, Inc.
-C0A00D (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
EC-83-50 (hex) Microsoft Corporation
EC8350 (base 16) Microsoft Corporation
One Microsoft Way
@@ -28001,28 +27647,28 @@ D89C67 (base 16) Hon Hai Precision Ind. Co.,Ltd. Gumi Gyeongbuk 730-350
KR
-C8-40-29 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-C84029 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+28-BF-89 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+28BF89 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
Wuhan Hubei 430074
CN
-CC-06-77 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-CC0677 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+C8-40-29 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+C84029 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
Wuhan Hubei 430074
CN
-1C-39-8A (hex) Fiberhome Telecommunication Technologies Co.,LTD
-1C398A (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+CC-06-77 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+CC0677 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
Wuhan Hubei 430074
CN
-10-77-B0 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-1077B0 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+B0-E2-E5 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+B0E2E5 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
- Wuhan Hubei 430074
+ Wuhan City Hubei Province 430074
CN
88-94-7E (hex) Fiberhome Telecommunication Technologies Co.,LTD
@@ -28037,16 +27683,16 @@ F4573E (base 16) Fiberhome Telecommunication Technologies Co.,LTD Wuhan Hubei 430074
CN
-28-BF-89 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-28BF89 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+1C-39-8A (hex) Fiberhome Telecommunication Technologies Co.,LTD
+1C398A (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
Wuhan Hubei 430074
CN
-B0-E2-E5 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-B0E2E5 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+10-77-B0 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+1077B0 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
No.5 DongXin Road
- Wuhan City Hubei Province 430074
+ Wuhan Hubei 430074
CN
E4-30-22 (hex) Hanwha Techwin Security Vietnam
@@ -28067,278 +27713,728 @@ F0B5B7 (base 16) Disruptive Technologies Research AS Blomsterdalen Hordaland 5258
NO
-54-AE-27 (hex) Apple, Inc.
-54AE27 (base 16) Apple, Inc.
+80-CE-62 (hex) Hewlett Packard
+80CE62 (base 16) Hewlett Packard
+ 11445 Compaq Center Drive
+ Houston TX 77070
+ US
+
+80-1F-12 (hex) Microchip Technology Inc.
+801F12 (base 16) Microchip Technology Inc.
+ 2355 W. Chandler Blvd.
+ Chandler AZ 85224
+ US
+
+50-6C-BE (hex) InnosiliconTechnology Ltd
+506CBE (base 16) InnosiliconTechnology Ltd
+ WuHan East Lake Wuhan New Technology Development Zone
+ Wuhan Hubei Province 430223
+ CN
+
+04-C2-41 (hex) Nokia
+04C241 (base 16) Nokia
+ 600 March Road
+ Kanata Ontario K2K 2E6
+ CA
+
+30-7B-AC (hex) New H3C Technologies Co., Ltd
+307BAC (base 16) New H3C Technologies Co., Ltd
+ 466 Changhe Road, Binjiang District
+ Hangzhou Zhejiang 310052
+ CN
+
+80-41-26 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+804126 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+0C-C6-CC (hex) HUAWEI TECHNOLOGIES CO.,LTD
+0CC6CC (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+70-5A-AC (hex) Samsung Electronics Co.,Ltd
+705AAC (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+FC-64-3A (hex) Samsung Electronics Co.,Ltd
+FC643A (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+D4-E6-B7 (hex) Samsung Electronics Co.,Ltd
+D4E6B7 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+28-02-D8 (hex) Samsung Electronics Co.,Ltd
+2802D8 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+60-84-BD (hex) BUFFALO.INC
+6084BD (base 16) BUFFALO.INC
+ AKAMONDORI Bld.,30-20,Ohsu 3-chome,Naka-ku
+ Nagoya Aichi Pref. 460-8315
+ JP
+
+10-F9-EB (hex) Industria Fueguina de Relojería Electrónica s.a.
+10F9EB (base 16) Industria Fueguina de Relojería Electrónica s.a.
+ Sarmiento 2920
+ Rio Grande Tierra de Fuego V9420GIV
+ AR
+
+34-7E-CA (hex) NEXTWILL
+347ECA (base 16) NEXTWILL
+ JJ-Building, 20, Deongmyeong-ro 71beon-gil1, Yuseong-gu
+ Daejeon 34155
+ KR
+
+5C-5A-EA (hex) FORD
+5C5AEA (base 16) FORD
+ 17425 Federal Drive
+ Allen Park MI 48101
+ US
+
+5C-AA-FD (hex) Sonos, Inc.
+5CAAFD (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+00-0E-58 (hex) Sonos, Inc.
+000E58 (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+88-29-50 (hex) Netmoon Technology Co., Ltd
+882950 (base 16) Netmoon Technology Co., Ltd
+ 2nd Floor, Building No.1, NO.319, Qingpi Avenue
+ Wenjiang District Chengdu 611130
+ CN
+
+7C-FF-4D (hex) AVM Audiovisuelles Marketing und Computersysteme GmbH
+7CFF4D (base 16) AVM Audiovisuelles Marketing und Computersysteme GmbH
+ Alt-Moabit 95
+ Berlin Berlin 10559
+ DE
+
+74-70-FD (hex) Intel Corporate
+7470FD (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+68-98-61 (hex) Beacon Inc
+689861 (base 16) Beacon Inc
+ 82-1, Anyangcheondong-ro, Dongan-gu
+ anyang Gyeonggi-do 14042
+ KR
+
+88-B3-62 (hex) Nokia Shanghai Bell Co. Ltd.)
+88B362 (base 16) Nokia Shanghai Bell Co. Ltd.)
+ No.388 Ning Qiao Road,Jin Qiao Pudong Shanghai 201206,P.R.China
+ Shanghai Pudong 201206
+ CN
+
+1C-A0-B8 (hex) Hon Hai Precision Ind. Co., Ltd.
+1CA0B8 (base 16) Hon Hai Precision Ind. Co., Ltd.
+ GuangDongShenZhen
+ ShenZhen GuangDong 518109
+ CN
+
+3C-47-9B (hex) Theissen Training Systems, Inc.
+3C479B (base 16) Theissen Training Systems, Inc.
+ 1225 SE 4th Terrace
+ Chiefland FL 32626
+ US
+
+8C-F7-73 (hex) Nokia
+8CF773 (base 16) Nokia
+ 600 March Road
+ Kanata Ontario K2K 2E6
+ CA
+
+C4-64-E3 (hex) Texas Instruments
+C464E3 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+F4-84-4C (hex) Texas Instruments
+F4844C (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+10-A4-B9 (hex) Baidu Online Network Technology (Beijing) Co., Ltd
+10A4B9 (base 16) Baidu Online Network Technology (Beijing) Co., Ltd
+ Baidu Campus, No.10 Shangdi 10th Street, Haidian District
+ Beijing 100085
+ CN
+
+1C-B0-44 (hex) ASKEY COMPUTER CORP
+1CB044 (base 16) ASKEY COMPUTER CORP
+ 10F,No.119,JIANKANG RD,ZHONGHE DIST
+ NEW TAIPEI TAIWAN 23585
+ TW
+
+90-03-72 (hex) Longnan Junya Digital Technology Co. Ltd.
+900372 (base 16) Longnan Junya Digital Technology Co. Ltd.
+ Champion Asia Road, Xinzhen industrial Park, Longnan national economic and technological development zone, Ganzhou city, JiangXi Province , China
+ ganzhou jiangxi 341700
+ CN
+
+50-14-79 (hex) iRobot Corporation
+501479 (base 16) iRobot Corporation
+ 8 Crosby Drive
+ Bedford MA 01730
+ US
+
+90-94-97 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+909497 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+EC-89-14 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+EC8914 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+DC-72-9B (hex) HUAWEI TECHNOLOGIES CO.,LTD
+DC729B (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+B8-94-36 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+B89436 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+F8-DF-15 (hex) Sunitec Enterprise Co.,Ltd
+F8DF15 (base 16) Sunitec Enterprise Co.,Ltd
+ 3F.,No.98-1,Mincyuan Rd.Sindian City
+ Taipei County 231 231141
+ CN
+
+A8-DA-01 (hex) Shenzhen NUOLIJIA Digital Technology Co.,Ltd
+A8DA01 (base 16) Shenzhen NUOLIJIA Digital Technology Co.,Ltd
+ A Area of The Second Flood and D Area of The First Floor,Factory Building A,Youxinda Industrial Park,Gengyu Road,Tianliao Community,Gongming Street Office,Guangming New District,Shenzhen City,Guangdong,P.R.China
+ Shenzhen Guangdong 518000
+ CN
+
+00-21-94 (hex) Ping Communication
+002194 (base 16) Ping Communication
+ Brenden 18
+ Appenzell Meistersrüte AI 9050
+ CH
+
+A4-38-CC (hex) Nintendo Co.,Ltd
+A438CC (base 16) Nintendo Co.,Ltd
+ 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
+ KYOTO KYOTO 601-8501
+ JP
+
+94-6A-B0 (hex) Arcadyan Corporation
+946AB0 (base 16) Arcadyan Corporation
+ No.8, Sec.2, Guangfu Rd.
+ Hsinchu City Hsinchu 30071
+ TW
+
+58-21-E9 (hex) TWPI
+5821E9 (base 16) TWPI
+ PMB# 335; 1121 Annapolis Road
+ Odenton MD 21113
+ US
+
+64-CB-5D (hex) SIA TeleSet
+64CB5D (base 16) SIA TeleSet
+ Krāslavas iela 5
+ Vecstropi, Naujenes par., Daugavpils distr. LV-5413
+ LV
+
+70-69-5A (hex) Cisco Systems, Inc
+70695A (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+A0-66-10 (hex) FUJITSU LIMITED
+A06610 (base 16) FUJITSU LIMITED
+ Mushashi-kosuge Tower Place 13F
+ Kawasaki Kanagawa 211-0063
+ JP
+
+68-D4-82 (hex) SHENZHEN GONGJIN ELECTRONICS CO.,LT
+68D482 (base 16) SHENZHEN GONGJIN ELECTRONICS CO.,LT
+ SONGGANG
+ SHENZHEN GUANGDONG 518105
+ CN
+
+30-1F-9A (hex) IEEE Registration Authority
+301F9A (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+90-79-10 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
+907910 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
+ Phase 3, Bayan Lepas FIZ
+ Bayan Lepas Penang 11900
+ MY
+
+00-A0-D5 (hex) Sierra Wireless Inc
+00A0D5 (base 16) Sierra Wireless Inc
+ 13811 Wireless Way
+ RICHMOND B.C. V6V 3A4
+ CA
+
+6C-38-38 (hex) Marking System Technology Co., Ltd.
+6C3838 (base 16) Marking System Technology Co., Ltd.
+ 76-1, Hirakawa Yokomichi
+ Joyo-shi Kyoto 610-0101
+ JP
+
+24-C8-48 (hex) mywerk Portal GmbH
+24C848 (base 16) mywerk Portal GmbH
+ Fabrikstr. 3
+ Gronau 48599
+ DE
+
+0C-2C-54 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+0C2C54 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+00-BE-3B (hex) HUAWEI TECHNOLOGIES CO.,LTD
+00BE3B (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+7C-76-68 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+7C7668 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+24-2E-02 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+242E02 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+2C-B8-ED (hex) SonicWall
+2CB8ED (base 16) SonicWall
+ 5455 Great America Parkway
+ Santa Clara CA 95054
+ US
+
+9C-2E-A1 (hex) Xiaomi Communications Co Ltd
+9C2EA1 (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+AC-35-EE (hex) FN-LINK TECHNOLOGY LIMITED
+AC35EE (base 16) FN-LINK TECHNOLOGY LIMITED
+ A Building,HuiXin industial park,No 31, YongHe road, Fuyong town, Bao'an District
+ SHENZHEN GUANGDONG 518100
+ CN
+
+00-72-78 (hex) Cisco Systems, Inc
+007278 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+E4-4E-76 (hex) CHAMPIONTECH ENTERPRISE (SHENZHEN) INC
+E44E76 (base 16) CHAMPIONTECH ENTERPRISE (SHENZHEN) INC
+ Against Office of Dong-Zhou Residential Committee Guang Ming
+ Shenzhen 518000
+ CN
+
+00-08-89 (hex) Dish Technologies Corp
+000889 (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+6C-C4-D5 (hex) HMD Global Oy
+6CC4D5 (base 16) HMD Global Oy
+ Karaportti 2
+ Espoo 02610
+ FI
+
+E8-C1-B8 (hex) Nanjing Bangzhong Electronic Commerce Limited
+E8C1B8 (base 16) Nanjing Bangzhong Electronic Commerce Limited
+ No.22, Liuzhou East Road, High - tech Zone
+ Nanjing 210000
+ CN
+
+B4-DE-31 (hex) Cisco Systems, Inc
+B4DE31 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+70-16-9F (hex) EtherCAT Technology Group
+70169F (base 16) EtherCAT Technology Group
+ Ostendstr. 196
+ NUremberg 90482
+ DE
+
+64-98-29 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
+649829 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
+ Phase 3, Bayan Lepas FIZ
+ Bayan Lepas Penang 11900
+ MY
+
+08-1D-C4 (hex) Thermo Fisher Scientific Messtechnik GmbH
+081DC4 (base 16) Thermo Fisher Scientific Messtechnik GmbH
+ Frauenauracher Strasse 96
+ Erlangen 91056
+ DE
+
+90-CC-24 (hex) Synaptics, Inc
+90CC24 (base 16) Synaptics, Inc
+ 1251 McKay Drive
+ San Jose CA 95131-1709
+ US
+
+CC-99-16 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
+CC9916 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
+ Phase 3, Bayan Lepas FIZ
+ Bayan Lepas Penang 11900
+ MY
+
+F0-41-C8 (hex) IEEE Registration Authority
+F041C8 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+00-13-86 (hex) ABB Inc/Totalflow
+001386 (base 16) ABB Inc/Totalflow
+
+ Bartlesville OK 74006
+ US
+
+A4-50-55 (hex) BUSWARE.DE
+A45055 (base 16) BUSWARE.DE
+ Lindenstrasse 18
+ Scharbeutz 23684
+ DE
+
+48-60-5F (hex) LG Electronics (Mobile Communications)
+48605F (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+00-15-C4 (hex) FLOVEL CO., LTD.
+0015C4 (base 16) FLOVEL CO., LTD.
+ The Tachihi building No,3 hall, 6-1, Sakae-cho,
+ Tokyo 190-0003
+ US
+
+3C-EA-F9 (hex) JUBIXCOLTD
+3CEAF9 (base 16) JUBIXCOLTD
+ Rm 808, 809, B dong, Gunpo IT vally, 17, Gosan-ro 148beon-gil, Gunpo-si, Gyeonggi-do, Republic of Korea
+ GUNPOSI 15850
+ KR
+
+C0-EE-B5 (hex) Enice Network.
+C0EEB5 (base 16) Enice Network.
+ NO.30, Shuige Rd, JiangNing Economic Development Zone, Nanjing
+ Nanjing 211106
+ CN
+
+DC-DE-4F (hex) Gionee Communication Equipment Co Ltd
+DCDE4F (base 16) Gionee Communication Equipment Co Ltd
+ 21/F Times Technology Building, 7028 Shennan Road
+ Shenzhen Futian District 518040
+ CN
+
+60-DE-F3 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+60DEF3 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+58-F9-87 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+58F987 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+50-1D-93 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+501D93 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+D4-72-26 (hex) zte corporation
+D47226 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+E4-82-CC (hex) Jumptronic GmbH
+E482CC (base 16) Jumptronic GmbH
+ An der Weide 5
+ Springe 31832
+ DE
+
+20-16-B9 (hex) Intel Corporate
+2016B9 (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+78-1D-4A (hex) zte corporation
+781D4A (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+F0-76-6F (hex) Apple, Inc.
+F0766F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F4-37-B7 (hex) Apple, Inc.
-F437B7 (base 16) Apple, Inc.
+40-CB-C0 (hex) Apple, Inc.
+40CBC0 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-31-C1 (hex) Apple, Inc.
-7831C1 (base 16) Apple, Inc.
+40-98-AD (hex) Apple, Inc.
+4098AD (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-8C-7C-92 (hex) Apple, Inc.
-8C7C92 (base 16) Apple, Inc.
+6C-4D-73 (hex) Apple, Inc.
+6C4D73 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D0-E1-40 (hex) Apple, Inc.
-D0E140 (base 16) Apple, Inc.
+C4-84-66 (hex) Apple, Inc.
+C48466 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-AC-FD-EC (hex) Apple, Inc.
-ACFDEC (base 16) Apple, Inc.
+B8-63-4D (hex) Apple, Inc.
+B8634D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-24-E3-14 (hex) Apple, Inc.
-24E314 (base 16) Apple, Inc.
+50-32-37 (hex) Apple, Inc.
+503237 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-2C-BE-08 (hex) Apple, Inc.
-2CBE08 (base 16) Apple, Inc.
+D4-61-9D (hex) Apple, Inc.
+D4619D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-3A-84 (hex) Apple, Inc.
-783A84 (base 16) Apple, Inc.
+B0-48-1A (hex) Apple, Inc.
+B0481A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-84-B1-53 (hex) Apple, Inc.
-84B153 (base 16) Apple, Inc.
+98-9E-63 (hex) Apple, Inc.
+989E63 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-64-76-BA (hex) Apple, Inc.
-6476BA (base 16) Apple, Inc.
+DC-A9-04 (hex) Apple, Inc.
+DCA904 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-3E-AC (hex) Apple, Inc.
-703EAC (base 16) Apple, Inc.
+48-A1-95 (hex) Apple, Inc.
+48A195 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-94-F8 (hex) Apple, Inc.
-6C94F8 (base 16) Apple, Inc.
+6C-AB-31 (hex) Apple, Inc.
+6CAB31 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-84-78-8B (hex) Apple, Inc.
-84788B (base 16) Apple, Inc.
+7C-50-49 (hex) Apple, Inc.
+7C5049 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-2C-F0-EE (hex) Apple, Inc.
-2CF0EE (base 16) Apple, Inc.
+E4-2B-34 (hex) Apple, Inc.
+E42B34 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-D9-3C (hex) Apple, Inc.
-68D93C (base 16) Apple, Inc.
+1C-36-BB (hex) Apple, Inc.
+1C36BB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F8-27-93 (hex) Apple, Inc.
-F82793 (base 16) Apple, Inc.
+3C-2E-FF (hex) Apple, Inc.
+3C2EFF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-E5-36 (hex) Apple, Inc.
-04E536 (base 16) Apple, Inc.
+6C-96-CF (hex) Apple, Inc.
+6C96CF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-88-1F-A1 (hex) Apple, Inc.
-881FA1 (base 16) Apple, Inc.
+30-35-AD (hex) Apple, Inc.
+3035AD (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-DB-56 (hex) Apple, Inc.
-04DB56 (base 16) Apple, Inc.
+A8-BE-27 (hex) Apple, Inc.
+A8BE27 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-1E-E7 (hex) Apple, Inc.
-C81EE7 (base 16) Apple, Inc.
+70-A2-B3 (hex) Apple, Inc.
+70A2B3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-34-36-3B (hex) Apple, Inc.
-34363B (base 16) Apple, Inc.
+4C-57-CA (hex) Apple, Inc.
+4C57CA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C0-1A-DA (hex) Apple, Inc.
-C01ADA (base 16) Apple, Inc.
+68-FB-7E (hex) Apple, Inc.
+68FB7E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-80-CE-62 (hex) Hewlett Packard
-80CE62 (base 16) Hewlett Packard
- 11445 Compaq Center Drive
- Houston TX 77070
+90-C1-C6 (hex) Apple, Inc.
+90C1C6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-80-1F-12 (hex) Microchip Technology Inc.
-801F12 (base 16) Microchip Technology Inc.
- 2355 W. Chandler Blvd.
- Chandler AZ 85224
+A4-F1-E8 (hex) Apple, Inc.
+A4F1E8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-50-6C-BE (hex) InnosiliconTechnology Ltd
-506CBE (base 16) InnosiliconTechnology Ltd
- WuHan East Lake Wuhan New Technology Development Zone
- Wuhan Hubei Province 430223
- CN
-
-90-CC-24 (hex) Synaptics, Inc
-90CC24 (base 16) Synaptics, Inc
- 1251 McKay Drive
- San Jose CA 95131-1709
+AC-61-EA (hex) Apple, Inc.
+AC61EA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-80-41-26 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-804126 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
-
-0C-C6-CC (hex) HUAWEI TECHNOLOGIES CO.,LTD
-0CC6CC (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
-
-3C-04-61 (hex) ARRIS Group, Inc.
-3C0461 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
+38-B5-4D (hex) Apple, Inc.
+38B54D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-04-C2-41 (hex) Nokia
-04C241 (base 16) Nokia
- 600 March Road
- Kanata Ontario K2K 2E6
- CA
-
-30-7B-AC (hex) New H3C Technologies Co., Ltd
-307BAC (base 16) New H3C Technologies Co., Ltd
- 466 Changhe Road, Binjiang District
- Hangzhou Zhejiang 310052
- CN
-
-8C-F7-73 (hex) Nokia
-8CF773 (base 16) Nokia
- 600 March Road
- Kanata Ontario K2K 2E6
- CA
-
-3C-47-9B (hex) Theissen Training Systems, Inc.
-3C479B (base 16) Theissen Training Systems, Inc.
- 1225 SE 4th Terrace
- Chiefland FL 32626
+00-CD-FE (hex) Apple, Inc.
+00CDFE (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-70-5A-AC (hex) Samsung Electronics Co.,Ltd
-705AAC (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-FC-64-3A (hex) Samsung Electronics Co.,Ltd
-FC643A (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-D4-E6-B7 (hex) Samsung Electronics Co.,Ltd
-D4E6B7 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
+18-AF-61 (hex) Apple, Inc.
+18AF61 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-28-02-D8 (hex) Samsung Electronics Co.,Ltd
-2802D8 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
+CC-44-63 (hex) Apple, Inc.
+CC4463 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-C4-64-E3 (hex) Texas Instruments
-C464E3 (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
+34-15-9E (hex) Apple, Inc.
+34159E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-F4-84-4C (hex) Texas Instruments
-F4844C (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
+58-B0-35 (hex) Apple, Inc.
+58B035 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-00-08-89 (hex) Dish Technologies Corp
-000889 (base 16) Dish Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
+F0-B4-79 (hex) Apple, Inc.
+F0B479 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-6C-C4-D5 (hex) HMD Global Oy
-6CC4D5 (base 16) HMD Global Oy
- Karaportti 2
- Espoo 02610
- FI
+10-9A-DD (hex) Apple, Inc.
+109ADD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-60-C5-47 (hex) Apple, Inc.
-60C547 (base 16) Apple, Inc.
+40-A6-D9 (hex) Apple, Inc.
+40A6D9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-28-E0-2C (hex) Apple, Inc.
-28E02C (base 16) Apple, Inc.
+7C-F0-5F (hex) Apple, Inc.
+7CF05F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-50-EA-D6 (hex) Apple, Inc.
-50EAD6 (base 16) Apple, Inc.
+A4-B1-97 (hex) Apple, Inc.
+A4B197 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-48-60-BC (hex) Apple, Inc.
-4860BC (base 16) Apple, Inc.
+0C-74-C2 (hex) Apple, Inc.
+0C74C2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
@@ -28349,761 +28445,929 @@ F4844C (base 16) Texas Instruments Cupertino CA 95014
US
-0C-74-C2 (hex) Apple, Inc.
-0C74C2 (base 16) Apple, Inc.
+48-60-BC (hex) Apple, Inc.
+4860BC (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A4-B1-97 (hex) Apple, Inc.
-A4B197 (base 16) Apple, Inc.
+D0-2B-20 (hex) Apple, Inc.
+D02B20 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-7C-F0-5F (hex) Apple, Inc.
-7CF05F (base 16) Apple, Inc.
+9C-E3-3F (hex) Apple, Inc.
+9CE33F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-6C-1C (hex) Apple, Inc.
-786C1C (base 16) Apple, Inc.
+F0-98-9D (hex) Apple, Inc.
+F0989D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-BC-3B-AF (hex) Apple, Inc.
-BC3BAF (base 16) Apple, Inc.
+AC-E4-B5 (hex) Apple, Inc.
+ACE4B5 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-D1-A9 (hex) Apple, Inc.
-F0D1A9 (base 16) Apple, Inc.
+6C-72-E7 (hex) Apple, Inc.
+6C72E7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-34-C0-59 (hex) Apple, Inc.
-34C059 (base 16) Apple, Inc.
+60-FE-C5 (hex) Apple, Inc.
+60FEC5 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-F7-E4 (hex) Apple, Inc.
-04F7E4 (base 16) Apple, Inc.
+00-A0-40 (hex) Apple, Inc.
+00A040 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-10-DD-B1 (hex) Apple, Inc.
-10DDB1 (base 16) Apple, Inc.
+00-0D-93 (hex) Apple, Inc.
+000D93 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B4-F0-AB (hex) Apple, Inc.
-B4F0AB (base 16) Apple, Inc.
+AC-BC-32 (hex) Apple, Inc.
+ACBC32 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-A0-40 (hex) Apple, Inc.
-00A040 (base 16) Apple, Inc.
+30-D9-D9 (hex) Apple, Inc.
+30D9D9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-60-FE-C5 (hex) Apple, Inc.
-60FEC5 (base 16) Apple, Inc.
+60-30-D4 (hex) Apple, Inc.
+6030D4 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-CC-44-63 (hex) Apple, Inc.
-CC4463 (base 16) Apple, Inc.
+94-BF-2D (hex) Apple, Inc.
+94BF2D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-72-E7 (hex) Apple, Inc.
-6C72E7 (base 16) Apple, Inc.
+C4-98-80 (hex) Apple, Inc.
+C49880 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-18-AF-61 (hex) Apple, Inc.
-18AF61 (base 16) Apple, Inc.
+E0-33-8E (hex) Apple, Inc.
+E0338E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-CD-FE (hex) Apple, Inc.
-00CDFE (base 16) Apple, Inc.
+68-FE-F7 (hex) Apple, Inc.
+68FEF7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-30-10-E4 (hex) Apple, Inc.
-3010E4 (base 16) Apple, Inc.
+BC-E1-43 (hex) Apple, Inc.
+BCE143 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-38-0F-4A (hex) Apple, Inc.
-380F4A (base 16) Apple, Inc.
+64-5A-ED (hex) Apple, Inc.
+645AED (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-5B-35 (hex) Apple, Inc.
-685B35 (base 16) Apple, Inc.
+C0-B6-58 (hex) Apple, Inc.
+C0B658 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-6F-1D (hex) Apple, Inc.
-C86F1D (base 16) Apple, Inc.
+88-19-08 (hex) Apple, Inc.
+881908 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-11-24 (hex) Apple, Inc.
-701124 (base 16) Apple, Inc.
+FC-2A-9C (hex) Apple, Inc.
+FC2A9C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-38-48-4C (hex) Apple, Inc.
-38484C (base 16) Apple, Inc.
+44-D8-84 (hex) Apple, Inc.
+44D884 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-15-52 (hex) Apple, Inc.
-041552 (base 16) Apple, Inc.
+EC-85-2F (hex) Apple, Inc.
+EC852F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-40-A6-D9 (hex) Apple, Inc.
-40A6D9 (base 16) Apple, Inc.
+28-6A-BA (hex) Apple, Inc.
+286ABA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-10-9A-DD (hex) Apple, Inc.
-109ADD (base 16) Apple, Inc.
+70-56-81 (hex) Apple, Inc.
+705681 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-B4-79 (hex) Apple, Inc.
-F0B479 (base 16) Apple, Inc.
+7C-D1-C3 (hex) Apple, Inc.
+7CD1C3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-58-B0-35 (hex) Apple, Inc.
-58B035 (base 16) Apple, Inc.
+F0-DC-E2 (hex) Apple, Inc.
+F0DCE2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-34-15-9E (hex) Apple, Inc.
-34159E (base 16) Apple, Inc.
+B0-65-BD (hex) Apple, Inc.
+B065BD (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-28-6A-BA (hex) Apple, Inc.
-286ABA (base 16) Apple, Inc.
+A8-20-66 (hex) Apple, Inc.
+A82066 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-EC-85-2F (hex) Apple, Inc.
-EC852F (base 16) Apple, Inc.
+BC-67-78 (hex) Apple, Inc.
+BC6778 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-44-D8-84 (hex) Apple, Inc.
-44D884 (base 16) Apple, Inc.
+68-96-7B (hex) Apple, Inc.
+68967B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-3E-E1 (hex) Apple, Inc.
-003EE1 (base 16) Apple, Inc.
+84-85-06 (hex) Apple, Inc.
+848506 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-7C-11-BE (hex) Apple, Inc.
-7C11BE (base 16) Apple, Inc.
+54-AE-27 (hex) Apple, Inc.
+54AE27 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-28-F0-76 (hex) Apple, Inc.
-28F076 (base 16) Apple, Inc.
+64-76-BA (hex) Apple, Inc.
+6476BA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-28-5A-EB (hex) Apple, Inc.
-285AEB (base 16) Apple, Inc.
+84-B1-53 (hex) Apple, Inc.
+84B153 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-08-74-02 (hex) Apple, Inc.
-087402 (base 16) Apple, Inc.
+78-3A-84 (hex) Apple, Inc.
+783A84 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-64-B9-E8 (hex) Apple, Inc.
-64B9E8 (base 16) Apple, Inc.
+2C-BE-08 (hex) Apple, Inc.
+2CBE08 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-1C-B3 (hex) Apple, Inc.
-001CB3 (base 16) Apple, Inc.
+24-E3-14 (hex) Apple, Inc.
+24E314 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-0D-93 (hex) Apple, Inc.
-000D93 (base 16) Apple, Inc.
+68-D9-3C (hex) Apple, Inc.
+68D93C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-CC-C7-60 (hex) Apple, Inc.
-CCC760 (base 16) Apple, Inc.
+2C-F0-EE (hex) Apple, Inc.
+2CF0EE (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-9C-FC-01 (hex) Apple, Inc.
-9CFC01 (base 16) Apple, Inc.
+84-78-8B (hex) Apple, Inc.
+84788B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-AC-BC-32 (hex) Apple, Inc.
-ACBC32 (base 16) Apple, Inc.
+6C-94-F8 (hex) Apple, Inc.
+6C94F8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A8-BE-27 (hex) Apple, Inc.
-A8BE27 (base 16) Apple, Inc.
+70-3E-AC (hex) Apple, Inc.
+703EAC (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-63-4D (hex) Apple, Inc.
-B8634D (base 16) Apple, Inc.
+B4-F0-AB (hex) Apple, Inc.
+B4F0AB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-9C-E3-3F (hex) Apple, Inc.
-9CE33F (base 16) Apple, Inc.
+10-DD-B1 (hex) Apple, Inc.
+10DDB1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-98-9D (hex) Apple, Inc.
-F0989D (base 16) Apple, Inc.
+04-F7-E4 (hex) Apple, Inc.
+04F7E4 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-AC-E4-B5 (hex) Apple, Inc.
-ACE4B5 (base 16) Apple, Inc.
+34-C0-59 (hex) Apple, Inc.
+34C059 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E4-2B-34 (hex) Apple, Inc.
-E42B34 (base 16) Apple, Inc.
+F0-D1-A9 (hex) Apple, Inc.
+F0D1A9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-1C-36-BB (hex) Apple, Inc.
-1C36BB (base 16) Apple, Inc.
+BC-3B-AF (hex) Apple, Inc.
+BC3BAF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-3C-2E-FF (hex) Apple, Inc.
-3C2EFF (base 16) Apple, Inc.
+78-6C-1C (hex) Apple, Inc.
+786C1C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-76-6F (hex) Apple, Inc.
-F0766F (base 16) Apple, Inc.
+04-15-52 (hex) Apple, Inc.
+041552 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-40-CB-C0 (hex) Apple, Inc.
-40CBC0 (base 16) Apple, Inc.
+38-48-4C (hex) Apple, Inc.
+38484C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-40-98-AD (hex) Apple, Inc.
-4098AD (base 16) Apple, Inc.
+70-11-24 (hex) Apple, Inc.
+701124 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-4D-73 (hex) Apple, Inc.
-6C4D73 (base 16) Apple, Inc.
+C8-6F-1D (hex) Apple, Inc.
+C86F1D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C4-84-66 (hex) Apple, Inc.
-C48466 (base 16) Apple, Inc.
+68-5B-35 (hex) Apple, Inc.
+685B35 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D0-2B-20 (hex) Apple, Inc.
-D02B20 (base 16) Apple, Inc.
+38-0F-4A (hex) Apple, Inc.
+380F4A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-70-0D (hex) Apple, Inc.
-70700D (base 16) Apple, Inc.
+30-10-E4 (hex) Apple, Inc.
+3010E4 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-7C-50-49 (hex) Apple, Inc.
-7C5049 (base 16) Apple, Inc.
+04-DB-56 (hex) Apple, Inc.
+04DB56 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-50-32-37 (hex) Apple, Inc.
-503237 (base 16) Apple, Inc.
+88-1F-A1 (hex) Apple, Inc.
+881FA1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D4-61-9D (hex) Apple, Inc.
-D4619D (base 16) Apple, Inc.
+04-E5-36 (hex) Apple, Inc.
+04E536 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B0-48-1A (hex) Apple, Inc.
-B0481A (base 16) Apple, Inc.
+F8-27-93 (hex) Apple, Inc.
+F82793 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-9E-63 (hex) Apple, Inc.
-989E63 (base 16) Apple, Inc.
+AC-FD-EC (hex) Apple, Inc.
+ACFDEC (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-DC-A9-04 (hex) Apple, Inc.
-DCA904 (base 16) Apple, Inc.
+D0-E1-40 (hex) Apple, Inc.
+D0E140 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-48-A1-95 (hex) Apple, Inc.
-48A195 (base 16) Apple, Inc.
+8C-7C-92 (hex) Apple, Inc.
+8C7C92 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-AB-31 (hex) Apple, Inc.
-6CAB31 (base 16) Apple, Inc.
+78-31-C1 (hex) Apple, Inc.
+7831C1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-96-CF (hex) Apple, Inc.
-6C96CF (base 16) Apple, Inc.
+F4-37-B7 (hex) Apple, Inc.
+F437B7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-30-35-AD (hex) Apple, Inc.
-3035AD (base 16) Apple, Inc.
+50-EA-D6 (hex) Apple, Inc.
+50EAD6 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-AC-61-EA (hex) Apple, Inc.
-AC61EA (base 16) Apple, Inc.
+28-E0-2C (hex) Apple, Inc.
+28E02C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-38-B5-4D (hex) Apple, Inc.
-38B54D (base 16) Apple, Inc.
+60-C5-47 (hex) Apple, Inc.
+60C547 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A4-F1-E8 (hex) Apple, Inc.
-A4F1E8 (base 16) Apple, Inc.
+7C-11-BE (hex) Apple, Inc.
+7C11BE (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-A2-B3 (hex) Apple, Inc.
-70A2B3 (base 16) Apple, Inc.
+00-3E-E1 (hex) Apple, Inc.
+003EE1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-4C-57-CA (hex) Apple, Inc.
-4C57CA (base 16) Apple, Inc.
+C0-1A-DA (hex) Apple, Inc.
+C01ADA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-FB-7E (hex) Apple, Inc.
-68FB7E (base 16) Apple, Inc.
+34-36-3B (hex) Apple, Inc.
+34363B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-90-C1-C6 (hex) Apple, Inc.
-90C1C6 (base 16) Apple, Inc.
+C8-1E-E7 (hex) Apple, Inc.
+C81EE7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-9C-F4-8E (hex) Apple, Inc.
-9CF48E (base 16) Apple, Inc.
+9C-FC-01 (hex) Apple, Inc.
+9CFC01 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-FC-D8-48 (hex) Apple, Inc.
-FCD848 (base 16) Apple, Inc.
+CC-C7-60 (hex) Apple, Inc.
+CCC760 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-84-85-06 (hex) Apple, Inc.
-848506 (base 16) Apple, Inc.
+08-74-02 (hex) Apple, Inc.
+087402 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-96-7B (hex) Apple, Inc.
-68967B (base 16) Apple, Inc.
+28-5A-EB (hex) Apple, Inc.
+285AEB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-BC-67-78 (hex) Apple, Inc.
-BC6778 (base 16) Apple, Inc.
+28-F0-76 (hex) Apple, Inc.
+28F076 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A8-20-66 (hex) Apple, Inc.
-A82066 (base 16) Apple, Inc.
+3C-36-E4 (hex) ARRIS Group, Inc.
+3C36E4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-00-C5 (hex) ARRIS Group, Inc.
+0000C5 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+D0-39-B3 (hex) ARRIS Group, Inc.
+D039B3 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+8C-7F-3B (hex) ARRIS Group, Inc.
+8C7F3B (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+94-62-69 (hex) ARRIS Group, Inc.
+946269 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+D4-05-98 (hex) ARRIS Group, Inc.
+D40598 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+78-71-9C (hex) ARRIS Group, Inc.
+78719C (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+9C-FE-A1 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+9CFEA1 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+48-D3-43 (hex) ARRIS Group, Inc.
+48D343 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+D4-0A-A9 (hex) ARRIS Group, Inc.
+D40AA9 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+38-4C-90 (hex) ARRIS Group, Inc.
+384C90 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-AC-E0 (hex) ARRIS Group, Inc.
+00ACE0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+70-70-0D (hex) Apple, Inc.
+70700D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B0-65-BD (hex) Apple, Inc.
-B065BD (base 16) Apple, Inc.
+9C-F4-8E (hex) Apple, Inc.
+9CF48E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-DC-E2 (hex) Apple, Inc.
-F0DCE2 (base 16) Apple, Inc.
+FC-D8-48 (hex) Apple, Inc.
+FCD848 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-7C-D1-C3 (hex) Apple, Inc.
-7CD1C3 (base 16) Apple, Inc.
+E4-57-40 (hex) ARRIS Group, Inc.
+E45740 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+E0-22-02 (hex) ARRIS Group, Inc.
+E02202 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1C-B3 (hex) Apple, Inc.
+001CB3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-56-81 (hex) Apple, Inc.
-705681 (base 16) Apple, Inc.
+64-B9-E8 (hex) Apple, Inc.
+64B9E8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-1C-A0-B8 (hex) Hon Hai Precision Ind. Co., Ltd.
-1CA0B8 (base 16) Hon Hai Precision Ind. Co., Ltd.
- GuangDongShenZhen
- ShenZhen GuangDong 518109
- CN
+2C-1D-B8 (hex) ARRIS Group, Inc.
+2C1DB8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-E8-C1-B8 (hex) Nanjing Bangzhong Electronic Commerce Limited
-E8C1B8 (base 16) Nanjing Bangzhong Electronic Commerce Limited
- No.22, Liuzhou East Road, High - tech Zone
- Nanjing 210000
- CN
+94-9D-57 (hex) Panasonic do Brasil Limitada
+949D57 (base 16) Panasonic do Brasil Limitada
+ Rua Matrinxa
+ Manaus Amazonas 69075150
+ BR
-1C-B0-44 (hex) ASKEY COMPUTER CORP
-1CB044 (base 16) ASKEY COMPUTER CORP
- 10F,No.119,JIANKANG RD,ZHONGHE DIST
- NEW TAIPEI TAIWAN 23585
- TW
+00-50-89 (hex) SAFETY MANAGEMENT SYSTEMS
+005089 (base 16) SAFETY MANAGEMENT SYSTEMS
+ Burgemeester Burgerslaan 40
+ NH Rosmalen 5245
+ NL
-90-03-72 (hex) Longnan Junya Digital Technology Co. Ltd.
-900372 (base 16) Longnan Junya Digital Technology Co. Ltd.
- Champion Asia Road, Xinzhen industrial Park, Longnan national economic and technological development zone, Ganzhou city, JiangXi Province , China
- ganzhou jiangxi 341700
+48-DD-9D (hex) ITEL MOBILE LIMITED
+48DD9D (base 16) ITEL MOBILE LIMITED
+ RM B3 & B4 BLOCK B, KO FAI INDUSTRIAL BUILDING NO.7 KO FAI ROAD, YAU TONG, KLN, H.K
+ Hong Kong KOWLOON 999077
+ HK
+
+E4-8F-65 (hex) Yelatma Instrument Making Enterprise, JSC
+E48F65 (base 16) Yelatma Instrument Making Enterprise, JSC
+ Yanina 25
+ Yelatma Ryazan Region 391351
+ RU
+
+9C-2F-73 (hex) Universal Tiancheng Technology (Beijing) Co., Ltd.
+9C2F73 (base 16) Universal Tiancheng Technology (Beijing) Co., Ltd.
+ 13 floor,Changxin Building,Anding Road No.39,Chaoyang District,Beijing
+ Beijing Beijing 100029
CN
-F0-41-C8 (hex) IEEE Registration Authority
-F041C8 (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
+00-15-D0 (hex) ARRIS Group, Inc.
+0015D0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-A4-38-CC (hex) Nintendo Co.,Ltd
-A438CC (base 16) Nintendo Co.,Ltd
- 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
- KYOTO KYOTO 601-8501
- JP
+E8-6D-52 (hex) ARRIS Group, Inc.
+E86D52 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-94-6A-B0 (hex) Arcadyan Corporation
-946AB0 (base 16) Arcadyan Corporation
- No.8, Sec.2, Guangfu Rd.
- Hsinchu City Hsinchu 30071
- TW
+3C-43-8E (hex) ARRIS Group, Inc.
+3C438E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-B4-DE-31 (hex) Cisco Systems, Inc
-B4DE31 (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
+90-B1-34 (hex) ARRIS Group, Inc.
+90B134 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-70-16-9F (hex) EtherCAT Technology Group
-70169F (base 16) EtherCAT Technology Group
- Ostendstr. 196
- NUremberg 90482
- DE
+20-E5-64 (hex) ARRIS Group, Inc.
+20E564 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-64-98-29 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
-649829 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
- Phase 3, Bayan Lepas FIZ
- Bayan Lepas Penang 11900
- MY
+40-B7-F3 (hex) ARRIS Group, Inc.
+40B7F3 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-08-1D-C4 (hex) Thermo Fisher Scientific Messtechnik GmbH
-081DC4 (base 16) Thermo Fisher Scientific Messtechnik GmbH
- Frauenauracher Strasse 96
- Erlangen 91056
- DE
+94-CC-B9 (hex) ARRIS Group, Inc.
+94CCB9 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-68-98-61 (hex) Beacon Inc
-689861 (base 16) Beacon Inc
- 82-1, Anyangcheondong-ro, Dongan-gu
- anyang Gyeonggi-do 14042
- KR
+00-50-E3 (hex) ARRIS Group, Inc.
+0050E3 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-88-B3-62 (hex) Nokia Shanghai Bell Co. Ltd.)
-88B362 (base 16) Nokia Shanghai Bell Co. Ltd.)
- No.388 Ning Qiao Road,Jin Qiao Pudong Shanghai 201206,P.R.China
- Shanghai Pudong 201206
- CN
+EC-70-97 (hex) ARRIS Group, Inc.
+EC7097 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-10-A4-B9 (hex) Baidu Online Network Technology (Beijing) Co., Ltd
-10A4B9 (base 16) Baidu Online Network Technology (Beijing) Co., Ltd
- Baidu Campus, No.10 Shangdi 10th Street, Haidian District
- Beijing 100085
- CN
+C0-A0-0D (hex) ARRIS Group, Inc.
+C0A00D (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-34-7E-CA (hex) NEXTWILL
-347ECA (base 16) NEXTWILL
- JJ-Building, 20, Deongmyeong-ro 71beon-gil1, Yuseong-gu
- Daejeon 34155
- KR
+3C-04-61 (hex) ARRIS Group, Inc.
+3C0461 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-50-14-79 (hex) iRobot Corporation
-501479 (base 16) iRobot Corporation
- 8 Crosby Drive
- Bedford MA 01730
+88-96-4E (hex) ARRIS Group, Inc.
+88964E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-60-84-BD (hex) BUFFALO.INC
-6084BD (base 16) BUFFALO.INC
- AKAMONDORI Bld.,30-20,Ohsu 3-chome,Naka-ku
- Nagoya Aichi Pref. 460-8315
- JP
+F8-F5-32 (hex) ARRIS Group, Inc.
+F8F532 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-10-F9-EB (hex) Industria Fueguina de Relojería Electrónica s.a.
-10F9EB (base 16) Industria Fueguina de Relojería Electrónica s.a.
- Sarmiento 2920
- Rio Grande Tierra de Fuego V9420GIV
- AR
+B0-83-D6 (hex) ARRIS Group, Inc.
+B083D6 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-B8-94-36 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-B89436 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+44-AA-F5 (hex) ARRIS Group, Inc.
+44AAF5 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-F8-DF-15 (hex) Sunitec Enterprise Co.,Ltd
-F8DF15 (base 16) Sunitec Enterprise Co.,Ltd
- 3F.,No.98-1,Mincyuan Rd.Sindian City
- Taipei County 231 231141
- CN
+70-85-C6 (hex) ARRIS Group, Inc.
+7085C6 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-A8-DA-01 (hex) Shenzhen NUOLIJIA Digital Technology Co.,Ltd
-A8DA01 (base 16) Shenzhen NUOLIJIA Digital Technology Co.,Ltd
- A Area of The Second Flood and D Area of The First Floor,Factory Building A,Youxinda Industrial Park,Gengyu Road,Tianliao Community,Gongming Street Office,Guangming New District,Shenzhen City,Guangdong,P.R.China
- Shenzhen Guangdong 518000
- CN
+D0-E5-4D (hex) ARRIS Group, Inc.
+D0E54D (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-90-94-97 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-909497 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+B4-F2-E8 (hex) ARRIS Group, Inc.
+B4F2E8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-EC-89-14 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-EC8914 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+FC-8E-7E (hex) ARRIS Group, Inc.
+FC8E7E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-DC-72-9B (hex) HUAWEI TECHNOLOGIES CO.,LTD
-DC729B (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+00-50-94 (hex) ARRIS Group, Inc.
+005094 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-5C-5A-EA (hex) FORD
-5C5AEA (base 16) FORD
- 17425 Federal Drive
- Allen Park MI 48101
+E0-B7-0A (hex) ARRIS Group, Inc.
+E0B70A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-5C-AA-FD (hex) Sonos, Inc.
-5CAAFD (base 16) Sonos, Inc.
- 614 Chapala St
- Santa Barbara CA 93101
+C8-3F-B4 (hex) ARRIS Group, Inc.
+C83FB4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-00-0E-58 (hex) Sonos, Inc.
-000E58 (base 16) Sonos, Inc.
- 614 Chapala St
- Santa Barbara CA 93101
+20-73-55 (hex) ARRIS Group, Inc.
+207355 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-88-29-50 (hex) Netmoon Technology Co., Ltd
-882950 (base 16) Netmoon Technology Co., Ltd
- 2nd Floor, Building No.1, NO.319, Qingpi Avenue
- Wenjiang District Chengdu 611130
- CN
+90-0D-CB (hex) ARRIS Group, Inc.
+900DCB (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-00-21-94 (hex) Ping Communication
-002194 (base 16) Ping Communication
- Brenden 18
- Appenzell Meistersrüte AI 9050
- CH
+14-CF-E2 (hex) ARRIS Group, Inc.
+14CFE2 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-7C-FF-4D (hex) AVM Audiovisuelles Marketing und Computersysteme GmbH
-7CFF4D (base 16) AVM Audiovisuelles Marketing und Computersysteme GmbH
- Alt-Moabit 95
- Berlin Berlin 10559
- DE
+90-3E-AB (hex) ARRIS Group, Inc.
+903EAB (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-74-70-FD (hex) Intel Corporate
-7470FD (base 16) Intel Corporate
- Lot 8, Jalan Hi-Tech 2/3
- Kulim Kedah 09000
- MY
+00-21-43 (hex) ARRIS Group, Inc.
+002143 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-CC-99-16 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
-CC9916 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
- Phase 3, Bayan Lepas FIZ
- Bayan Lepas Penang 11900
- MY
+00-23-EE (hex) ARRIS Group, Inc.
+0023EE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-A4-50-55 (hex) BUSWARE.DE
-A45055 (base 16) BUSWARE.DE
- Lindenstrasse 18
- Scharbeutz 23684
- DE
+64-ED-57 (hex) ARRIS Group, Inc.
+64ED57 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-00-13-86 (hex) ABB Inc/Totalflow
-001386 (base 16) ABB Inc/Totalflow
-
- Bartlesville OK 74006
+00-23-A3 (hex) ARRIS Group, Inc.
+0023A3 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-A0-66-10 (hex) FUJITSU LIMITED
-A06610 (base 16) FUJITSU LIMITED
- Mushashi-kosuge Tower Place 13F
- Kawasaki Kanagawa 211-0063
- JP
+F8-7B-7A (hex) ARRIS Group, Inc.
+F87B7A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-64-CB-5D (hex) SIA TeleSet
-64CB5D (base 16) SIA TeleSet
- Krāslavas iela 5
- Vecstropi, Naujenes par., Daugavpils distr. LV-5413
- LV
+00-25-F1 (hex) ARRIS Group, Inc.
+0025F1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-70-69-5A (hex) Cisco Systems, Inc
-70695A (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
+00-1A-66 (hex) ARRIS Group, Inc.
+001A66 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-58-21-E9 (hex) TWPI
-5821E9 (base 16) TWPI
- PMB# 335; 1121 Annapolis Road
- Odenton MD 21113
+00-18-C0 (hex) ARRIS Group, Inc.
+0018C0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-68-D4-82 (hex) SHENZHEN GONGJIN ELECTRONICS CO.,LT
-68D482 (base 16) SHENZHEN GONGJIN ELECTRONICS CO.,LT
- SONGGANG
- SHENZHEN GUANGDONG 518105
- CN
+00-1E-46 (hex) ARRIS Group, Inc.
+001E46 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-30-1F-9A (hex) IEEE Registration Authority
-301F9A (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
+00-1A-DE (hex) ARRIS Group, Inc.
+001ADE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-90-79-10 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
-907910 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
- Phase 3, Bayan Lepas FIZ
- Bayan Lepas Penang 11900
- MY
+00-23-AF (hex) ARRIS Group, Inc.
+0023AF (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-00-A0-D5 (hex) Sierra Wireless Inc
-00A0D5 (base 16) Sierra Wireless Inc
- 13811 Wireless Way
- RICHMOND B.C. V6V 3A4
- CA
+CC-A4-62 (hex) ARRIS Group, Inc.
+CCA462 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1D-CD (hex) ARRIS Group, Inc.
+001DCD (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1D-D4 (hex) ARRIS Group, Inc.
+001DD4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1D-CE (hex) ARRIS Group, Inc.
+001DCE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-08-0E (hex) ARRIS Group, Inc.
+00080E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-15-9A (hex) ARRIS Group, Inc.
+00159A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-19-2C (hex) ARRIS Group, Inc.
+00192C (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+58-56-E8 (hex) ARRIS Group, Inc.
+5856E8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+50-50-CE (hex) Hangzhou Dianyixia Communication Technology Co. Ltd.
+5050CE (base 16) Hangzhou Dianyixia Communication Technology Co. Ltd.
+ Room 207, Building 7, 1197 bin 'an road, Binjiang district,
+ Hangzhou Zhejiang 310011
+ CN
+
+50-A0-09 (hex) Xiaomi Communications Co Ltd
+50A009 (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+2C-28-B7 (hex) Hangzhou Ruiying technology co., LTD
+2C28B7 (base 16) Hangzhou Ruiying technology co., LTD
+ No. 1, building 305, Yunqi Town Cloud Computing Industrial Park, Hangzhou City, Xihu District
+ Hangzhou Zhejiang 310000
+ CN
+
+9C-E8-2B (hex) vivo Mobile Communication Co., Ltd.
+9CE82B (base 16) vivo Mobile Communication Co., Ltd.
+ #283,BBK Road
+ Wusha,Chang'An DongGuan City,Guangdong, 523860
+ CN
+
+00-22-18 (hex) AKAMAI TECHNOLOGIES INC
+002218 (base 16) AKAMAI TECHNOLOGIES INC
+ 150 BROADWAY
+ CAMBRIDGE MA 02142
+ US
0C-6F-9C (hex) Shaw Communications Inc.
0C6F9C (base 16) Shaw Communications Inc.
@@ -30779,12 +31043,6 @@ C43ABE (base 16) Sony Mobile Communications AB shenzhen guangdong 518057
CN
-C8-D7-79 (hex) Qingdao Haier Telecom Co.,Ltd
-C8D779 (base 16) Qingdao Haier Telecom Co.,Ltd
- No 1 Haier road,Hi-tech Zone,Qingdao,PR.China
- Qingdao Shandong 266101
- CN
-
2C-A2-B4 (hex) Fortify Technologies, LLC
2CA2B4 (base 16) Fortify Technologies, LLC
6200 Shingle Creek Pkwy, Suite 400
@@ -31952,12 +32210,6 @@ FCFE77 (base 16) Hitachi Reftechno, Inc. Egham Surrey TW208RN
GB
-14-B1-26 (hex) Industrial Software Co
-14B126 (base 16) Industrial Software Co
- 91, Aleksandyr Malinov blvd.
- Sofia 1715
- BG
-
C0-35-80 (hex) A&R TECH
C03580 (base 16) A&R TECH
Marksteinergasse 13
@@ -40682,12 +40934,6 @@ D0D286 (base 16) Beckman Coulter K.K. Taipei 114
TW
-00-16-5C (hex) Trackflow Ltd
-00165C (base 16) Trackflow Ltd
- 167-169 Kensington High Street
- London England W86SH
- GB
-
00-16-55 (hex) FUHO TECHNOLOGY Co., LTD
001655 (base 16) FUHO TECHNOLOGY Co., LTD
No. 30, Lane 726, Jinma Rd, Sec. 3
@@ -48359,12 +48605,6 @@ D0D286 (base 16) Beckman Coulter K.K. SEATTLE WA 98168
US
-00-E0-09 (hex) MARATHON TECHNOLOGIES CORP.
-00E009 (base 16) MARATHON TECHNOLOGIES CORP.
- 1300 MASSACHUSETTS AVENUE
- BOXBOROUGH MA 01719
- US
-
00-E0-2F (hex) MCNS HOLDINGS, L.P.
00E02F (base 16) MCNS HOLDINGS, L.P.
TCI, INC.-TECHNOLOGY VENTURES
@@ -54533,6 +54773,1125 @@ D825B0 (base 16) Rockeetech Systems Co.,Ltd. Chongqing Chongqing City 401120
CN
+F4-6E-24 (hex) NEC Personal Computers, Ltd.
+F46E24 (base 16) NEC Personal Computers, Ltd.
+ Akihabara UDX,14-1, Sotokanda 4-Chome
+ Chiyoda-ku Tokyo 101-0021
+ JP
+
+88-82-79 (hex) Shenzhen RB-LINK Intelligent Technology Co.Ltd
+888279 (base 16) Shenzhen RB-LINK Intelligent Technology Co.Ltd
+ Second floor, No 22, Wanfeng the third industry area, Shajing , BaoAn district
+ Shenzhen City 518125
+ CN
+
+78-32-1B (hex) D-Link International
+78321B (base 16) D-Link International
+ 1 Internal Business Park, #03-12,The Synergy, Singapore
+ Singapore Singapore 609917
+ SG
+
+EC-51-BC (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+EC51BC (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+F0-79-E8 (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+F079E8 (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+D8-A5-34 (hex) Spectronix Corporation
+D8A534 (base 16) Spectronix Corporation
+ 3-28-15, Tarumi-cho
+ Suita-city Osaka 564-0062
+ JP
+
+58-38-79 (hex) RICOH COMPANY, LTD.
+583879 (base 16) RICOH COMPANY, LTD.
+ 1005, Shimo-ogino
+ Atsugi-City Kanagawa-Pref. 243-0298
+ JP
+
+94-28-2E (hex) New H3C Technologies Co., Ltd
+94282E (base 16) New H3C Technologies Co., Ltd
+ 466 Changhe Road, Binjiang District
+ Hangzhou Zhejiang 310052
+ CN
+
+D8-43-ED (hex) Suzuken
+D843ED (base 16) Suzuken
+ 8, Higashikatahamachi, Higashiku
+ Nagoya Aich 4610015
+ JP
+
+88-75-98 (hex) Samsung Electronics Co.,Ltd
+887598 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+D0-B1-28 (hex) Samsung Electronics Co.,Ltd
+D0B128 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+FC-EE-E6 (hex) FORMIKE ELECTRONIC CO., LTD
+FCEEE6 (base 16) FORMIKE ELECTRONIC CO., LTD
+ Flats 401-403, Block B, iPARK Building, 26 Dengliang Rd., NanShan Distric
+ Shenzhen Guang Dong 518054
+ CN
+
+2C-43-1A (hex) Shenzhen YOUHUA Technology Co., Ltd
+2C431A (base 16) Shenzhen YOUHUA Technology Co., Ltd
+ Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
+ Shenzhen Guangdong 518055
+ CN
+
+A8-D3-C8 (hex) Topcon Electronics GmbH & Co. KG
+A8D3C8 (base 16) Topcon Electronics GmbH & Co. KG
+ Industriestraße 7
+ Geisenheim 65366
+ DE
+
+38-9F-5A (hex) C-Kur TV Inc.
+389F5A (base 16) C-Kur TV Inc.
+ A-1902, 583, Yangcheon-ro, Gangseo-gu
+ Seoul 07547
+ KR
+
+24-B2-09 (hex) Avaya Inc
+24B209 (base 16) Avaya Inc
+ 360 Mt Kemble Ave
+ Morristown NJ 07960
+ US
+
+24-E1-24 (hex) Xiamen Ursaconn Technology Co. , Ltd.
+24E124 (base 16) Xiamen Ursaconn Technology Co. , Ltd.
+ 3/F, No. 46 Guanri Road, 2nd Software Park
+ Xiamen Fujian 361008
+ CN
+
+DC-68-EB (hex) Nintendo Co.,Ltd
+DC68EB (base 16) Nintendo Co.,Ltd
+ 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
+ KYOTO KYOTO 601-8501
+ JP
+
+94-41-C1 (hex) Mini-Cam Limited
+9441C1 (base 16) Mini-Cam Limited
+ Unit 4 Yew Tree Way
+ Warrington Cheshire WA33JD
+ GB
+
+E8-D8-19 (hex) AzureWave Technology Inc.
+E8D819 (base 16) AzureWave Technology Inc.
+ 8F., No. 94, Baozhong Rd.
+ New Taipei City Taiwan 231
+ TW
+
+AC-1D-DF (hex) IEEE Registration Authority
+AC1DDF (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+00-08-FA (hex) KEB Automation KG
+0008FA (base 16) KEB Automation KG
+ Südstraße 38
+ Barntrup NRW D-32683
+ DE
+
+18-39-6E (hex) SUNSEA TELECOMMUNICATIONS CO.,LTD.
+18396E (base 16) SUNSEA TELECOMMUNICATIONS CO.,LTD.
+ High tech Industrial Park,Longhua District of Shenzhen City,South central concept
+ Shenzhen 518110
+ CN
+
+E8-DF-70 (hex) AVM Audiovisuelles Marketing und Computersysteme GmbH
+E8DF70 (base 16) AVM Audiovisuelles Marketing und Computersysteme GmbH
+ Alt-Moabit 95
+ Berlin Berlin 10559
+ DE
+
+7C-DD-76 (hex) Suzhou Hanming Technologies Co., Ltd.
+7CDD76 (base 16) Suzhou Hanming Technologies Co., Ltd.
+ Suite 407, No. 166, Ren Ai Road
+ Suzhou Jiangsu 215123
+ CN
+
+24-68-80 (hex) Braveridge.co.,ltd.
+246880 (base 16) Braveridge.co.,ltd.
+ 3-27-2, Susenji
+ Nishi-ku, Fukuoka-shi Fukuoka 819-0373
+ JP
+
+D0-04-01 (hex) Motorola Mobility LLC, a Lenovo Company
+D00401 (base 16) Motorola Mobility LLC, a Lenovo Company
+ 222 West Merchandise Mart Plaza
+ Chicago IL 60654
+ US
+
+58-90-43 (hex) Sagemcom Broadband SAS
+589043 (base 16) Sagemcom Broadband SAS
+ 250, route de l'Empereur
+ Rueil Malmaison Cedex hauts de seine 92848
+ FR
+
+28-CF-08 (hex) ESSYS
+28CF08 (base 16) ESSYS
+ gaetbeol-ro
+ Incheon 21999
+ KR
+
+70-7D-B9 (hex) Cisco Systems, Inc
+707DB9 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+34-6F-ED (hex) Enovation Controls
+346FED (base 16) Enovation Controls
+ 5311 S. 122nd E. Ave.
+ Tulsa OK 74146
+ US
+
+00-00-B4 (hex) Edimax Technology Co. Ltd.
+0000B4 (base 16) Edimax Technology Co. Ltd.
+ No. 278, Xinhu 1st Road
+ Taipei City Neihu Dist 248
+ TW
+
+08-BE-AC (hex) Edimax Technology Co. Ltd.
+08BEAC (base 16) Edimax Technology Co. Ltd.
+ No. 278, Xinhu 1st Road
+ Taipei City Neihu Dist 248
+ TW
+
+F0-6D-78 (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+F06D78 (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+78-44-FD (hex) TP-LINK TECHNOLOGIES CO.,LTD.
+7844FD (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
+ Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
+ Shenzhen Guangdong 518057
+ CN
+
+50-3E-AA (hex) TP-LINK TECHNOLOGIES CO.,LTD.
+503EAA (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
+ Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
+ Shenzhen Guangdong 518057
+ CN
+
+AC-84-C6 (hex) TP-LINK TECHNOLOGIES CO.,LTD.
+AC84C6 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
+ Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
+ Shenzhen Guangdong 518057
+ CN
+
+34-D0-B8 (hex) IEEE Registration Authority
+34D0B8 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+B0-C1-9E (hex) zte corporation
+B0C19E (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+0C-37-47 (hex) zte corporation
+0C3747 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+00-00-97 (hex) Dell EMC
+000097 (base 16) Dell EMC
+ 176 South Street
+ Hopkinton MA 01748
+ US
+
+EC-C0-6A (hex) PowerChord Group Limited
+ECC06A (base 16) PowerChord Group Limited
+ 1 Blythe Road
+ London W14 0HG
+ GB
+
+38-D7-CA (hex) 7HUGS LABS
+38D7CA (base 16) 7HUGS LABS
+ 29 bd Romain Rolland
+ Montrouge 92120
+ FR
+
+6C-05-D5 (hex) Ethertronics Inc
+6C05D5 (base 16) Ethertronics Inc
+ 5501 Oberlin Drive, Suite 100
+ SAN DIEGO CA 92121
+ US
+
+00-1D-F4 (hex) Magellan Technology Pty Limited
+001DF4 (base 16) Magellan Technology Pty Limited
+ 65 Johnston Street
+ Annandale NSW 2000
+ AU
+
+C0-22-50 (hex) Private
+C02250 (base 16) Private
+
+00-94-A1 (hex) F5 Networks, Inc.
+0094A1 (base 16) F5 Networks, Inc.
+ 401 Elliott Ave. W.
+ Seattle WA 98119
+ US
+
+18-90-D8 (hex) Sagemcom Broadband SAS
+1890D8 (base 16) Sagemcom Broadband SAS
+ 250, route de l'Empereur
+ Rueil Malmaison Cedex hauts de seine 92848
+ FR
+
+88-83-5D (hex) FN-LINK TECHNOLOGY LIMITED
+88835D (base 16) FN-LINK TECHNOLOGY LIMITED
+ No.8, Litong Road, Liuyang Economic & Technical Development Zone
+ ChangSha Hu Nan 410300
+ CN
+
+10-68-3F (hex) LG Electronics (Mobile Communications)
+10683F (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+74-A7-22 (hex) LG Electronics (Mobile Communications)
+74A722 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+58-A2-B5 (hex) LG Electronics (Mobile Communications)
+58A2B5 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+64-89-9A (hex) LG Electronics (Mobile Communications)
+64899A (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+88-07-4B (hex) LG Electronics (Mobile Communications)
+88074B (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+64-BC-0C (hex) LG Electronics (Mobile Communications)
+64BC0C (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+A0-39-F7 (hex) LG Electronics (Mobile Communications)
+A039F7 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+04-1B-6D (hex) LG Electronics (Mobile Communications)
+041B6D (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+00-1F-6B (hex) LG Electronics (Mobile Communications)
+001F6B (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+D0-07-CA (hex) Juniper Networks
+D007CA (base 16) Juniper Networks
+ 1133 Innovation Way
+ Sunnyvale CA 94089
+ US
+
+F8-6C-E1 (hex) Taicang T&W Electronics
+F86CE1 (base 16) Taicang T&W Electronics
+ 89# Jiang Nan RD
+ Suzhou Jiangsu 215412
+ CN
+
+1C-73-28 (hex) Connected Home
+1C7328 (base 16) Connected Home
+ 19-22, Rathbone Place
+ London W1T 1HY
+ GB
+
+40-A9-3F (hex) Private
+40A93F (base 16) Private
+
+5C-77-76 (hex) TCT mobile ltd
+5C7776 (base 16) TCT mobile ltd
+ No.86 hechang 7th road, zhongkai, Hi-Tech District
+ Hui Zhou Guang Dong 516006
+ CN
+
+EC-1D-8B (hex) Cisco Systems, Inc
+EC1D8B (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+38-F7-3D (hex) Amazon Technologies Inc.
+38F73D (base 16) Amazon Technologies Inc.
+ P.O Box 8102
+ Reno NV 89507
+ US
+
+30-B4-B8 (hex) LG Electronics
+30B4B8 (base 16) LG Electronics
+ 222 LG-ro, JINWI-MYEON
+ Pyeongtaek-si Gyeonggi-do 451-713
+ KR
+
+2C-FD-AB (hex) Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.
+2CFDAB (base 16) Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.
+ No.19, Gaoxin 4th Road, Wuhan East Lake High-tech Zone, Wuhan
+ Wuhan Hubei 430000
+ CN
+
+F4-1E-5E (hex) RtBrick Inc.
+F41E5E (base 16) RtBrick Inc.
+ 26 Kingston Terrace
+ Princeton NJ 08540
+ US
+
+18-06-FF (hex) Acer Computer(Shanghai) Limited.
+1806FF (base 16) Acer Computer(Shanghai) Limited.
+ Room1806-20, No.769, Jiujiang Road, Huangpu District
+ Shanghai 200000
+ CN
+
+B8-EC-A3 (hex) Zyxel Communications Corporation
+B8ECA3 (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+EC-43-F6 (hex) Zyxel Communications Corporation
+EC43F6 (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+58-8B-F3 (hex) Zyxel Communications Corporation
+588BF3 (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+FC-F5-28 (hex) Zyxel Communications Corporation
+FCF528 (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+00-19-CB (hex) Zyxel Communications Corporation
+0019CB (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+60-31-97 (hex) Zyxel Communications Corporation
+603197 (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+34-FA-9F (hex) Ruckus Wireless
+34FA9F (base 16) Ruckus Wireless
+ 350 West Java Drive
+ Sunnyvale CA 94089
+ US
+
+50-6F-98 (hex) Sehaj Synergy Technologies Private Limited
+506F98 (base 16) Sehaj Synergy Technologies Private Limited
+ E-112A, Kataria Colony, Ramanagar Extension, New Sanganer Road, Sodala, Jaipur-302019
+ Jaipur Rajasthan 302019
+ IN
+
+04-F1-28 (hex) HMD Global Oy
+04F128 (base 16) HMD Global Oy
+ Karaportti 2
+ Espoo 02610
+ FI
+
+F0-65-C2 (hex) Yanfeng Visteon Electronics Technology (Shanghai) Co.,Ltd.
+F065C2 (base 16) Yanfeng Visteon Electronics Technology (Shanghai) Co.,Ltd.
+ 1001 North Qin Zhou Road
+ Shang Hai 200233
+ CN
+
+70-B7-E2 (hex) Jiangsu Miter Technology Co.,Ltd.
+70B7E2 (base 16) Jiangsu Miter Technology Co.,Ltd.
+ No.86 fuyuan community,the town of houbei
+ Jurong Jiangsu 212400
+ CN
+
+50-3C-EA (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+503CEA (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+00-04-CF (hex) Seagate Technology
+0004CF (base 16) Seagate Technology
+ M/S NW1F01
+ Longmont CO 80503
+ US
+
+00-14-C3 (hex) Seagate Technology
+0014C3 (base 16) Seagate Technology
+ M/S NW1F01
+ Longmont CO 80503
+ US
+
+00-20-37 (hex) Seagate Technology
+002037 (base 16) Seagate Technology
+ 8001 E. BLOOMINGTON FWY
+ BLOOMINGTON MN 55420
+ US
+
+00-50-CC (hex) Seagate Cloud Systems Inc
+0050CC (base 16) Seagate Cloud Systems Inc
+ 1351 S Sunset Street
+ Longmont CO 80501
+ US
+
+1C-27-DD (hex) Datang Gohighsec(zhejiang)Information Technology Co.,Ltd.
+1C27DD (base 16) Datang Gohighsec(zhejiang)Information Technology Co.,Ltd.
+ Beiwu Innovation park, #23 Beiwu Villiage Road
+ Beijing Beijing 100000
+ CN
+
+00-72-63 (hex) Netcore Technology Inc.
+007263 (base 16) Netcore Technology Inc.
+ ORIENTAL CYBERPORT,HIGHTECH 6 ROAD
+ Shenzhen 518057
+ CN
+
+48-55-5C (hex) Wu Qi Technologies,Inc.
+48555C (base 16) Wu Qi Technologies,Inc.
+ Xiantao street data on the 19th East Road
+ Chongqing City Yubei District 401120
+ CN
+
+70-EE-A3 (hex) Eoptolink Technology Inc. Ltd,
+70EEA3 (base 16) Eoptolink Technology Inc. Ltd,
+ No.127 West Wulian Street
+ Chengdu China/Sichuan 610213
+ CN
+
+5C-58-19 (hex) Jingsheng Technology Co., Ltd.
+5C5819 (base 16) Jingsheng Technology Co., Ltd.
+ Linyin street 5#
+ chengdu sichuan 610000
+ CN
+
+74-7D-24 (hex) Phicomm (Shanghai) Co., Ltd.
+747D24 (base 16) Phicomm (Shanghai) Co., Ltd.
+ 3666 SiXian Rd.,Songjiang District
+ Shanghai Shanghai 201616
+ CN
+
+5C-81-A7 (hex) Network Devices Pty Ltd
+5C81A7 (base 16) Network Devices Pty Ltd
+ 16 Dickson Ave
+ Artarmon NSW 2064
+ AU
+
+80-8D-B7 (hex) Hewlett Packard Enterprise
+808DB7 (base 16) Hewlett Packard Enterprise
+ 8000 Foothills Blvd.
+ Roseville CA 95747
+ US
+
+10-CE-A9 (hex) Texas Instruments
+10CEA9 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+F8-B5-68 (hex) IEEE Registration Authority
+F8B568 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+14-44-4A (hex) Apollo Seiko Ltd.
+14444A (base 16) Apollo Seiko Ltd.
+ 2271-7 Jinba
+ Gotenba Shizuoka 412-0047
+ JP
+
+5C-0C-0E (hex) Guizhou Huaxintong Semiconductor Technology Co Ltd
+5C0C0E (base 16) Guizhou Huaxintong Semiconductor Technology Co Ltd
+ Sitelin Park
+ Intersection between Jin ma Ave and Qianzhong Ave Gui An New Area, Guizhou Prov 550003
+ CN
+
+2C-FD-A1 (hex) ASUSTek COMPUTER INC.
+2CFDA1 (base 16) ASUSTek COMPUTER INC.
+ 15,Li-Te Rd., Peitou, Taipei 112, Taiwan
+ Taipei Taiwan 112
+ TW
+
+38-07-D4 (hex) Zeppelin Systems GmbH
+3807D4 (base 16) Zeppelin Systems GmbH
+ Messenhäuser Str. 37-45
+ Rödermark Hessen 63322
+ DE
+
+64-20-9F (hex) Tilgin AB
+64209F (base 16) Tilgin AB
+ Finlandsgatan 40
+ Kista 16474
+ SE
+
+04-E0-B0 (hex) Shenzhen YOUHUA Technology Co., Ltd
+04E0B0 (base 16) Shenzhen YOUHUA Technology Co., Ltd
+ Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
+ Shenzhen Guangdong 518055
+ CN
+
+0C-98-38 (hex) Xiaomi Communications Co Ltd
+0C9838 (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+00-04-96 (hex) Extreme Networks, Inc.
+000496 (base 16) Extreme Networks, Inc.
+ 3585 Monroe Street
+ Santa Clara CA 95051
+ US
+
+B8-50-01 (hex) Extreme Networks, Inc.
+B85001 (base 16) Extreme Networks, Inc.
+ ONE ZEBRA PLAZA
+ HOLTSVILLE NY 11742
+ US
+
+7C-76-30 (hex) Shenzhen YOUHUA Technology Co., Ltd
+7C7630 (base 16) Shenzhen YOUHUA Technology Co., Ltd
+ Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
+ Shenzhen Guangdong 518055
+ CN
+
+98-22-EF (hex) Liteon Technology Corporation
+9822EF (base 16) Liteon Technology Corporation
+ 4F, 90, Chien 1 Road
+ New Taipei City Taiwan 23585
+ TW
+
+58-04-54 (hex) ICOMM HK LIMITED
+580454 (base 16) ICOMM HK LIMITED
+ SUITES 2302-6, 23/F GREAT EAGLE CTR 23 HARBOUR RD
+ WANCHAI NA
+ HK
+
+A0-BD-CD (hex) BSkyB Ltd
+A0BDCD (base 16) BSkyB Ltd
+ 130 Kings Road
+ Brentwood Essex 08854
+ GB
+
+80-3A-59 (hex) AT&T
+803A59 (base 16) AT&T
+ 1025 Lenox Park Blvd
+ Atlanta GA 30319
+ US
+
+60-6D-3C (hex) Luxshare Precision Industry Company Limited
+606D3C (base 16) Luxshare Precision Industry Company Limited
+ Floor 2, Block A, Sanyo New Industrial Area
+ West Haoyi Community, Shajing Subdistrict Office Bao'an District, Shenzhen, Guangdong 523000
+ CN
+
+CC-4D-38 (hex) Carnegie Technologies
+CC4D38 (base 16) Carnegie Technologies
+ 9737 Great Hills Trail #260
+ Austin TX 78759
+ US
+
+54-FC-F0 (hex) Samsung Electronics Co.,Ltd
+54FCF0 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+08-AE-D6 (hex) Samsung Electronics Co.,Ltd
+08AED6 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+B0-67-2F (hex) Bowers & Wilkins
+B0672F (base 16) Bowers & Wilkins
+ 900 Middlefield Rd Floor 4
+ Redwood City CA 94063
+ US
+
+A8-16-D0 (hex) Samsung Electronics Co.,Ltd
+A816D0 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+88-BD-45 (hex) Samsung Electronics Co.,Ltd
+88BD45 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+74-C9-A3 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+74C9A3 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+A8-E7-05 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+A8E705 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+CC-50-0A (hex) Fiberhome Telecommunication Technologies Co.,LTD
+CC500A (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+60-B6-17 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+60B617 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan City Hubei Province 430074
+ CN
+
+18-A3-E8 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+18A3E8 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan City Hubei Province 430074
+ CN
+
+74-1E-93 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+741E93 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan City Hubei Province 430074
+ CN
+
+20-89-6F (hex) Fiberhome Telecommunication Technologies Co.,LTD
+20896F (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+A0-13-CB (hex) Fiberhome Telecommunication Technologies Co.,LTD
+A013CB (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+3C-FB-5C (hex) Fiberhome Telecommunication Technologies Co.,LTD
+3CFB5C (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+CC-3A-DF (hex) Neptune Technology Group Inc.
+CC3ADF (base 16) Neptune Technology Group Inc.
+ 1600 AL Highway 229 S
+ Tallassee AL 36078
+ US
+
+28-ED-E0 (hex) AMPAK Technology, Inc.
+28EDE0 (base 16) AMPAK Technology, Inc.
+ No.1,Jen Ai Road Hsinchu Industrial Park, Hukou
+ Hsinchu Taiwan ROC. 30352
+ TW
+
+04-09-73 (hex) Hewlett Packard Enterprise
+040973 (base 16) Hewlett Packard Enterprise
+ 8000 Foothills Blvd.
+ Roseville CA 95747
+ US
+
+70-F2-20 (hex) Actiontec Electronics, Inc
+70F220 (base 16) Actiontec Electronics, Inc
+ 760 North Mary Ave
+ Sunnyvale CA 94085
+ US
+
+4C-C2-06 (hex) Somfy
+4CC206 (base 16) Somfy
+ 50 avenue du nouveau monde
+ Cluses 74300
+ FR
+
+50-DC-E7 (hex) Amazon Technologies Inc.
+50DCE7 (base 16) Amazon Technologies Inc.
+ P.O Box 8102
+ Reno NV 89507
+ US
+
+04-C9-D9 (hex) Dish Technologies Corp
+04C9D9 (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+00-24-AF (hex) Dish Technologies Corp
+0024AF (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+28-57-67 (hex) Dish Technologies Corp
+285767 (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+70-55-F8 (hex) Cerebras Systems Inc
+7055F8 (base 16) Cerebras Systems Inc
+ 175 S San Antonio Rd #100
+ Los Altos CA 94022
+ US
+
+9C-43-1E (hex) IEEE Registration Authority
+9C431E (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+6C-54-CD (hex) LAMPEX ELECTRONICS LIMITED
+6C54CD (base 16) LAMPEX ELECTRONICS LIMITED
+ 6-2/231/B, Kukatpally,
+ Hyderabad Telangana 500072
+ IN
+
+80-C5-48 (hex) Shenzhen Zowee Technology Co.,Ltd
+80C548 (base 16) Shenzhen Zowee Technology Co.,Ltd
+ NO.5 Zowee technology building, Science & Technology industrial park of privately Science & Technology industrial park of privately owned enterprises
+ Shenzhen GuangDong 518055
+ CN
+
+88-3D-24 (hex) Google, Inc.
+883D24 (base 16) Google, Inc.
+ 1600 Amphitheatre Parkway
+ Mountain View CA 94043
+ US
+
+90-84-8B (hex) HDR10+ Technologies, LLC
+90848B (base 16) HDR10+ Technologies, LLC
+ 3855 SW 153rd Drive
+ Beaverton OR 97006
+ US
+
+0C-23-69 (hex) Honeywell SPS
+0C2369 (base 16) Honeywell SPS
+ 700 Visions Dr.
+ Skaneateles Falls NY 13153
+ US
+
+E8-DE-FB (hex) MESOTIC SAS
+E8DEFB (base 16) MESOTIC SAS
+ 11, Avenue de la Division Leclerc
+ Cachan 94230
+ FR
+
+8C-16-45 (hex) LCFC(HeFei) Electronics Technology co., ltd
+8C1645 (base 16) LCFC(HeFei) Electronics Technology co., ltd
+ YunGu Road 3188-1
+ Hefei Anhui 230000
+ CN
+
+B4-E9-A3 (hex) port GmbH
+B4E9A3 (base 16) port GmbH
+ Regensburger Str. 7b
+ Halle (S.) 06132
+ DE
+
+6C-B6-CA (hex) DIVUS GmbH
+6CB6CA (base 16) DIVUS GmbH
+ Pillhof 51
+ Eppan 39057
+ IT
+
+B8-DE-5E (hex) LONGCHEER TELECOMMUNICATION LIMITED
+B8DE5E (base 16) LONGCHEER TELECOMMUNICATION LIMITED
+ Building 1,No.401,Caobao Rd
+ Shanghai Xuhui District 200233
+ CN
+
+DC-DD-24 (hex) Energica Motor Company SpA
+DCDD24 (base 16) Energica Motor Company SpA
+ Via Cesare della Chiesa, 150
+ MODENA (MO) Mo 41126
+ IT
+
+64-1C-B0 (hex) Samsung Electronics Co.,Ltd
+641CB0 (base 16) Samsung Electronics Co.,Ltd
+ 129, Samsung-ro, Youngtongl-Gu
+ Suwon Gyeonggi-Do 16677
+ KR
+
+94-63-72 (hex) vivo Mobile Communication Co., Ltd.
+946372 (base 16) vivo Mobile Communication Co., Ltd.
+ #283,BBK Road
+ Wusha,Chang'An DongGuan City,Guangdong, 523860
+ CN
+
+44-9E-F9 (hex) vivo Mobile Communication Co., Ltd.
+449EF9 (base 16) vivo Mobile Communication Co., Ltd.
+ #283,BBK Road
+ Wusha,Chang'An DongGuan City,Guangdong, 523860
+ CN
+
+8C-F9-57 (hex) RuiXingHengFang Network (Shenzhen) Co.,Ltd
+8CF957 (base 16) RuiXingHengFang Network (Shenzhen) Co.,Ltd
+ Room 507, 2nd tower of KangTai biological building NO.6 KeFa Rd. NanShan District
+ Shenzhen Guangdong 518057
+ CN
+
+00-1B-D8 (hex) FLIR Systems Inc
+001BD8 (base 16) FLIR Systems Inc
+ 65 Challenger Road
+ Ridgefield Park NJ 07660-2103
+ US
+
+20-36-5B (hex) Megafone Limited
+20365B (base 16) Megafone Limited
+ Unit 702,7/F,Bankok Bank Building,NO.18 Bonham Strand West
+ Hong Kong 999077
+ HK
+
+E8-DE-00 (hex) ChongQing GuanFang Technology Co.,LTD
+E8DE00 (base 16) ChongQing GuanFang Technology Co.,LTD
+ 2F, A District,No.3 Middle Section of Mount Huangshan Avenue
+ ChongQing ChongQing 401121
+ CN
+
+3C-DC-BC (hex) Samsung Electronics Co.,Ltd
+3CDCBC (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+F4-71-90 (hex) Samsung Electronics Co.,Ltd
+F47190 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+4C-77-6D (hex) Cisco Systems, Inc
+4C776D (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+FC-A6-CD (hex) Fiberhome Telecommunication Technologies Co.,LTD
+FCA6CD (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+64-DB-8B (hex) Hangzhou Hikvision Digital Technology Co.,Ltd.
+64DB8B (base 16) Hangzhou Hikvision Digital Technology Co.,Ltd.
+ No.555 Qianmo Road
+ Hangzhou Zhejiang 310052
+ CN
+
+78-25-7A (hex) LEO Innovation Lab
+78257A (base 16) LEO Innovation Lab
+ Silkegade 8
+ Copenhagen K Denmark 1113
+ DK
+
+A4-DA-22 (hex) IEEE Registration Authority
+A4DA22 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+00-03-97 (hex) FireBrick Limited
+000397 (base 16) FireBrick Limited
+ C/O Andrews & Arnold Ltd,
+ Enterprise Court, Downmill Road Bracknell, Berks RG12 1QS
+ GB
+
+A8-61-0A (hex) ARDUINO AG
+A8610A (base 16) ARDUINO AG
+ Corso San Gottardo 6A
+ Chiasso 6830
+ CH
+
+60-97-DD (hex) MicroSys Electronics GmbH
+6097DD (base 16) MicroSys Electronics GmbH
+ Muehlweg 1
+ Sauerlach 82054
+ DE
+
+04-79-70 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+047970 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+C4-9F-4C (hex) HUAWEI TECHNOLOGIES CO.,LTD
+C49F4C (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+A0-57-E3 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+A057E3 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+E0-E6-2E (hex) TCT mobile ltd
+E0E62E (base 16) TCT mobile ltd
+ No.86 hechang 7th road, zhongkai, Hi-Tech District
+ Hui Zhou Guang Dong 516006
+ CN
+
+00-A0-85 (hex) Private
+00A085 (base 16) Private
+
+94-B8-6D (hex) Intel Corporate
+94B86D (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+58-7A-6A (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+587A6A (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+E4-C4-83 (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+E4C483 (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+30-FD-38 (hex) Google, Inc.
+30FD38 (base 16) Google, Inc.
+ 1600 Amphitheatre Parkway
+ Mountain View CA 94043
+ US
+
+18-50-2A (hex) SOARNEX
+18502A (base 16) SOARNEX
+ NO.158, RUIHU ST., NEIHU DIST.,
+ TAIPEI CITY TAIWAN (R.O.C.) 11494
+ TW
+
+30-45-11 (hex) Texas Instruments
+304511 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+34-03-DE (hex) Texas Instruments
+3403DE (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+F4-E1-1E (hex) Texas Instruments
+F4E11E (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+10-E7-C6 (hex) Hewlett Packard
+10E7C6 (base 16) Hewlett Packard
+ 11445 Compaq Center Drive
+ Houston TX 77070
+ US
+
+20-F5-43 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+20F543 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+1C-1E-E3 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+1C1EE3 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+0C-91-60 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+0C9160 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+0C-62-A6 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+0C62A6 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+7C-49-EB (hex) XIAOMI Electronics,CO.,LTD
+7C49EB (base 16) XIAOMI Electronics,CO.,LTD
+ Xiaomi Building, No.68 Qinghe Middle Street,Haidian District
+ Beijing Beijing 100085
+ CN
+
+C4-33-06 (hex) China Mobile Group Device Co.,Ltd.
+C43306 (base 16) China Mobile Group Device Co.,Ltd.
+ 32 Xuanwumen West Street,Xicheng District
+ Beijing 100053
+ CN
+
+68-FE-DA (hex) Fiberhome Telecommunication Technologies Co.,LTD
+68FEDA (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+0C-6A-BC (hex) Fiberhome Telecommunication Technologies Co.,LTD
+0C6ABC (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+00-01-B9 (hex) SKF (U.K.) Limited
+0001B9 (base 16) SKF (U.K.) Limited
+ 2 Michaelson Square Kirkton Campus
+ Livingston West Lothian EH54 7DP
+ GB
+
+64-C3-D6 (hex) Juniper Networks
+64C3D6 (base 16) Juniper Networks
+ 1133 Innovation Way
+ Sunnyvale CA 94089
+ US
+
C0-D9-F7 (hex) ShanDong Domor Intelligent S&T CO.,Ltd
C0D9F7 (base 16) ShanDong Domor Intelligent S&T CO.,Ltd
Jining high-tech zone base of production,education & research
@@ -55145,324 +56504,6 @@ D428D5 (base 16) TCT mobile ltd Round Rock TX 78682
US
-00-D0-37 (hex) ARRIS Group, Inc.
-00D037 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-D6 (hex) ARRIS Group, Inc.
-001DD6 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-30-60-23 (hex) ARRIS Group, Inc.
-306023 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-AC-B3-13 (hex) ARRIS Group, Inc.
-ACB313 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-14-AB-F0 (hex) ARRIS Group, Inc.
-14ABF0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-0C-F8-93 (hex) ARRIS Group, Inc.
-0CF893 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-84-61-A0 (hex) ARRIS Group, Inc.
-8461A0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E8-33-81 (hex) ARRIS Group, Inc.
-E83381 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-44-E1-37 (hex) ARRIS Group, Inc.
-44E137 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-FC-6F-B7 (hex) ARRIS Group, Inc.
-FC6FB7 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-A0-C5-62 (hex) ARRIS Group, Inc.
-A0C562 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-A0-55-DE (hex) ARRIS Group, Inc.
-A055DE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-54-E2-E0 (hex) ARRIS Group, Inc.
-54E2E0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-28-C8-7A (hex) ARRIS Group, Inc.
-28C87A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-26-D9 (hex) ARRIS Group, Inc.
-0026D9 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-C8-AA-21 (hex) ARRIS Group, Inc.
-C8AA21 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-2C-9E-5F (hex) ARRIS Group, Inc.
-2C9E5F (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-24-95 (hex) ARRIS Group, Inc.
-002495 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-26-42 (hex) ARRIS Group, Inc.
-002642 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-A4-ED-4E (hex) ARRIS Group, Inc.
-A4ED4E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-24-A1 (hex) ARRIS Group, Inc.
-0024A1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-23-75 (hex) ARRIS Group, Inc.
-002375 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-CE (hex) ARRIS Group, Inc.
-0015CE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-13-11 (hex) ARRIS Group, Inc.
-001311 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-A2 (hex) ARRIS Group, Inc.
-0015A2 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-96 (hex) ARRIS Group, Inc.
-001596 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-00-CA (hex) ARRIS Group, Inc.
-0000CA (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-60-19-71 (hex) ARRIS Group, Inc.
-601971 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-D1 (hex) ARRIS Group, Inc.
-001DD1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-16-26 (hex) ARRIS Group, Inc.
-001626 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-11-1A (hex) ARRIS Group, Inc.
-00111A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-2F (hex) ARRIS Group, Inc.
-00152F (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-0B-06 (hex) ARRIS Group, Inc.
-000B06 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-0F-9F (hex) ARRIS Group, Inc.
-000F9F (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-11-AE (hex) ARRIS Group, Inc.
-0011AE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-20-40 (hex) ARRIS Group, Inc.
-002040 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-1C-1B-68 (hex) ARRIS Group, Inc.
-1C1B68 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-10-86-8C (hex) ARRIS Group, Inc.
-10868C (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-10-05-B1 (hex) ARRIS Group, Inc.
-1005B1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-7C-26-34 (hex) ARRIS Group, Inc.
-7C2634 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1E-5A (hex) ARRIS Group, Inc.
-001E5A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-BE (hex) ARRIS Group, Inc.
-001DBE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-13-71 (hex) ARRIS Group, Inc.
-001371 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-14-9A (hex) ARRIS Group, Inc.
-00149A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1A-1B (hex) ARRIS Group, Inc.
-001A1B (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-18-A4 (hex) ARRIS Group, Inc.
-0018A4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1A-DB (hex) ARRIS Group, Inc.
-001ADB (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1F-7E (hex) ARRIS Group, Inc.
-001F7E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1C-11 (hex) ARRIS Group, Inc.
-001C11 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1C-C1 (hex) ARRIS Group, Inc.
-001CC1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-6B (hex) ARRIS Group, Inc.
-001D6B (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-40-0D-10 (hex) ARRIS Group, Inc.
-400D10 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-34-1F-E4 (hex) ARRIS Group, Inc.
-341FE4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
A0-09-4C (hex) CenturyLink
A0094C (base 16) CenturyLink
100 CenturyLink Drive
@@ -55529,18 +56570,6 @@ C0A5DD (base 16) SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. Shenzhen Guangdong 518057
CN
-18-35-D1 (hex) ARRIS Group, Inc.
-1835D1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-4C-38-D8 (hex) ARRIS Group, Inc.
-4C38D8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
DC-BE-7A (hex) Zhejiang Nurotron Biotechnology Co.
DCBE7A (base 16) Zhejiang Nurotron Biotechnology Co.
Building4, No.99 Xiaomao Rd
@@ -56378,1016 +57407,434 @@ A0FE61 (base 16) Vivint Wireless Inc. Shenzhen, Guangdong, 518067
CN
-F4-6E-24 (hex) NEC Personal Computers, Ltd.
-F46E24 (base 16) NEC Personal Computers, Ltd.
- Akihabara UDX,14-1, Sotokanda 4-Chome
- Chiyoda-ku Tokyo 101-0021
- JP
-
-88-82-79 (hex) Shenzhen RB-LINK Intelligent Technology Co.Ltd
-888279 (base 16) Shenzhen RB-LINK Intelligent Technology Co.Ltd
- Second floor, No 22, Wanfeng the third industry area, Shajing , BaoAn district
- Shenzhen City 518125
- CN
-
-78-32-1B (hex) D-Link International
-78321B (base 16) D-Link International
- 1 Internal Business Park, #03-12,The Synergy, Singapore
- Singapore Singapore 609917
- SG
-
-EC-51-BC (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-EC51BC (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
- NO.18 HAIBIN ROAD,
- DONG GUAN GUANG DONG 523860
- CN
-
-F0-79-E8 (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-F079E8 (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
- NO.18 HAIBIN ROAD,
- DONG GUAN GUANG DONG 523860
- CN
-
-D8-A5-34 (hex) Spectronix Corporation
-D8A534 (base 16) Spectronix Corporation
- 3-28-15, Tarumi-cho
- Suita-city Osaka 564-0062
- JP
-
-58-38-79 (hex) RICOH COMPANY, LTD.
-583879 (base 16) RICOH COMPANY, LTD.
- 1005, Shimo-ogino
- Atsugi-City Kanagawa-Pref. 243-0298
- JP
-
-94-28-2E (hex) New H3C Technologies Co., Ltd
-94282E (base 16) New H3C Technologies Co., Ltd
- 466 Changhe Road, Binjiang District
- Hangzhou Zhejiang 310052
- CN
-
-D8-43-ED (hex) Suzuken
-D843ED (base 16) Suzuken
- 8, Higashikatahamachi, Higashiku
- Nagoya Aich 4610015
- JP
-
-88-75-98 (hex) Samsung Electronics Co.,Ltd
-887598 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-D0-B1-28 (hex) Samsung Electronics Co.,Ltd
-D0B128 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-FC-EE-E6 (hex) FORMIKE ELECTRONIC CO., LTD
-FCEEE6 (base 16) FORMIKE ELECTRONIC CO., LTD
- Flats 401-403, Block B, iPARK Building, 26 Dengliang Rd., NanShan Distric
- Shenzhen Guang Dong 518054
- CN
-
-2C-43-1A (hex) Shenzhen YOUHUA Technology Co., Ltd
-2C431A (base 16) Shenzhen YOUHUA Technology Co., Ltd
- Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
- Shenzhen Guangdong 518055
- CN
-
-A8-D3-C8 (hex) Topcon Electronics GmbH & Co. KG
-A8D3C8 (base 16) Topcon Electronics GmbH & Co. KG
- Industriestraße 7
- Geisenheim 65366
- DE
-
-38-9F-5A (hex) C-Kur TV Inc.
-389F5A (base 16) C-Kur TV Inc.
- A-1902, 583, Yangcheon-ro, Gangseo-gu
- Seoul 07547
- KR
-
-24-B2-09 (hex) Avaya Inc
-24B209 (base 16) Avaya Inc
- 360 Mt Kemble Ave
- Morristown NJ 07960
- US
-
-24-E1-24 (hex) Xiamen Ursaconn Technology Co. , Ltd.
-24E124 (base 16) Xiamen Ursaconn Technology Co. , Ltd.
- 3/F, No. 46 Guanri Road, 2nd Software Park
- Xiamen Fujian 361008
- CN
-
-DC-68-EB (hex) Nintendo Co.,Ltd
-DC68EB (base 16) Nintendo Co.,Ltd
- 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
- KYOTO KYOTO 601-8501
- JP
-
-94-41-C1 (hex) Mini-Cam Limited
-9441C1 (base 16) Mini-Cam Limited
- Unit 4 Yew Tree Way
- Warrington Cheshire WA33JD
- GB
-
-E8-D8-19 (hex) AzureWave Technology Inc.
-E8D819 (base 16) AzureWave Technology Inc.
- 8F., No. 94, Baozhong Rd.
- New Taipei City Taiwan 231
- TW
-
-AC-1D-DF (hex) IEEE Registration Authority
-AC1DDF (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
- US
-
-00-08-FA (hex) KEB Automation KG
-0008FA (base 16) KEB Automation KG
- Südstraße 38
- Barntrup NRW D-32683
- DE
-
-18-39-6E (hex) SUNSEA TELECOMMUNICATIONS CO.,LTD.
-18396E (base 16) SUNSEA TELECOMMUNICATIONS CO.,LTD.
- High tech Industrial Park,Longhua District of Shenzhen City,South central concept
- Shenzhen 518110
+B4-CD-27 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+B4CD27 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
CN
-E8-DF-70 (hex) AVM Audiovisuelles Marketing und Computersysteme GmbH
-E8DF70 (base 16) AVM Audiovisuelles Marketing und Computersysteme GmbH
- Alt-Moabit 95
- Berlin Berlin 10559
- DE
-
-7C-DD-76 (hex) Suzhou Hanming Technologies Co., Ltd.
-7CDD76 (base 16) Suzhou Hanming Technologies Co., Ltd.
- Suite 407, No. 166, Ren Ai Road
- Suzhou Jiangsu 215123
+3C-CD-5D (hex) HUAWEI TECHNOLOGIES CO.,LTD
+3CCD5D (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
CN
-24-68-80 (hex) Braveridge.co.,ltd.
-246880 (base 16) Braveridge.co.,ltd.
- 3-27-2, Susenji
- Nishi-ku, Fukuoka-shi Fukuoka 819-0373
- JP
-
-D0-04-01 (hex) Motorola Mobility LLC, a Lenovo Company
-D00401 (base 16) Motorola Mobility LLC, a Lenovo Company
- 222 West Merchandise Mart Plaza
- Chicago IL 60654
- US
-
-58-90-43 (hex) Sagemcom Broadband SAS
-589043 (base 16) Sagemcom Broadband SAS
+34-6B-46 (hex) Sagemcom Broadband SAS
+346B46 (base 16) Sagemcom Broadband SAS
250, route de l'Empereur
Rueil Malmaison Cedex hauts de seine 92848
FR
-28-CF-08 (hex) ESSYS
-28CF08 (base 16) ESSYS
- gaetbeol-ro
- Incheon 21999
- KR
-
-70-7D-B9 (hex) Cisco Systems, Inc
-707DB9 (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
- US
-
-34-6F-ED (hex) Enovation Controls
-346FED (base 16) Enovation Controls
- 5311 S. 122nd E. Ave.
- Tulsa OK 74146
+D4-C1-9E (hex) Ruckus Wireless
+D4C19E (base 16) Ruckus Wireless
+ 350 West Java Drive
+ Sunnyvale CA 94089
US
-00-00-B4 (hex) Edimax Technology Co. Ltd.
-0000B4 (base 16) Edimax Technology Co. Ltd.
- No. 278, Xinhu 1st Road
- Taipei City Neihu Dist 248
- TW
-
-08-BE-AC (hex) Edimax Technology Co. Ltd.
-08BEAC (base 16) Edimax Technology Co. Ltd.
- No. 278, Xinhu 1st Road
- Taipei City Neihu Dist 248
- TW
-
-F0-6D-78 (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-F06D78 (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
- NO.18 HAIBIN ROAD,
- DONG GUAN GUANG DONG 523860
- CN
-
-78-44-FD (hex) TP-LINK TECHNOLOGIES CO.,LTD.
-7844FD (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
- Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
- Shenzhen Guangdong 518057
- CN
-
-50-3E-AA (hex) TP-LINK TECHNOLOGIES CO.,LTD.
-503EAA (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
- Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
- Shenzhen Guangdong 518057
- CN
+08-DF-CB (hex) Systrome Networks
+08DFCB (base 16) Systrome Networks
+ Sohna Road
+ Gurgaon Haryana 122018
+ IN
-AC-84-C6 (hex) TP-LINK TECHNOLOGIES CO.,LTD.
-AC84C6 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
+9C-A6-15 (hex) TP-LINK TECHNOLOGIES CO.,LTD.
+9CA615 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
Shenzhen Guangdong 518057
CN
-34-D0-B8 (hex) IEEE Registration Authority
-34D0B8 (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
+28-AC-9E (hex) Cisco Systems, Inc
+28AC9E (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
US
-B0-C1-9E (hex) zte corporation
-B0C19E (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
+04-FA-83 (hex) Qingdao Haier Technology Co.,Ltd
+04FA83 (base 16) Qingdao Haier Technology Co.,Ltd
+ Building A01,Haier Information Park, No.1 Haier Road,
+ Qingdao Shandong 266101
CN
-0C-37-47 (hex) zte corporation
-0C3747 (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
+84-F3-EB (hex) Espressif Inc.
+84F3EB (base 16) Espressif Inc.
+ Room 204, Building 2, 690 Bibo Road, Pudong New Area
+ Shanghai Shanghai 201203
CN
-00-00-97 (hex) Dell EMC
-000097 (base 16) Dell EMC
- 176 South Street
- Hopkinton MA 01748
- US
-
-EC-C0-6A (hex) PowerChord Group Limited
-ECC06A (base 16) PowerChord Group Limited
- 1 Blythe Road
- London W14 0HG
- GB
-
-A8-9F-EC (hex) ARRIS Group, Inc.
-A89FEC (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-38-D7-CA (hex) 7HUGS LABS
-38D7CA (base 16) 7HUGS LABS
- 29 bd Romain Rolland
- Montrouge 92120
- FR
-
-6C-05-D5 (hex) Ethertronics Inc
-6C05D5 (base 16) Ethertronics Inc
- 5501 Oberlin Drive, Suite 100
- SAN DIEGO CA 92121
- US
-
-00-1D-F4 (hex) Magellan Technology Pty Limited
-001DF4 (base 16) Magellan Technology Pty Limited
- 65 Johnston Street
- Annandale NSW 2000
- AU
-
-C0-22-50 (hex) Private
-C02250 (base 16) Private
-
-00-94-A1 (hex) F5 Networks, Inc.
-0094A1 (base 16) F5 Networks, Inc.
- 401 Elliott Ave. W.
- Seattle WA 98119
- US
-
-18-90-D8 (hex) Sagemcom Broadband SAS
-1890D8 (base 16) Sagemcom Broadband SAS
- 250, route de l'Empereur
- Rueil Malmaison Cedex hauts de seine 92848
- FR
-
-88-83-5D (hex) FN-LINK TECHNOLOGY LIMITED
-88835D (base 16) FN-LINK TECHNOLOGY LIMITED
- No.8, Litong Road, Liuyang Economic & Technical Development Zone
- ChangSha Hu Nan 410300
+10-B3-6F (hex) Bowei Technology Company Limited
+10B36F (base 16) Bowei Technology Company Limited
+ 2F,Building No.6C,1658,Gumei Rd
+ Shanghai Shanghai 200233
CN
-10-68-3F (hex) LG Electronics (Mobile Communications)
-10683F (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-74-A7-22 (hex) LG Electronics (Mobile Communications)
-74A722 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-58-A2-B5 (hex) LG Electronics (Mobile Communications)
-58A2B5 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-64-89-9A (hex) LG Electronics (Mobile Communications)
-64899A (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-88-07-4B (hex) LG Electronics (Mobile Communications)
-88074B (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-64-BC-0C (hex) LG Electronics (Mobile Communications)
-64BC0C (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-A0-39-F7 (hex) LG Electronics (Mobile Communications)
-A039F7 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-04-1B-6D (hex) LG Electronics (Mobile Communications)
-041B6D (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-00-1F-6B (hex) LG Electronics (Mobile Communications)
-001F6B (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-D0-07-CA (hex) Juniper Networks
-D007CA (base 16) Juniper Networks
- 1133 Innovation Way
- Sunnyvale CA 94089
- US
+80-05-88 (hex) Ruijie Networks Co.,LTD
+800588 (base 16) Ruijie Networks Co.,LTD
+ 20# Building,Star-net Science Plaza,Juyuanzhou, 618 Jinshan Road
+ Fuzhou Fujian 350002
+ CN
-F8-6C-E1 (hex) Taicang T&W Electronics
-F86CE1 (base 16) Taicang T&W Electronics
- 89# Jiang Nan RD
- Suzhou Jiangsu 215412
+9C-E8-95 (hex) New H3C Technologies Co., Ltd
+9CE895 (base 16) New H3C Technologies Co., Ltd
+ 466 Changhe Road, Binjiang District
+ Hangzhou Zhejiang 310052
CN
-1C-73-28 (hex) Connected Home
-1C7328 (base 16) Connected Home
- 19-22, Rathbone Place
- London W1T 1HY
+00-16-5C (hex) Trackflow Ltd.
+00165C (base 16) Trackflow Ltd.
+ 167-169 Kensington High Street
+ London England W86SH
GB
-40-A9-3F (hex) Private
-40A93F (base 16) Private
-
-5C-77-76 (hex) TCT mobile ltd
-5C7776 (base 16) TCT mobile ltd
- No.86 hechang 7th road, zhongkai, Hi-Tech District
- Hui Zhou Guang Dong 516006
+04-E2-29 (hex) Qingdao Haier Technology Co.,Ltd
+04E229 (base 16) Qingdao Haier Technology Co.,Ltd
+ Building A01,Haier Information Park, No.1 Haier Road,
+ Qingdao Shandong 266101
CN
-EC-1D-8B (hex) Cisco Systems, Inc
-EC1D8B (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
- US
-
-0C-EA-C9 (hex) ARRIS Group, Inc.
-0CEAC9 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-38-F7-3D (hex) Amazon Technologies Inc.
-38F73D (base 16) Amazon Technologies Inc.
- P.O Box 8102
- Reno NV 89507
- US
-
-30-B4-B8 (hex) LG Electronics
-30B4B8 (base 16) LG Electronics
- 222 LG-ro, JINWI-MYEON
- Pyeongtaek-si Gyeonggi-do 451-713
- KR
-
-2C-FD-AB (hex) Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.
-2CFDAB (base 16) Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.
- No.19, Gaoxin 4th Road, Wuhan East Lake High-tech Zone, Wuhan
- Wuhan Hubei 430000
- CN
+78-F9-B4 (hex) Nokia
+78F9B4 (base 16) Nokia
+ Karaportti 3
+ Espoo Finland 02610
+ FI
-F4-1E-5E (hex) RtBrick Inc.
-F41E5E (base 16) RtBrick Inc.
- 26 Kingston Terrace
- Princeton NJ 08540
- US
+04-D3-B0 (hex) Intel Corporate
+04D3B0 (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
-18-06-FF (hex) Acer Computer(Shanghai) Limited.
-1806FF (base 16) Acer Computer(Shanghai) Limited.
- Room1806-20, No.769, Jiujiang Road, Huangpu District
- Shanghai 200000
+C8-D7-79 (hex) QING DAO HAIER TELECOM CO.,LTD.
+C8D779 (base 16) QING DAO HAIER TELECOM CO.,LTD.
+ No 1 Haier road,Hi-tech Zone,Qingdao,PR.China
+ Qingdao Shandong 266101
CN
-B8-EC-A3 (hex) Zyxel Communications Corporation
-B8ECA3 (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-EC-43-F6 (hex) Zyxel Communications Corporation
-EC43F6 (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-58-8B-F3 (hex) Zyxel Communications Corporation
-588BF3 (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-FC-F5-28 (hex) Zyxel Communications Corporation
-FCF528 (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-00-19-CB (hex) Zyxel Communications Corporation
-0019CB (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-60-31-97 (hex) Zyxel Communications Corporation
-603197 (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
+3C-E1-A1 (hex) Universal Global Scientific Industrial Co., Ltd.
+3CE1A1 (base 16) Universal Global Scientific Industrial Co., Ltd.
+ 141, Lane 351, Taiping Road, Sec.1,Tsao Tuen
+ Nan-Tou Taiwan 54261
TW
-34-FA-9F (hex) Ruckus Wireless
-34FA9F (base 16) Ruckus Wireless
- 350 West Java Drive
- Sunnyvale CA 94089
- US
-
-50-6F-98 (hex) Sehaj Synergy Technologies Private Limited
-506F98 (base 16) Sehaj Synergy Technologies Private Limited
- E-112A, Kataria Colony, Ramanagar Extension, New Sanganer Road, Sodala, Jaipur-302019
- Jaipur Rajasthan 302019
- IN
-
-04-F1-28 (hex) HMD Global Oy
-04F128 (base 16) HMD Global Oy
- Karaportti 2
- Espoo 02610
- FI
-
-F0-65-C2 (hex) Yanfeng Visteon Electronics Technology (Shanghai) Co.,Ltd.
-F065C2 (base 16) Yanfeng Visteon Electronics Technology (Shanghai) Co.,Ltd.
- 1001 North Qin Zhou Road
- Shang Hai 200233
- CN
-
-70-B7-E2 (hex) Jiangsu Miter Technology Co.,Ltd.
-70B7E2 (base 16) Jiangsu Miter Technology Co.,Ltd.
- No.86 fuyuan community,the town of houbei
- Jurong Jiangsu 212400
- CN
-
-50-3C-EA (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-503CEA (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
- NO.18 HAIBIN ROAD,
- DONG GUAN GUANG DONG 523860
+58-BA-D4 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+58BAD4 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
CN
-00-04-CF (hex) Seagate Technology
-0004CF (base 16) Seagate Technology
- M/S NW1F01
- Longmont CO 80503
- US
-
-00-14-C3 (hex) Seagate Technology
-0014C3 (base 16) Seagate Technology
- M/S NW1F01
- Longmont CO 80503
- US
+14-B1-26 (hex) Industrial Software Co
+14B126 (base 16) Industrial Software Co
+ 85, Aleksandyr Malinov Blvd. Office 6
+ Sofia 1715
+ BG
-00-20-37 (hex) Seagate Technology
-002037 (base 16) Seagate Technology
- 8001 E. BLOOMINGTON FWY
- BLOOMINGTON MN 55420
+B8-C1-11 (hex) Apple, Inc.
+B8C111 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-00-50-CC (hex) Seagate Cloud Systems Inc
-0050CC (base 16) Seagate Cloud Systems Inc
- 1351 S Sunset Street
- Longmont CO 80501
+34-08-BC (hex) Apple, Inc.
+3408BC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-1C-27-DD (hex) Datang Gohighsec(zhejiang)Information Technology Co.,Ltd.
-1C27DD (base 16) Datang Gohighsec(zhejiang)Information Technology Co.,Ltd.
- Beiwu Innovation park, #23 Beiwu Villiage Road
- Beijing Beijing 100000
- CN
-
-00-72-63 (hex) Netcore Technology Inc.
-007263 (base 16) Netcore Technology Inc.
- ORIENTAL CYBERPORT,HIGHTECH 6 ROAD
- Shenzhen 518057
- CN
-
-48-55-5C (hex) Wu Qi Technologies,Inc.
-48555C (base 16) Wu Qi Technologies,Inc.
- Xiantao street data on the 19th East Road
- Chongqing City Yubei District 401120
- CN
-
-70-EE-A3 (hex) Eoptolink Technology Inc. Ltd,
-70EEA3 (base 16) Eoptolink Technology Inc. Ltd,
- No.127 West Wulian Street
- Chengdu China/Sichuan 610213
- CN
-
-5C-58-19 (hex) Jingsheng Technology Co., Ltd.
-5C5819 (base 16) Jingsheng Technology Co., Ltd.
- Linyin street 5#
- chengdu sichuan 610000
- CN
-
-74-7D-24 (hex) Phicomm (Shanghai) Co., Ltd.
-747D24 (base 16) Phicomm (Shanghai) Co., Ltd.
- 3666 SiXian Rd.,Songjiang District
- Shanghai Shanghai 201616
- CN
-
-5C-81-A7 (hex) Network Devices Pty Ltd
-5C81A7 (base 16) Network Devices Pty Ltd
- 16 Dickson Ave
- Artarmon NSW 2064
- AU
-
-80-8D-B7 (hex) Hewlett Packard Enterprise
-808DB7 (base 16) Hewlett Packard Enterprise
- 8000 Foothills Blvd.
- Roseville CA 95747
+84-41-67 (hex) Apple, Inc.
+844167 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-10-CE-A9 (hex) Texas Instruments
-10CEA9 (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
+B4-F6-1C (hex) Apple, Inc.
+B4F61C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-F8-B5-68 (hex) IEEE Registration Authority
-F8B568 (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
+68-AB-1E (hex) Apple, Inc.
+68AB1E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-14-44-4A (hex) Apollo Seiko Ltd.
-14444A (base 16) Apollo Seiko Ltd.
- 2271-7 Jinba
- Gotenba Shizuoka 412-0047
- JP
-
-5C-0C-0E (hex) Guizhou Huaxintong Semiconductor Technology Co Ltd
-5C0C0E (base 16) Guizhou Huaxintong Semiconductor Technology Co Ltd
- Sitelin Park
- Intersection between Jin ma Ave and Qianzhong Ave Gui An New Area, Guizhou Prov 550003
- CN
-
-2C-FD-A1 (hex) ASUSTek COMPUTER INC.
-2CFDA1 (base 16) ASUSTek COMPUTER INC.
- 15,Li-Te Rd., Peitou, Taipei 112, Taiwan
- Taipei Taiwan 112
- TW
-
-38-07-D4 (hex) Zeppelin Systems GmbH
-3807D4 (base 16) Zeppelin Systems GmbH
- Messenhäuser Str. 37-45
- Rödermark Hessen 63322
- DE
-
-64-20-9F (hex) Tilgin AB
-64209F (base 16) Tilgin AB
- Finlandsgatan 40
- Kista 16474
- SE
-
-04-E0-B0 (hex) Shenzhen YOUHUA Technology Co., Ltd
-04E0B0 (base 16) Shenzhen YOUHUA Technology Co., Ltd
- Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
- Shenzhen Guangdong 518055
- CN
-
-0C-98-38 (hex) Xiaomi Communications Co Ltd
-0C9838 (base 16) Xiaomi Communications Co Ltd
- The Rainbow City of China Resources
- NO.68, Qinghe Middle Street Haidian District, Beijing 100085
- CN
-
-00-04-96 (hex) Extreme Networks, Inc.
-000496 (base 16) Extreme Networks, Inc.
- 3585 Monroe Street
- Santa Clara CA 95051
+2C-61-F6 (hex) Apple, Inc.
+2C61F6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-B8-50-01 (hex) Extreme Networks, Inc.
-B85001 (base 16) Extreme Networks, Inc.
- ONE ZEBRA PLAZA
- HOLTSVILLE NY 11742
+E4-9A-DC (hex) Apple, Inc.
+E49ADC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-7C-76-30 (hex) Shenzhen YOUHUA Technology Co., Ltd
-7C7630 (base 16) Shenzhen YOUHUA Technology Co., Ltd
- Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
- Shenzhen Guangdong 518055
- CN
-
-98-22-EF (hex) Liteon Technology Corporation
-9822EF (base 16) Liteon Technology Corporation
- 4F, 90, Chien 1 Road
- New Taipei City Taiwan 23585
- TW
-
-58-04-54 (hex) ICOMM HK LIMITED
-580454 (base 16) ICOMM HK LIMITED
- SUITES 2302-6, 23/F GREAT EAGLE CTR 23 HARBOUR RD
- WANCHAI NA
- HK
-
-A0-BD-CD (hex) BSkyB Ltd
-A0BDCD (base 16) BSkyB Ltd
- 130 Kings Road
- Brentwood Essex 08854
- GB
-
-80-3A-59 (hex) AT&T
-803A59 (base 16) AT&T
- 1025 Lenox Park Blvd
- Atlanta GA 30319
+D0-81-7A (hex) Apple, Inc.
+D0817A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-60-6D-3C (hex) Luxshare Precision Industry Company Limited
-606D3C (base 16) Luxshare Precision Industry Company Limited
- Floor 2, Block A, Sanyo New Industrial Area
- West Haoyi Community, Shajing Subdistrict Office Bao'an District, Shenzhen, Guangdong 523000
- CN
-
-CC-4D-38 (hex) Carnegie Technologies
-CC4D38 (base 16) Carnegie Technologies
- 9737 Great Hills Trail #260
- Austin TX 78759
+C4-61-8B (hex) Apple, Inc.
+C4618B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-08-AE-D6 (hex) Samsung Electronics Co.,Ltd
-08AED6 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-B0-67-2F (hex) Bowers & Wilkins
-B0672F (base 16) Bowers & Wilkins
- 900 Middlefield Rd Floor 4
- Redwood City CA 94063
+34-51-C9 (hex) Apple, Inc.
+3451C9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-A8-16-D0 (hex) Samsung Electronics Co.,Ltd
-A816D0 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-88-BD-45 (hex) Samsung Electronics Co.,Ltd
-88BD45 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-54-FC-F0 (hex) Samsung Electronics Co.,Ltd
-54FCF0 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-CC-50-0A (hex) Fiberhome Telecommunication Technologies Co.,LTD
-CC500A (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-60-B6-17 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-60B617 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan City Hubei Province 430074
- CN
-
-18-A3-E8 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-18A3E8 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan City Hubei Province 430074
- CN
-
-74-1E-93 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-741E93 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan City Hubei Province 430074
- CN
-
-20-89-6F (hex) Fiberhome Telecommunication Technologies Co.,LTD
-20896F (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-A0-13-CB (hex) Fiberhome Telecommunication Technologies Co.,LTD
-A013CB (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-3C-FB-5C (hex) Fiberhome Telecommunication Technologies Co.,LTD
-3CFB5C (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-74-C9-A3 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-74C9A3 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-A8-E7-05 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-A8E705 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-CC-3A-DF (hex) Neptune Technology Group Inc.
-CC3ADF (base 16) Neptune Technology Group Inc.
- 1600 AL Highway 229 S
- Tallassee AL 36078
+E0-B9-BA (hex) Apple, Inc.
+E0B9BA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-28-ED-E0 (hex) AMPAK Technology, Inc.
-28EDE0 (base 16) AMPAK Technology, Inc.
- No.1,Jen Ai Road Hsinchu Industrial Park, Hukou
- Hsinchu Taiwan ROC. 30352
- TW
-
-A8-5B-78 (hex) Apple, Inc.
-A85B78 (base 16) Apple, Inc.
+D0-23-DB (hex) Apple, Inc.
+D023DB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-9C-F3-87 (hex) Apple, Inc.
-9CF387 (base 16) Apple, Inc.
+B8-8D-12 (hex) Apple, Inc.
+B88D12 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-34-A3-95 (hex) Apple, Inc.
-34A395 (base 16) Apple, Inc.
+B8-17-C2 (hex) Apple, Inc.
+B817C2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-48-43-7C (hex) Apple, Inc.
-48437C (base 16) Apple, Inc.
+68-A8-6D (hex) Apple, Inc.
+68A86D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-AC-87-A3 (hex) Apple, Inc.
-AC87A3 (base 16) Apple, Inc.
+78-A3-E4 (hex) Apple, Inc.
+78A3E4 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-F7-6F (hex) Apple, Inc.
-00F76F (base 16) Apple, Inc.
+68-09-27 (hex) Apple, Inc.
+680927 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A4-5E-60 (hex) Apple, Inc.
-A45E60 (base 16) Apple, Inc.
+60-FA-CD (hex) Apple, Inc.
+60FACD (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-0C-BC-9F (hex) Apple, Inc.
-0CBC9F (base 16) Apple, Inc.
+1C-AB-A7 (hex) Apple, Inc.
+1CABA7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-BC-4C-C4 (hex) Apple, Inc.
-BC4CC4 (base 16) Apple, Inc.
+78-4F-43 (hex) Apple, Inc.
+784F43 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-0C-15-39 (hex) Apple, Inc.
-0C1539 (base 16) Apple, Inc.
+40-4D-7F (hex) Apple, Inc.
+404D7F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-90-8D-6C (hex) Apple, Inc.
-908D6C (base 16) Apple, Inc.
+7C-04-D0 (hex) Apple, Inc.
+7C04D0 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D0-33-11 (hex) Apple, Inc.
-D03311 (base 16) Apple, Inc.
+BC-9F-EF (hex) Apple, Inc.
+BC9FEF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-E7-2C (hex) Apple, Inc.
-70E72C (base 16) Apple, Inc.
+88-66-A5 (hex) Apple, Inc.
+8866A5 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C0-CE-CD (hex) Apple, Inc.
-C0CECD (base 16) Apple, Inc.
+88-E8-7F (hex) Apple, Inc.
+88E87F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-E0-D9 (hex) Apple, Inc.
-98E0D9 (base 16) Apple, Inc.
+B8-53-AC (hex) Apple, Inc.
+B853AC (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E0-AC-CB (hex) Apple, Inc.
-E0ACCB (base 16) Apple, Inc.
+2C-33-61 (hex) Apple, Inc.
+2C3361 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-D7-5F (hex) Apple, Inc.
-78D75F (base 16) Apple, Inc.
+A8-60-B6 (hex) Apple, Inc.
+A860B6 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-20-78-F0 (hex) Apple, Inc.
-2078F0 (base 16) Apple, Inc.
+24-F0-94 (hex) Apple, Inc.
+24F094 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-5A-EB (hex) Apple, Inc.
-985AEB (base 16) Apple, Inc.
+90-B0-ED (hex) Apple, Inc.
+90B0ED (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-54-4E-90 (hex) Apple, Inc.
-544E90 (base 16) Apple, Inc.
+C4-B3-01 (hex) Apple, Inc.
+C4B301 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-6D-52 (hex) Apple, Inc.
-006D52 (base 16) Apple, Inc.
+E0-5F-45 (hex) Apple, Inc.
+E05F45 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-5C-AD-CF (hex) Apple, Inc.
-5CADCF (base 16) Apple, Inc.
+48-3B-38 (hex) Apple, Inc.
+483B38 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-E8-56 (hex) Apple, Inc.
-B8E856 (base 16) Apple, Inc.
+E0-C7-67 (hex) Apple, Inc.
+E0C767 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-90-B2-1F (hex) Apple, Inc.
-90B21F (base 16) Apple, Inc.
+1C-9E-46 (hex) Apple, Inc.
+1C9E46 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A8-BB-CF (hex) Apple, Inc.
-A8BBCF (base 16) Apple, Inc.
+0C-D7-46 (hex) Apple, Inc.
+0CD746 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-B5-B7 (hex) Apple, Inc.
-C8B5B7 (base 16) Apple, Inc.
+44-00-10 (hex) Apple, Inc.
+440010 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-18-AF-8F (hex) Apple, Inc.
-18AF8F (base 16) Apple, Inc.
+E4-98-D6 (hex) Apple, Inc.
+E498D6 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F4-F9-51 (hex) Apple, Inc.
-F4F951 (base 16) Apple, Inc.
+60-69-44 (hex) Apple, Inc.
+606944 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-C1-F1 (hex) Apple, Inc.
-F0C1F1 (base 16) Apple, Inc.
+04-52-F3 (hex) Apple, Inc.
+0452F3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-03-D8 (hex) Apple, Inc.
-9803D8 (base 16) Apple, Inc.
+24-1E-EB (hex) Apple, Inc.
+241EEB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-2A-14 (hex) Apple, Inc.
-C82A14 (base 16) Apple, Inc.
+F4-31-C3 (hex) Apple, Inc.
+F431C3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-88-C6-63 (hex) Apple, Inc.
-88C663 (base 16) Apple, Inc.
+64-A5-C3 (hex) Apple, Inc.
+64A5C3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-8C-7B-9D (hex) Apple, Inc.
-8C7B9D (base 16) Apple, Inc.
+BC-92-6B (hex) Apple, Inc.
+BC926B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-58-55-CA (hex) Apple, Inc.
-5855CA (base 16) Apple, Inc.
+00-50-E4 (hex) Apple, Inc.
+0050E4 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-CC-08-E0 (hex) Apple, Inc.
-CC08E0 (base 16) Apple, Inc.
+00-30-65 (hex) Apple, Inc.
+003065 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E8-06-88 (hex) Apple, Inc.
-E80688 (base 16) Apple, Inc.
+00-0A-27 (hex) Apple, Inc.
+000A27 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-17-C2 (hex) Apple, Inc.
-B817C2 (base 16) Apple, Inc.
+00-14-51 (hex) Apple, Inc.
+001451 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-8D-12 (hex) Apple, Inc.
-B88D12 (base 16) Apple, Inc.
+8C-7B-9D (hex) Apple, Inc.
+8C7B9D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D0-23-DB (hex) Apple, Inc.
-D023DB (base 16) Apple, Inc.
+88-C6-63 (hex) Apple, Inc.
+88C663 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E0-B9-BA (hex) Apple, Inc.
-E0B9BA (base 16) Apple, Inc.
+C8-2A-14 (hex) Apple, Inc.
+C82A14 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-34-51-C9 (hex) Apple, Inc.
-3451C9 (base 16) Apple, Inc.
+98-03-D8 (hex) Apple, Inc.
+9803D8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
@@ -57398,841 +57845,928 @@ E0B9BA (base 16) Apple, Inc. Cupertino CA 95014
US
-C0-F2-FB (hex) Apple, Inc.
-C0F2FB (base 16) Apple, Inc.
+00-19-E3 (hex) Apple, Inc.
+0019E3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-5C-8D-4E (hex) Apple, Inc.
-5C8D4E (base 16) Apple, Inc.
+00-23-12 (hex) Apple, Inc.
+002312 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E0-66-78 (hex) Apple, Inc.
-E06678 (base 16) Apple, Inc.
+00-23-32 (hex) Apple, Inc.
+002332 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-1C-1A-C0 (hex) Apple, Inc.
-1C1AC0 (base 16) Apple, Inc.
+00-24-36 (hex) Apple, Inc.
+002436 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-F6-50 (hex) Apple, Inc.
-C8F650 (base 16) Apple, Inc.
+00-25-4B (hex) Apple, Inc.
+00254B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-60-D9-C7 (hex) Apple, Inc.
-60D9C7 (base 16) Apple, Inc.
+00-26-BB (hex) Apple, Inc.
+0026BB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-3C-E0-72 (hex) Apple, Inc.
-3CE072 (base 16) Apple, Inc.
+70-F0-87 (hex) Apple, Inc.
+70F087 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F4-1B-A1 (hex) Apple, Inc.
-F41BA1 (base 16) Apple, Inc.
+88-6B-6E (hex) Apple, Inc.
+886B6E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-44-FB-42 (hex) Apple, Inc.
-44FB42 (base 16) Apple, Inc.
+4C-74-BF (hex) Apple, Inc.
+4C74BF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-64-A3-CB (hex) Apple, Inc.
-64A3CB (base 16) Apple, Inc.
+E8-06-88 (hex) Apple, Inc.
+E80688 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D8-D1-CB (hex) Apple, Inc.
-D8D1CB (base 16) Apple, Inc.
+CC-08-E0 (hex) Apple, Inc.
+CC08E0 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-54-26-96 (hex) Apple, Inc.
-542696 (base 16) Apple, Inc.
+58-55-CA (hex) Apple, Inc.
+5855CA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-EC-35-86 (hex) Apple, Inc.
-EC3586 (base 16) Apple, Inc.
+5C-09-47 (hex) Apple, Inc.
+5C0947 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-88-CB-87 (hex) Apple, Inc.
-88CB87 (base 16) Apple, Inc.
+38-89-2C (hex) Apple, Inc.
+38892C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-AC-3C-0B (hex) Apple, Inc.
-AC3C0B (base 16) Apple, Inc.
+40-83-1D (hex) Apple, Inc.
+40831D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-CC-78-5F (hex) Apple, Inc.
-CC785F (base 16) Apple, Inc.
+50-BC-96 (hex) Apple, Inc.
+50BC96 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E8-8D-28 (hex) Apple, Inc.
-E88D28 (base 16) Apple, Inc.
+B4-C0-F5 (hex) Shenzhen TINNO Mobile Technology Corp.
+B4C0F5 (base 16) Shenzhen TINNO Mobile Technology Corp.
+ 4/F, H-3 Building, Qiao Cheng Eastern Industrial Park, Overseas Chinese Town, Shenzhen
+ Shenzhen guangdong 518053
+ CN
+
+74-12-BB (hex) Fiberhome Telecommunication Technologies Co.,LTD
+7412BB (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+98-5A-EB (hex) Apple, Inc.
+985AEB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-14-10-9F (hex) Apple, Inc.
-14109F (base 16) Apple, Inc.
+20-78-F0 (hex) Apple, Inc.
+2078F0 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-BC-52-B7 (hex) Apple, Inc.
-BC52B7 (base 16) Apple, Inc.
+78-D7-5F (hex) Apple, Inc.
+78D75F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E0-C9-7A (hex) Apple, Inc.
-E0C97A (base 16) Apple, Inc.
+E0-AC-CB (hex) Apple, Inc.
+E0ACCB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-5C-95-AE (hex) Apple, Inc.
-5C95AE (base 16) Apple, Inc.
+98-E0-D9 (hex) Apple, Inc.
+98E0D9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-8C-FA-BA (hex) Apple, Inc.
-8CFABA (base 16) Apple, Inc.
+C0-CE-CD (hex) Apple, Inc.
+C0CECD (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-1C-AB-A7 (hex) Apple, Inc.
-1CABA7 (base 16) Apple, Inc.
+70-E7-2C (hex) Apple, Inc.
+70E72C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-60-FA-CD (hex) Apple, Inc.
-60FACD (base 16) Apple, Inc.
+D0-33-11 (hex) Apple, Inc.
+D03311 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-09-27 (hex) Apple, Inc.
-680927 (base 16) Apple, Inc.
+5C-AD-CF (hex) Apple, Inc.
+5CADCF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-A3-E4 (hex) Apple, Inc.
-78A3E4 (base 16) Apple, Inc.
+00-6D-52 (hex) Apple, Inc.
+006D52 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-A8-6D (hex) Apple, Inc.
-68A86D (base 16) Apple, Inc.
+48-43-7C (hex) Apple, Inc.
+48437C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-80-00-6E (hex) Apple, Inc.
-80006E (base 16) Apple, Inc.
+34-A3-95 (hex) Apple, Inc.
+34A395 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B4-18-D1 (hex) Apple, Inc.
-B418D1 (base 16) Apple, Inc.
+9C-F3-87 (hex) Apple, Inc.
+9CF387 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-14-99-E2 (hex) Apple, Inc.
-1499E2 (base 16) Apple, Inc.
+A8-5B-78 (hex) Apple, Inc.
+A85B78 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-1C-9E-46 (hex) Apple, Inc.
-1C9E46 (base 16) Apple, Inc.
+90-8D-6C (hex) Apple, Inc.
+908D6C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E0-C7-67 (hex) Apple, Inc.
-E0C767 (base 16) Apple, Inc.
+0C-15-39 (hex) Apple, Inc.
+0C1539 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A8-60-B6 (hex) Apple, Inc.
-A860B6 (base 16) Apple, Inc.
+BC-4C-C4 (hex) Apple, Inc.
+BC4CC4 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-24-F0-94 (hex) Apple, Inc.
-24F094 (base 16) Apple, Inc.
+0C-BC-9F (hex) Apple, Inc.
+0CBC9F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-90-B0-ED (hex) Apple, Inc.
-90B0ED (base 16) Apple, Inc.
+A4-5E-60 (hex) Apple, Inc.
+A45E60 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C4-B3-01 (hex) Apple, Inc.
-C4B301 (base 16) Apple, Inc.
+54-4E-90 (hex) Apple, Inc.
+544E90 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E0-5F-45 (hex) Apple, Inc.
-E05F45 (base 16) Apple, Inc.
+9C-E6-5E (hex) Apple, Inc.
+9CE65E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-48-3B-38 (hex) Apple, Inc.
-483B38 (base 16) Apple, Inc.
+90-DD-5D (hex) Apple, Inc.
+90DD5D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-88-E8-7F (hex) Apple, Inc.
-88E87F (base 16) Apple, Inc.
+08-F6-9C (hex) Apple, Inc.
+08F69C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-53-AC (hex) Apple, Inc.
-B853AC (base 16) Apple, Inc.
+D4-61-DA (hex) Apple, Inc.
+D461DA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-2C-33-61 (hex) Apple, Inc.
-2C3361 (base 16) Apple, Inc.
+C8-D0-83 (hex) Apple, Inc.
+C8D083 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-0A-27 (hex) Apple, Inc.
-000A27 (base 16) Apple, Inc.
+88-E9-FE (hex) Apple, Inc.
+88E9FE (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-30-65 (hex) Apple, Inc.
-003065 (base 16) Apple, Inc.
+88-AE-07 (hex) Apple, Inc.
+88AE07 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-50-E4 (hex) Apple, Inc.
-0050E4 (base 16) Apple, Inc.
+18-AF-8F (hex) Apple, Inc.
+18AF8F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-BC-92-6B (hex) Apple, Inc.
-BC926B (base 16) Apple, Inc.
+C8-B5-B7 (hex) Apple, Inc.
+C8B5B7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-52-F3 (hex) Apple, Inc.
-0452F3 (base 16) Apple, Inc.
+A8-BB-CF (hex) Apple, Inc.
+A8BBCF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-24-1E-EB (hex) Apple, Inc.
-241EEB (base 16) Apple, Inc.
+90-B2-1F (hex) Apple, Inc.
+90B21F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F4-31-C3 (hex) Apple, Inc.
-F431C3 (base 16) Apple, Inc.
+B8-E8-56 (hex) Apple, Inc.
+B8E856 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-64-A5-C3 (hex) Apple, Inc.
-64A5C3 (base 16) Apple, Inc.
+14-99-E2 (hex) Apple, Inc.
+1499E2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-60-69-44 (hex) Apple, Inc.
-606944 (base 16) Apple, Inc.
+B4-18-D1 (hex) Apple, Inc.
+B418D1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E4-98-D6 (hex) Apple, Inc.
-E498D6 (base 16) Apple, Inc.
+80-00-6E (hex) Apple, Inc.
+80006E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-0C-D7-46 (hex) Apple, Inc.
-0CD746 (base 16) Apple, Inc.
+60-D9-C7 (hex) Apple, Inc.
+60D9C7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-44-00-10 (hex) Apple, Inc.
-440010 (base 16) Apple, Inc.
+C8-F6-50 (hex) Apple, Inc.
+C8F650 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-4F-43 (hex) Apple, Inc.
-784F43 (base 16) Apple, Inc.
+1C-1A-C0 (hex) Apple, Inc.
+1C1AC0 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-40-4D-7F (hex) Apple, Inc.
-404D7F (base 16) Apple, Inc.
+E0-66-78 (hex) Apple, Inc.
+E06678 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-7C-04-D0 (hex) Apple, Inc.
-7C04D0 (base 16) Apple, Inc.
+5C-8D-4E (hex) Apple, Inc.
+5C8D4E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-BC-9F-EF (hex) Apple, Inc.
-BC9FEF (base 16) Apple, Inc.
+C0-F2-FB (hex) Apple, Inc.
+C0F2FB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-88-66-A5 (hex) Apple, Inc.
-8866A5 (base 16) Apple, Inc.
+00-F7-6F (hex) Apple, Inc.
+00F76F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-F0-87 (hex) Apple, Inc.
-70F087 (base 16) Apple, Inc.
+AC-87-A3 (hex) Apple, Inc.
+AC87A3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-88-6B-6E (hex) Apple, Inc.
-886B6E (base 16) Apple, Inc.
+54-26-96 (hex) Apple, Inc.
+542696 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-4C-74-BF (hex) Apple, Inc.
-4C74BF (base 16) Apple, Inc.
+D8-D1-CB (hex) Apple, Inc.
+D8D1CB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-84-41-67 (hex) Apple, Inc.
-844167 (base 16) Apple, Inc.
+64-A3-CB (hex) Apple, Inc.
+64A3CB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B4-F6-1C (hex) Apple, Inc.
-B4F61C (base 16) Apple, Inc.
+44-FB-42 (hex) Apple, Inc.
+44FB42 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E4-9A-DC (hex) Apple, Inc.
-E49ADC (base 16) Apple, Inc.
+F4-1B-A1 (hex) Apple, Inc.
+F41BA1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-C1-11 (hex) Apple, Inc.
-B8C111 (base 16) Apple, Inc.
+3C-E0-72 (hex) Apple, Inc.
+3CE072 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-34-08-BC (hex) Apple, Inc.
-3408BC (base 16) Apple, Inc.
+E8-8D-28 (hex) Apple, Inc.
+E88D28 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D0-81-7A (hex) Apple, Inc.
-D0817A (base 16) Apple, Inc.
+CC-78-5F (hex) Apple, Inc.
+CC785F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C4-61-8B (hex) Apple, Inc.
-C4618B (base 16) Apple, Inc.
+AC-3C-0B (hex) Apple, Inc.
+AC3C0B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-AB-1E (hex) Apple, Inc.
-68AB1E (base 16) Apple, Inc.
+88-CB-87 (hex) Apple, Inc.
+88CB87 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-2C-61-F6 (hex) Apple, Inc.
-2C61F6 (base 16) Apple, Inc.
+EC-35-86 (hex) Apple, Inc.
+EC3586 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-26-BB (hex) Apple, Inc.
-0026BB (base 16) Apple, Inc.
+F0-C1-F1 (hex) Apple, Inc.
+F0C1F1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-25-4B (hex) Apple, Inc.
-00254B (base 16) Apple, Inc.
+F4-F9-51 (hex) Apple, Inc.
+F4F951 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-24-36 (hex) Apple, Inc.
-002436 (base 16) Apple, Inc.
+8C-FA-BA (hex) Apple, Inc.
+8CFABA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-23-32 (hex) Apple, Inc.
-002332 (base 16) Apple, Inc.
+5C-95-AE (hex) Apple, Inc.
+5C95AE (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-23-12 (hex) Apple, Inc.
-002312 (base 16) Apple, Inc.
+E0-C9-7A (hex) Apple, Inc.
+E0C97A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-19-E3 (hex) Apple, Inc.
-0019E3 (base 16) Apple, Inc.
+BC-52-B7 (hex) Apple, Inc.
+BC52B7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-14-51 (hex) Apple, Inc.
-001451 (base 16) Apple, Inc.
+14-10-9F (hex) Apple, Inc.
+14109F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-50-DC-E7 (hex) Amazon Technologies Inc.
-50DCE7 (base 16) Amazon Technologies Inc.
- P.O Box 8102
- Reno NV 89507
+0C-F8-93 (hex) ARRIS Group, Inc.
+0CF893 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-04-09-73 (hex) Hewlett Packard Enterprise
-040973 (base 16) Hewlett Packard Enterprise
- 8000 Foothills Blvd.
- Roseville CA 95747
+14-AB-F0 (hex) ARRIS Group, Inc.
+14ABF0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-4C-C2-06 (hex) Somfy
-4CC206 (base 16) Somfy
- 50 avenue du nouveau monde
- Cluses 74300
- FR
+AC-B3-13 (hex) ARRIS Group, Inc.
+ACB313 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-70-F2-20 (hex) Actiontec Electronics, Inc
-70F220 (base 16) Actiontec Electronics, Inc
- 760 North Mary Ave
- Sunnyvale CA 94085
+30-60-23 (hex) ARRIS Group, Inc.
+306023 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-28-57-67 (hex) Dish Technologies Corp
-285767 (base 16) Dish Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
+00-1D-D6 (hex) ARRIS Group, Inc.
+001DD6 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-70-55-F8 (hex) Cerebras Systems Inc
-7055F8 (base 16) Cerebras Systems Inc
- 175 S San Antonio Rd #100
- Los Altos CA 94022
+1C-1B-68 (hex) ARRIS Group, Inc.
+1C1B68 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-04-C9-D9 (hex) Dish Technologies Corp
-04C9D9 (base 16) Dish Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
+44-E1-37 (hex) ARRIS Group, Inc.
+44E137 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-00-24-AF (hex) Dish Technologies Corp
-0024AF (base 16) Dish Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
+E8-33-81 (hex) ARRIS Group, Inc.
+E83381 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-9C-43-1E (hex) IEEE Registration Authority
-9C431E (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
+84-61-A0 (hex) ARRIS Group, Inc.
+8461A0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-80-C5-48 (hex) Shenzhen Zowee Technology Co.,Ltd
-80C548 (base 16) Shenzhen Zowee Technology Co.,Ltd
- NO.5 Zowee technology building, Science & Technology industrial park of privately Science & Technology industrial park of privately owned enterprises
- Shenzhen GuangDong 518055
- CN
+60-19-71 (hex) ARRIS Group, Inc.
+601971 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-6C-54-CD (hex) LAMPEX ELECTRONICS LIMITED
-6C54CD (base 16) LAMPEX ELECTRONICS LIMITED
- 6-2/231/B, Kukatpally,
- Hyderabad Telangana 500072
- IN
+00-00-CA (hex) ARRIS Group, Inc.
+0000CA (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-88-3D-24 (hex) Google, Inc.
-883D24 (base 16) Google, Inc.
- 1600 Amphitheatre Parkway
- Mountain View CA 94043
+00-15-96 (hex) ARRIS Group, Inc.
+001596 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-E8-DE-FB (hex) MESOTIC SAS
-E8DEFB (base 16) MESOTIC SAS
- 11, Avenue de la Division Leclerc
- Cachan 94230
- FR
+00-15-A2 (hex) ARRIS Group, Inc.
+0015A2 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-90-84-8B (hex) HDR10+ Technologies, LLC
-90848B (base 16) HDR10+ Technologies, LLC
- 3855 SW 153rd Drive
- Beaverton OR 97006
+00-13-11 (hex) ARRIS Group, Inc.
+001311 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-0C-23-69 (hex) Honeywell SPS
-0C2369 (base 16) Honeywell SPS
- 700 Visions Dr.
- Skaneateles Falls NY 13153
+7C-26-34 (hex) ARRIS Group, Inc.
+7C2634 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-8C-16-45 (hex) LCFC(HeFei) Electronics Technology co., ltd
-8C1645 (base 16) LCFC(HeFei) Electronics Technology co., ltd
- YunGu Road 3188-1
- Hefei Anhui 230000
- CN
+10-05-B1 (hex) ARRIS Group, Inc.
+1005B1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-B4-E9-A3 (hex) port GmbH
-B4E9A3 (base 16) port GmbH
- Regensburger Str. 7b
- Halle (S.) 06132
- DE
+10-86-8C (hex) ARRIS Group, Inc.
+10868C (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-6C-B6-CA (hex) DIVUS GmbH
-6CB6CA (base 16) DIVUS GmbH
- Pillhof 51
- Eppan 39057
- IT
+00-1D-D1 (hex) ARRIS Group, Inc.
+001DD1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-B8-DE-5E (hex) LONGCHEER TELECOMMUNICATION LIMITED
-B8DE5E (base 16) LONGCHEER TELECOMMUNICATION LIMITED
- Building 1,No.401,Caobao Rd
- Shanghai Xuhui District 200233
- CN
+00-26-D9 (hex) ARRIS Group, Inc.
+0026D9 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-DC-DD-24 (hex) Energica Motor Company SpA
-DCDD24 (base 16) Energica Motor Company SpA
- Via Cesare della Chiesa, 150
- MODENA (MO) Mo 41126
- IT
+28-C8-7A (hex) ARRIS Group, Inc.
+28C87A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-94-63-72 (hex) vivo Mobile Communication Co., Ltd.
-946372 (base 16) vivo Mobile Communication Co., Ltd.
- #283,BBK Road
- Wusha,Chang'An DongGuan City,Guangdong, 523860
- CN
+54-E2-E0 (hex) ARRIS Group, Inc.
+54E2E0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-44-9E-F9 (hex) vivo Mobile Communication Co., Ltd.
-449EF9 (base 16) vivo Mobile Communication Co., Ltd.
- #283,BBK Road
- Wusha,Chang'An DongGuan City,Guangdong, 523860
- CN
+A0-55-DE (hex) ARRIS Group, Inc.
+A055DE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-64-1C-B0 (hex) Samsung Electronics Co.,Ltd
-641CB0 (base 16) Samsung Electronics Co.,Ltd
- 129, Samsung-ro, Youngtongl-Gu
- Suwon Gyeonggi-Do 16677
- KR
+A0-C5-62 (hex) ARRIS Group, Inc.
+A0C562 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-8C-F9-57 (hex) RuiXingHengFang Network (Shenzhen) Co.,Ltd
-8CF957 (base 16) RuiXingHengFang Network (Shenzhen) Co.,Ltd
- Room 507, 2nd tower of KangTai biological building NO.6 KeFa Rd. NanShan District
- Shenzhen Guangdong 518057
- CN
+FC-6F-B7 (hex) ARRIS Group, Inc.
+FC6FB7 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-00-1B-D8 (hex) FLIR Systems Inc
-001BD8 (base 16) FLIR Systems Inc
- 65 Challenger Road
- Ridgefield Park NJ 07660-2103
+00-D0-37 (hex) ARRIS Group, Inc.
+00D037 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-20-36-5B (hex) Megafone Limited
-20365B (base 16) Megafone Limited
- Unit 702,7/F,Bankok Bank Building,NO.18 Bonham Strand West
- Hong Kong 999077
- HK
+18-35-D1 (hex) ARRIS Group, Inc.
+1835D1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-E8-DE-00 (hex) ChongQing GuanFang Technology Co.,LTD
-E8DE00 (base 16) ChongQing GuanFang Technology Co.,LTD
- 2F, A District,No.3 Middle Section of Mount Huangshan Avenue
- ChongQing ChongQing 401121
- CN
+4C-38-D8 (hex) ARRIS Group, Inc.
+4C38D8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-3C-DC-BC (hex) Samsung Electronics Co.,Ltd
-3CDCBC (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
+A8-9F-EC (hex) ARRIS Group, Inc.
+A89FEC (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-F4-71-90 (hex) Samsung Electronics Co.,Ltd
-F47190 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
+0C-EA-C9 (hex) ARRIS Group, Inc.
+0CEAC9 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-4C-77-6D (hex) Cisco Systems, Inc
-4C776D (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
+F8-8B-37 (hex) ARRIS Group, Inc.
+F88B37 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-FC-A6-CD (hex) Fiberhome Telecommunication Technologies Co.,LTD
-FCA6CD (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
+44-34-A7 (hex) ARRIS Group, Inc.
+4434A7 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-64-DB-8B (hex) Hangzhou Hikvision Digital Technology Co.,Ltd.
-64DB8B (base 16) Hangzhou Hikvision Digital Technology Co.,Ltd.
- No.555 Qianmo Road
- Hangzhou Zhejiang 310052
- CN
+00-18-A4 (hex) ARRIS Group, Inc.
+0018A4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-78-25-7A (hex) LEO Innovation Lab
-78257A (base 16) LEO Innovation Lab
- Silkegade 8
- Copenhagen K Denmark 1113
- DK
+00-1A-1B (hex) ARRIS Group, Inc.
+001A1B (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-A4-DA-22 (hex) IEEE Registration Authority
-A4DA22 (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
+00-14-9A (hex) ARRIS Group, Inc.
+00149A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-00-03-97 (hex) FireBrick Limited
-000397 (base 16) FireBrick Limited
- C/O Andrews & Arnold Ltd,
- Enterprise Court, Downmill Road Bracknell, Berks RG12 1QS
- GB
+00-13-71 (hex) ARRIS Group, Inc.
+001371 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-A8-61-0A (hex) ARDUINO AG
-A8610A (base 16) ARDUINO AG
- Corso San Gottardo 6A
- Chiasso 6830
- CH
+00-1D-BE (hex) ARRIS Group, Inc.
+001DBE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-60-97-DD (hex) MicroSys Electronics GmbH
-6097DD (base 16) MicroSys Electronics GmbH
- Muehlweg 1
- Sauerlach 82054
- DE
+00-1E-5A (hex) ARRIS Group, Inc.
+001E5A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-04-79-70 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-047970 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+00-1D-6B (hex) ARRIS Group, Inc.
+001D6B (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-C4-9F-4C (hex) HUAWEI TECHNOLOGIES CO.,LTD
-C49F4C (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+00-1C-C1 (hex) ARRIS Group, Inc.
+001CC1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-A0-57-E3 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-A057E3 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+00-1C-11 (hex) ARRIS Group, Inc.
+001C11 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-E0-E6-2E (hex) TCT mobile ltd
-E0E62E (base 16) TCT mobile ltd
- No.86 hechang 7th road, zhongkai, Hi-Tech District
- Hui Zhou Guang Dong 516006
- CN
+00-1F-7E (hex) ARRIS Group, Inc.
+001F7E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-00-A0-85 (hex) Private
-00A085 (base 16) Private
+00-24-95 (hex) ARRIS Group, Inc.
+002495 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-94-B8-6D (hex) Intel Corporate
-94B86D (base 16) Intel Corporate
- Lot 8, Jalan Hi-Tech 2/3
- Kulim Kedah 09000
- MY
+2C-9E-5F (hex) ARRIS Group, Inc.
+2C9E5F (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-F8-8B-37 (hex) ARRIS Group, Inc.
-F88B37 (base 16) ARRIS Group, Inc.
+C8-AA-21 (hex) ARRIS Group, Inc.
+C8AA21 (base 16) ARRIS Group, Inc.
6450 Sequence Drive
San Diego CA 92121
US
-30-FD-38 (hex) Google, Inc.
-30FD38 (base 16) Google, Inc.
- 1600 Amphitheatre Parkway
- Mountain View CA 94043
+34-1F-E4 (hex) ARRIS Group, Inc.
+341FE4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-18-50-2A (hex) SOARNEX
-18502A (base 16) SOARNEX
- NO.158, RUIHU ST., NEIHU DIST.,
- TAIPEI CITY TAIWAN (R.O.C.) 11494
- TW
+40-0D-10 (hex) ARRIS Group, Inc.
+400D10 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-58-7A-6A (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-587A6A (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
- NO.18 HAIBIN ROAD,
- DONG GUAN GUANG DONG 523860
- CN
+00-1A-DB (hex) ARRIS Group, Inc.
+001ADB (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-E4-C4-83 (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-E4C483 (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
- NO.18 HAIBIN ROAD,
- DONG GUAN GUANG DONG 523860
- CN
+00-23-75 (hex) ARRIS Group, Inc.
+002375 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-F4-E1-1E (hex) Texas Instruments
-F4E11E (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
+00-24-A1 (hex) ARRIS Group, Inc.
+0024A1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-30-45-11 (hex) Texas Instruments
-304511 (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
+A4-ED-4E (hex) ARRIS Group, Inc.
+A4ED4E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-34-03-DE (hex) Texas Instruments
-3403DE (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
+00-26-42 (hex) ARRIS Group, Inc.
+002642 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-10-E7-C6 (hex) Hewlett Packard
-10E7C6 (base 16) Hewlett Packard
- 11445 Compaq Center Drive
- Houston TX 77070
+00-15-CE (hex) ARRIS Group, Inc.
+0015CE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-20-F5-43 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-20F543 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
- CN
+00-20-40 (hex) ARRIS Group, Inc.
+002040 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-1C-1E-E3 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-1C1EE3 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
+00-11-AE (hex) ARRIS Group, Inc.
+0011AE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-0F-9F (hex) ARRIS Group, Inc.
+000F9F (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-0B-06 (hex) ARRIS Group, Inc.
+000B06 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-15-2F (hex) ARRIS Group, Inc.
+00152F (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-11-1A (hex) ARRIS Group, Inc.
+00111A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-16-26 (hex) ARRIS Group, Inc.
+001626 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-CF-C0 (hex) China Mobile Group Device Co.,Ltd.
+00CFC0 (base 16) China Mobile Group Device Co.,Ltd.
+ 32 Xuanwumen West Street,Xicheng District
+ Beijing 100053
CN
-0C-91-60 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-0C9160 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
+0C-73-EB (hex) IEEE Registration Authority
+0C73EB (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+10-65-30 (hex) Dell Inc.
+106530 (base 16) Dell Inc.
+ One Dell Way
+ Round Rock TX 78682
+ US
+
+9C-7F-57 (hex) DERA Co. Ltd
+9C7F57 (base 16) DERA Co. Ltd
+ Huilongguan Dongdajie No.338, Building A Room 506, Changping District
+ Beijing 102208
CN
-0C-62-A6 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-0C62A6 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
+B4-E0-1D (hex) CONCEPTION ELECTRONIQUE
+B4E01D (base 16) CONCEPTION ELECTRONIQUE
+ 3 boulevard de l'europe
+ NEUFCHATEL EN BRAY 76270
+ FR
+
+1C-00-42 (hex) NARI Technology Co., Ltd.
+1C0042 (base 16) NARI Technology Co., Ltd.
+ NO.19 Chengxin Avenue, Nanjing
+ Nanjing 211106
CN
-7C-49-EB (hex) XIAOMI Electronics,CO.,LTD
-7C49EB (base 16) XIAOMI Electronics,CO.,LTD
- Xiaomi Building, No.68 Qinghe Middle Street,Haidian District
- Beijing Beijing 100085
+70-1D-08 (hex) 99IOT Shenzhen co.,ltd
+701D08 (base 16) 99IOT Shenzhen co.,ltd
+ 609C north block, Cangsong Building, Tairan Seven Road, Futian District
+ Shenzhen Guangdong 518000
CN
-C4-33-06 (hex) China Mobile Group Device Co.,Ltd.
-C43306 (base 16) China Mobile Group Device Co.,Ltd.
- 32 Xuanwumen West Street,Xicheng District
- Beijing 100053
+00-E0-09 (hex) Stratus Technologies
+00E009 (base 16) Stratus Technologies
+ 5 Mill and Main Place, Suite 500
+ Maynard MA 01754
+ US
+
+30-0A-C5 (hex) Ruio telecommunication technologies Co., Limited
+300AC5 (base 16) Ruio telecommunication technologies Co., Limited
+ Room 2501, Broadegate Software Building, No,1003 Keyuan Road,
+ Shenzhen guangdong 518000
CN
-68-FE-DA (hex) Fiberhome Telecommunication Technologies Co.,LTD
-68FEDA (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
+3C-24-F0 (hex) IEEE Registration Authority
+3C24F0 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+C8-86-29 (hex) Shenzhen Duubee Intelligent Technologies Co.,LTD.
+C88629 (base 16) Shenzhen Duubee Intelligent Technologies Co.,LTD.
+ 9F, Block B, Unicenter, Xin’an Sub district, Bao’an District
+ Shenzhen GuangDong 518000
CN
-0C-6A-BC (hex) Fiberhome Telecommunication Technologies Co.,LTD
-0C6ABC (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
+A0-E6-17 (hex) MATIS
+A0E617 (base 16) MATIS
+ 2/F,Hatchobori MIYATA Bldg.,1-8-2,
+ Shintomi,Chuo-Ku, Tokyo 104-0041
+ JP
+
+84-0D-8E (hex) Espressif Inc.
+840D8E (base 16) Espressif Inc.
+ Room 204, Building 2, 690 Bibo Road, Pudong New Area
+ Shanghai Shanghai 201203
CN
-D4-C1-9E (hex) Ruckus Wireless
-D4C19E (base 16) Ruckus Wireless
- 350 West Java Drive
- Sunnyvale CA 94089
- US
+50-5B-C2 (hex) Liteon Technology Corporation
+505BC2 (base 16) Liteon Technology Corporation
+ 4F, 90, Chien 1 Road
+ New Taipei City Taiwan 23585
+ TW
-00-01-B9 (hex) SKF (U.K.) Limited
-0001B9 (base 16) SKF (U.K.) Limited
- 2 Michaelson Square Kirkton Campus
- Livingston West Lothian EH54 7DP
- GB
+D8-32-E3 (hex) Xiaomi Communications Co Ltd
+D832E3 (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
-64-C3-D6 (hex) Juniper Networks
-64C3D6 (base 16) Juniper Networks
- 1133 Innovation Way
- Sunnyvale CA 94089
+FC-90-FA (hex) Independent Technologies
+FC90FA (base 16) Independent Technologies
+ 1960 Ridgeview Rd
+ Blair NE 68008
US
58-46-E1 (hex) Baxter International Inc
@@ -58451,12 +58985,6 @@ CC4EEC (base 16) HUMAX Co., Ltd. Seongnam-si Gyeonggi-do 463-875
KR
-DC-33-0D (hex) Qingdao Haier Telecom Co.,Ltd
-DC330D (base 16) Qingdao Haier Telecom Co.,Ltd
- No 1 Haier road,Hi-tech Zone,Qingdao,PR.China
- Qingdao Shandong 266101
- CN
-
00-80-E1 (hex) STMicroelectronics SRL
0080E1 (base 16) STMicroelectronics SRL
1000 AZTEC WEST
@@ -66023,12 +66551,6 @@ A893E6 (base 16) JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LT Enschede 7544RT
NL
-00-25-0C (hex) Enertrac
-00250C (base 16) Enertrac
- 94 River Rd
- Hudson NH 03051
- US
-
00-25-05 (hex) eks Engel GmbH & Co. KG
002505 (base 16) eks Engel GmbH & Co. KG
Schuetzenstrasse 2
@@ -73898,12 +74420,6 @@ A06A00 (base 16) Verilink Corporation SE
-00-04-FC (hex) Stratus Computer (DE), Inc.
-0004FC (base 16) Stratus Computer (DE), Inc.
- 111 Powdermill Road
- Maynard MA 01754
- US
-
00-04-F6 (hex) Amphus
0004F6 (base 16) Amphus
2372 Qume Drive, #F
@@ -77774,12 +78290,6 @@ A06A00 (base 16) Verilink Corporation BALDWIN PARK CA 91706
US
-00-20-0E (hex) SATELLITE TECHNOLOGY MGMT, INC
-00200E (base 16) SATELLITE TECHNOLOGY MGMT, INC
- 3530 HYLAND AVENUE
- COSTA MESA CA 92626
- US
-
00-20-96 (hex) Invensys
002096 (base 16) Invensys
Robershaw Industrial Products
@@ -78716,12 +79226,6 @@ A06A00 (base 16) Verilink Corporation LA HABRA CA 90632
US
-00-00-A8 (hex) STRATUS COMPUTER INC.
-0000A8 (base 16) STRATUS COMPUTER INC.
- 111 Powdermill Road
- Maynard MA 01754
- US
-
00-00-DF (hex) BELL & HOWELL PUB SYS DIV
0000DF (base 16) BELL & HOWELL PUB SYS DIV
OLD MANSFIELD ROAD
@@ -81356,12 +81860,6 @@ D8D43C (base 16) Sony Corporation Zhongshan Guangdong 528467
CN
-00-25-D4 (hex) General Dynamics Mission Systems
-0025D4 (base 16) General Dynamics Mission Systems
- 150 Rustcraft Road
- Dedham MA 02026
- US
-
5C-A8-6A (hex) HUAWEI TECHNOLOGIES CO.,LTD
5CA86A (base 16) HUAWEI TECHNOLOGIES CO.,LTD
No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
@@ -83879,294 +84377,12 @@ B877C3 (base 16) METER Group Pullman WA 99163
US
-00-36-76 (hex) ARRIS Group, Inc.
-003676 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-84-E0-58 (hex) ARRIS Group, Inc.
-84E058 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
F0-74-85 (hex) NGD Systems, Inc.
F07485 (base 16) NGD Systems, Inc.
355 Goddard, Suite 200
Irvine CA 92618
US
-34-7A-60 (hex) ARRIS Group, Inc.
-347A60 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-BC-64-4B (hex) ARRIS Group, Inc.
-BC644B (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-F8-A0-97 (hex) ARRIS Group, Inc.
-F8A097 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-94-E8-C5 (hex) ARRIS Group, Inc.
-94E8C5 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-04-4E-5A (hex) ARRIS Group, Inc.
-044E5A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-74-EA-E8 (hex) ARRIS Group, Inc.
-74EAE8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-A8-11-FC (hex) ARRIS Group, Inc.
-A811FC (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-74-56-12 (hex) ARRIS Group, Inc.
-745612 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E4-64-49 (hex) ARRIS Group, Inc.
-E46449 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-C0-05-C2 (hex) ARRIS Group, Inc.
-C005C2 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-64-55-B1 (hex) ARRIS Group, Inc.
-6455B1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-20-3D-66 (hex) ARRIS Group, Inc.
-203D66 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-D4-04-CD (hex) ARRIS Group, Inc.
-D404CD (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-44-6A-B7 (hex) ARRIS Group, Inc.
-446AB7 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-2C-99-24 (hex) ARRIS Group, Inc.
-2C9924 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1B-DD (hex) ARRIS Group, Inc.
-001BDD (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-14-04 (hex) ARRIS Group, Inc.
-001404 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-19-5E (hex) ARRIS Group, Inc.
-00195E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1A-AD (hex) ARRIS Group, Inc.
-001AAD (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-A4-7A-A4 (hex) ARRIS Group, Inc.
-A47AA4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-1C-14-48 (hex) ARRIS Group, Inc.
-1C1448 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-24-93 (hex) ARRIS Group, Inc.
-002493 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-40-FC-89 (hex) ARRIS Group, Inc.
-40FC89 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-3C-75-4A (hex) ARRIS Group, Inc.
-3C754A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-24-C1 (hex) ARRIS Group, Inc.
-0024C1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-21-36 (hex) ARRIS Group, Inc.
-002136 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-22-B4 (hex) ARRIS Group, Inc.
-0022B4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-23-95 (hex) ARRIS Group, Inc.
-002395 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-23-ED (hex) ARRIS Group, Inc.
-0023ED (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1B-52 (hex) ARRIS Group, Inc.
-001B52 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-23-0B (hex) ARRIS Group, Inc.
-00230B (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1E-8D (hex) ARRIS Group, Inc.
-001E8D (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-23-A2 (hex) ARRIS Group, Inc.
-0023A2 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-D1 (hex) ARRIS Group, Inc.
-0015D1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-D3 (hex) ARRIS Group, Inc.
-001DD3 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E8-89-2C (hex) ARRIS Group, Inc.
-E8892C (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E8-3E-FC (hex) ARRIS Group, Inc.
-E83EFC (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-70-7E-43 (hex) ARRIS Group, Inc.
-707E43 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-03-E0 (hex) ARRIS Group, Inc.
-0003E0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-12-8A (hex) ARRIS Group, Inc.
-00128A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-12-25 (hex) ARRIS Group, Inc.
-001225 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-08-3E-0C (hex) ARRIS Group, Inc.
-083E0C (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-8C-09-F4 (hex) ARRIS Group, Inc.
-8C09F4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-3C-DF-A9 (hex) ARRIS Group, Inc.
-3CDFA9 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-10-56-11 (hex) ARRIS Group, Inc.
-105611 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
2C-3A-E8 (hex) Espressif Inc.
2C3AE8 (base 16) Espressif Inc.
Room 204, Building 2, 690 Bibo Road, Pudong New Area
@@ -84191,12 +84407,6 @@ E8B6C2 (base 16) Juniper Networks Sunnyvale CA 94089
US
-B0-DA-F9 (hex) ARRIS Group, Inc.
-B0DAF9 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
74-F6-1C (hex) HTC Corporation
74F61C (base 16) HTC Corporation
No. 23, Xinghua Rd., Taoyuan City
@@ -84677,12 +84887,6 @@ FC7F56 (base 16) CoSyst Control Systems GmbH Santa Rosa CA 95407
US
-18-B8-1F (hex) ARRIS Group, Inc.
-18B81F (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
00-C0-64 (hex) General Datacomm LLC
00C064 (base 16) General Datacomm LLC
353 Christian Street, Suite 4
@@ -85004,12 +85208,6 @@ CC5A53 (base 16) Cisco Systems, Inc San Jose CA 94568
US
-BC-2E-48 (hex) ARRIS Group, Inc.
-BC2E48 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
94-00-06 (hex) jinyoung
940006 (base 16) jinyoung
1000 Dongil-ro Nowon-gu Seoul
@@ -85511,12 +85709,6 @@ FC9DD8 (base 16) Beijing TongTongYiLian Science and Technology Ltd. Hangzhou Zhejiang 310052
CN
-58-19-F8 (hex) ARRIS Group, Inc.
-5819F8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
20-78-52 (hex) Nokia
207852 (base 16) Nokia
Karaportti 3
@@ -85886,6 +86078,246 @@ DC4EF4 (base 16) Shenzhen MTN Electronics CO., Ltd Shenzhen Guangdong 518117
CN
+40-CD-7A (hex) Qingdao Hisense Communications Co.,Ltd.
+40CD7A (base 16) Qingdao Hisense Communications Co.,Ltd.
+ Qianwangang Road 218
+ Qingdao Shandong 266510
+ CN
+
+7C-A1-77 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+7CA177 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+E4-0E-EE (hex) HUAWEI TECHNOLOGIES CO.,LTD
+E40EEE (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+20-47-DA (hex) Xiaomi Communications Co Ltd
+2047DA (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+10-1D-51 (hex) 8Mesh Networks Limited
+101D51 (base 16) 8Mesh Networks Limited
+ Unit 607, 6/F, Yen Sheng Centre,
+ 64 Hoi Yuen Road Kwun Tong 000
+ HK
+
+80-35-C1 (hex) Xiaomi Communications Co Ltd
+8035C1 (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+78-B6-EC (hex) Scuf Gaming International LLC
+78B6EC (base 16) Scuf Gaming International LLC
+ 3970 Johns Creek Court Suite 325 Suwanee
+ Atlanta GA 30024
+ US
+
+00-25-D4 (hex) General Dynamics Mission Systems
+0025D4 (base 16) General Dynamics Mission Systems
+ 150 Rustcraft Road
+ Dedham MA 02026
+ US
+
+D0-76-E7 (hex) TP-LINK TECHNOLOGIES CO.,LTD.
+D076E7 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
+ Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
+ Shenzhen Guangdong 518057
+ CN
+
+DC-29-19 (hex) AltoBeam (Xiamen) Technology Ltd, Co.
+DC2919 (base 16) AltoBeam (Xiamen) Technology Ltd, Co.
+ South Building 203-38,Huoju Square ,No.56-58,Huoju Road, Huoju Park, Huoju High-tech District
+ Xiamen 361000
+ CN
+
+00-58-3F (hex) PC Aquarius
+00583F (base 16) PC Aquarius
+ Comcity Office Park, Kievskoe shosse, est.6, bld. 1, Rumyantsevo, Moscow, 108811, RF
+ Moscow 108811
+ RU
+
+F0-9C-D7 (hex) Guangzhou Blue Cheetah Intelligent Technology Co., Ltd.
+F09CD7 (base 16) Guangzhou Blue Cheetah Intelligent Technology Co., Ltd.
+ Panyu District, Guangzhou City Panyu Avenue North 555 Panyu Energy Technology Park,Industry Building 2 seats 406-407
+ Guangzhou Guangdong 511400
+ CN
+
+00-20-0E (hex) NSSLGlobal Technologies AS
+00200E (base 16) NSSLGlobal Technologies AS
+ Martin Linges vei 25
+ Fornebu 1364
+ NO
+
+E0-38-3F (hex) zte corporation
+E0383F (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+00-25-0C (hex) Senet Inc
+00250C (base 16) Senet Inc
+ 100 Market Street, Suite 302
+ Portsmouth NH 03801
+ US
+
+DC-33-0D (hex) QING DAO HAIER TELECOM CO.,LTD.
+DC330D (base 16) QING DAO HAIER TELECOM CO.,LTD.
+ No 1 Haier road,Hi-tech Zone,Qingdao,PR.China
+ Qingdao Shandong 266101
+ CN
+
+E8-3E-FC (hex) ARRIS Group, Inc.
+E83EFC (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+E8-89-2C (hex) ARRIS Group, Inc.
+E8892C (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1D-D3 (hex) ARRIS Group, Inc.
+001DD3 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-15-D1 (hex) ARRIS Group, Inc.
+0015D1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+3C-DF-A9 (hex) ARRIS Group, Inc.
+3CDFA9 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+8C-09-F4 (hex) ARRIS Group, Inc.
+8C09F4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+08-3E-0C (hex) ARRIS Group, Inc.
+083E0C (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+44-6A-B7 (hex) ARRIS Group, Inc.
+446AB7 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+D4-04-CD (hex) ARRIS Group, Inc.
+D404CD (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+10-56-11 (hex) ARRIS Group, Inc.
+105611 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+2C-99-24 (hex) ARRIS Group, Inc.
+2C9924 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+64-55-B1 (hex) ARRIS Group, Inc.
+6455B1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+C0-05-C2 (hex) ARRIS Group, Inc.
+C005C2 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+20-3D-66 (hex) ARRIS Group, Inc.
+203D66 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+40-F0-4E (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
+40F04E (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
+ Phase 3, Bayan Lepas FIZ
+ Bayan Lepas Penang 11900
+ MY
+
+58-DB-15 (hex) TECNO MOBILE LIMITED
+58DB15 (base 16) TECNO MOBILE LIMITED
+ ROOMS 05-15, 13A/F., SOUTH TOWER, WORLD FINANCE CENTRE, HARBOUR CITY, 17 CANTON ROAD, TSIM SHA TSUI, KOWLOON, HONG KONG
+ Hong Kong Hong Kong 999077
+ HK
+
+44-66-FC (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+4466FC (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+38-35-FB (hex) Sagemcom Broadband SAS
+3835FB (base 16) Sagemcom Broadband SAS
+ 250, route de l'Empereur
+ Rueil Malmaison Cedex hauts de seine 92848
+ FR
+
+00-00-A8 (hex) Stratus Technologies
+0000A8 (base 16) Stratus Technologies
+ 5 Mill and Main Place, Suite 500
+ Maynard MA 01754
+ US
+
+00-04-FC (hex) Stratus Technologies
+0004FC (base 16) Stratus Technologies
+ 5 Mill and Main Place, Suite 500
+ Maynard MA 01754
+ US
+
+00-CB-B4 (hex) SHENZHEN ATEKO PHOTOELECTRICITY CO.,LTD
+00CBB4 (base 16) SHENZHEN ATEKO PHOTOELECTRICITY CO.,LTD
+ 4-5F,E1 Building,TCL International E City,No.1001 Zhongshanyuan Road,Nanshan District,Shenzhen
+ SHENZHEN GUANGDONG 518052
+ CN
+
+70-79-B3 (hex) Cisco Systems, Inc
+7079B3 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+0C-B3-4F (hex) Shenzhen Xiaoqi Intelligent Technology Co., Ltd.
+0CB34F (base 16) Shenzhen Xiaoqi Intelligent Technology Co., Ltd.
+ Room 1501, Block B4, Building 9, Section 2, Shenzhen Bay Science & Technology Ecological Park, West Shahe Road, Nanshan District,
+ Shenzhen Guangdong 518000
+ CN
+
+F0-4C-D5 (hex) Maxlinear, Inc
+F04CD5 (base 16) Maxlinear, Inc
+ 5966 La Place Ct. Ste# 100
+ Carlsbad CA 92008
+ US
+
AC-F8-5C (hex) Private
ACF85C (base 16) Private
@@ -85895,224 +86327,488 @@ D460E3 (base 16) Sercomm Corporation. Miao-Lih Hsuan 115
TW
-D0-25-98 (hex) Apple, Inc.
-D02598 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
+A0-39-EE (hex) Sagemcom Broadband SAS
+A039EE (base 16) Sagemcom Broadband SAS
+ 250, route de l'Empereur
+ Rueil Malmaison Cedex hauts de seine 92848
+ FR
+
+A4-40-27 (hex) zte corporation
+A44027 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+1C-11-61 (hex) Ciena Corporation
+1C1161 (base 16) Ciena Corporation
+ 7035 Ridge Road
+ Hanover MD 21076
US
-A8-66-7F (hex) Apple, Inc.
-A8667F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
+4C-82-CF (hex) Dish Technologies Corp
+4C82CF (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
US
-70-14-A6 (hex) Apple, Inc.
-7014A6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
+F0-C9-D1 (hex) GD Midea Air-Conditioning Equipment Co.,Ltd.
+F0C9D1 (base 16) GD Midea Air-Conditioning Equipment Co.,Ltd.
+ Midea Global Innovation Center,Beijiao Town,Shunde
+ Foshan Guangdong 528311
+ CN
+
+D4-9C-F4 (hex) Palo Alto Networks
+D49CF4 (base 16) Palo Alto Networks
+ 3000 Tannery Way
+ Santa Clara CA 95054
US
-10-41-7F (hex) Apple, Inc.
-10417F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
+3C-57-4F (hex) China Mobile Group Device Co.,Ltd.
+3C574F (base 16) China Mobile Group Device Co.,Ltd.
+ 32 Xuanwumen West Street,Xicheng District
+ Beijing 100053
+ CN
+
+50-6B-4B (hex) Mellanox Technologies, Inc.
+506B4B (base 16) Mellanox Technologies, Inc.
+ 350 Oakmead Parkway, Suite 100
+ Sunnyvale CA 94085
US
-AC-29-3A (hex) Apple, Inc.
-AC293A (base 16) Apple, Inc.
+F8-C1-20 (hex) Xi'an Link-Science Technology Co.,Ltd
+F8C120 (base 16) Xi'an Link-Science Technology Co.,Ltd
+ 1/F,Block F,Building zhichao Weilai,No.999,10#Caotan Road,Xi'an
+ xi'an 710016
+ CN
+
+90-3A-72 (hex) Ruckus Wireless
+903A72 (base 16) Ruckus Wireless
+ 350 West Java Drive
+ Sunnyvale CA 94089
+ US
+
+3C-E8-24 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+3CE824 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+E8-AB-F3 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+E8ABF3 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+70-06-AC (hex) Eastcompeace Technology Co., Ltd
+7006AC (base 16) Eastcompeace Technology Co., Ltd
+ Number 8 Pinggong Zhong Road,Nanping S&T Industry Community,Zhuhai,Guangdong,519060 China
+ Zhuhai Guangdong 519060
+ CN
+
+50-6F-77 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+506F77 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+60-98-13 (hex) Shanghai Visking Digital Technology Co. LTD
+609813 (base 16) Shanghai Visking Digital Technology Co. LTD
+ Room 1301, Building A8, No.1688 Guoquan North Road, Yangpu District
+ Shanghai 200082
+ CN
+
+8C-4C-AD (hex) Evoluzn Inc.
+8C4CAD (base 16) Evoluzn Inc.
+ 34 Samoset Lane
+ Schaumburg IL 60193
+ US
+
+A4-D4-B2 (hex) Shenzhen MeiG Smart Technology Co.,Ltd
+A4D4B2 (base 16) Shenzhen MeiG Smart Technology Co.,Ltd
+ #88 Qinjiang Road, Xuhui District
+ Shanghai 200233
+ CN
+
+DC-E5-33 (hex) IEEE Registration Authority
+DCE533 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+8C-F7-10 (hex) AMPAK Technology, Inc.
+8CF710 (base 16) AMPAK Technology, Inc.
+ No.1,Jen Ai Road Hsinchu Industrial Park, Hukou
+ Hsinchu Taiwan ROC. 30352
+ TW
+
+38-E1-AA (hex) zte corporation
+38E1AA (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+18-A2-8A (hex) Essel-T Co., Ltd
+18A28A (base 16) Essel-T Co., Ltd
+ 1211 kranztechno, 388 Dunchon-daero
+ Seongnam-si Jungwon-gu, Gyeonggi-do 13403
+ KR
+
+38-DE-AD (hex) Intel Corporate
+38DEAD (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+74-E1-82 (hex) Texas Instruments
+74E182 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+40-BD-32 (hex) Texas Instruments
+40BD32 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+3C-17-10 (hex) Sagemcom Broadband SAS
+3C1710 (base 16) Sagemcom Broadband SAS
+ 250, route de l'Empereur
+ Rueil Malmaison Cedex hauts de seine 92848
+ FR
+
+C8-FA-E1 (hex) ARQ Digital LLC
+C8FAE1 (base 16) ARQ Digital LLC
+ 2430 Auto Park Way
+ Escondido CA 92029
+ US
+
+80-AD-16 (hex) Xiaomi Communications Co Ltd
+80AD16 (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+04-4E-AF (hex) LG Innotek
+044EAF (base 16) LG Innotek
+ 26, Hanamsandan 5beon-ro
+ Gwangju Gwangsan-gu 506-731
+ KR
+
+DC-A3-33 (hex) Shenzhen YOUHUA Technology Co., Ltd
+DCA333 (base 16) Shenzhen YOUHUA Technology Co., Ltd
+ Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
+ Shenzhen Guangdong 518055
+ CN
+
+BC-DD-C2 (hex) Espressif Inc.
+BCDDC2 (base 16) Espressif Inc.
+ Room 204, Building 2, 690 Bibo Road, Pudong New Area
+ Shanghai Shanghai 201203
+ CN
+
+FC-7C-02 (hex) Phicomm (Shanghai) Co., Ltd.
+FC7C02 (base 16) Phicomm (Shanghai) Co., Ltd.
+ 3666 SiXian Rd.,Songjiang District
+ Shanghai Shanghai 201616
+ CN
+
+88-A9-A7 (hex) IEEE Registration Authority
+88A9A7 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+F0-E3-DC (hex) Tecon MT, LLC
+F0E3DC (base 16) Tecon MT, LLC
+ 3rd Khoroshevskaya st - 20
+ Moscow 123298
+ RU
+
+30-B2-16 (hex) ABB AG - Power Grids - Grid Automation
+30B216 (base 16) ABB AG - Power Grids - Grid Automation
+ Kallstadter Strasse 1
+ Mannheim 68309
+ DE
+
+00-D0-CE (hex) iSystem Labs
+00D0CE (base 16) iSystem Labs
+ BRODISCE 7, 10C
+ Trzin 1236
+ SI
+
+00-BE-75 (hex) Cisco Systems, Inc
+00BE75 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+50-4E-DC (hex) Ping Communication
+504EDC (base 16) Ping Communication
+ Brenden 18
+ Appenzell Meistersrüte AI 9050
+ CH
+
+20-67-7C (hex) Hewlett Packard Enterprise
+20677C (base 16) Hewlett Packard Enterprise
+ 8000 Foothills Blvd.
+ Roseville CA 95747
+ US
+
+C4-2C-4F (hex) Qingdao Hisense Mobile Communication Technology Co,Ltd
+C42C4F (base 16) Qingdao Hisense Mobile Communication Technology Co,Ltd
+ No.399, Song Ling Road
+ Qingdao Shandong 266100
+ CN
+
+24-CA-CB (hex) Fiberhome Telecommunication Technologies Co.,LTD
+24CACB (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+44-FF-BA (hex) zte corporation
+44FFBA (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+00-23-A8 (hex) Marshall Electronics
+0023A8 (base 16) Marshall Electronics
+ 20608 Madrona Ave
+ Torrance CA 90503
+ US
+
+B4-81-BF (hex) Meta-Networks, LLC
+B481BF (base 16) Meta-Networks, LLC
+ Office 106C, 5/2, Varshavskaya street
+ Saint-Petersburg Saint-Petersburg 196128
+ RU
+
+0C-AE-7D (hex) Texas Instruments
+0CAE7D (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+64-1C-AE (hex) Samsung Electronics Co.,Ltd
+641CAE (base 16) Samsung Electronics Co.,Ltd
+ 129, Samsung-ro, Youngtongl-Gu
+ Suwon Gyeonggi-Do 16677
+ KR
+
+40-50-B5 (hex) Shenzhen New Species Technology Co., Ltd.
+4050B5 (base 16) Shenzhen New Species Technology Co., Ltd.
+ Room 1827,Building R&D,EVOC intelligence valley,No 11,Gao xin west road,Guangming New District
+ Shenzhen 518107
+ CN
+
+4C-D0-CB (hex) HUAWEI TECHNOLOGIES CO.,LTD
+4CD0CB (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+38-BA-F8 (hex) Intel Corporate
+38BAF8 (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+A4-E9-75 (hex) Apple, Inc.
+A4E975 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-94-E9-6A (hex) Apple, Inc.
-94E96A (base 16) Apple, Inc.
+C0-A5-3E (hex) Apple, Inc.
+C0A53E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-0C-4D-E9 (hex) Apple, Inc.
-0C4DE9 (base 16) Apple, Inc.
+98-00-C6 (hex) Apple, Inc.
+9800C6 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-90-72-40 (hex) Apple, Inc.
-907240 (base 16) Apple, Inc.
+78-7B-8A (hex) Apple, Inc.
+787B8A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A8-88-08 (hex) Apple, Inc.
-A88808 (base 16) Apple, Inc.
+38-66-F0 (hex) Apple, Inc.
+3866F0 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-E0-EB (hex) Apple, Inc.
-C8E0EB (base 16) Apple, Inc.
+20-EE-28 (hex) Apple, Inc.
+20EE28 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-54-E4-3A (hex) Apple, Inc.
-54E43A (base 16) Apple, Inc.
+08-F4-AB (hex) Apple, Inc.
+08F4AB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-28-E1-4C (hex) Apple, Inc.
-28E14C (base 16) Apple, Inc.
+8C-85-90 (hex) Apple, Inc.
+8C8590 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-84-8E-0C (hex) Apple, Inc.
-848E0C (base 16) Apple, Inc.
+68-EF-43 (hex) Apple, Inc.
+68EF43 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B0-34-95 (hex) Apple, Inc.
-B03495 (base 16) Apple, Inc.
+CC-2D-B7 (hex) Apple, Inc.
+CC2DB7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-F6-1C (hex) Apple, Inc.
-F0F61C (base 16) Apple, Inc.
+D4-A3-3D (hex) Apple, Inc.
+D4A33D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-0C-30-21 (hex) Apple, Inc.
-0C3021 (base 16) Apple, Inc.
+E4-E0-A6 (hex) Apple, Inc.
+E4E0A6 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D8-96-95 (hex) Apple, Inc.
-D89695 (base 16) Apple, Inc.
+70-EF-00 (hex) Apple, Inc.
+70EF00 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-64-9A-BE (hex) Apple, Inc.
-649ABE (base 16) Apple, Inc.
+B0-CA-68 (hex) Apple, Inc.
+B0CA68 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-5C-F5-DA (hex) Apple, Inc.
-5CF5DA (base 16) Apple, Inc.
+98-10-E8 (hex) Apple, Inc.
+9810E8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-20-A2-E4 (hex) Apple, Inc.
-20A2E4 (base 16) Apple, Inc.
+B4-9C-DF (hex) Apple, Inc.
+B49CDF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-24-75 (hex) Apple, Inc.
-F02475 (base 16) Apple, Inc.
+DC-A4-CA (hex) Apple, Inc.
+DCA4CA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-24-A0-74 (hex) Apple, Inc.
-24A074 (base 16) Apple, Inc.
+8C-8F-E9 (hex) Apple, Inc.
+8C8FE9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-88-63-DF (hex) Apple, Inc.
-8863DF (base 16) Apple, Inc.
+98-CA-33 (hex) Apple, Inc.
+98CA33 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-60-92-17 (hex) Apple, Inc.
-609217 (base 16) Apple, Inc.
+FC-25-3F (hex) Apple, Inc.
+FC253F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-34-E2-FD (hex) Apple, Inc.
-34E2FD (base 16) Apple, Inc.
+18-34-51 (hex) Apple, Inc.
+183451 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-0C-3E-9F (hex) Apple, Inc.
-0C3E9F (base 16) Apple, Inc.
+C0-84-7A (hex) Apple, Inc.
+C0847A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-70-9F (hex) Apple, Inc.
-6C709F (base 16) Apple, Inc.
+64-20-0C (hex) Apple, Inc.
+64200C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-40-08 (hex) Apple, Inc.
-6C4008 (base 16) Apple, Inc.
+74-E1-B6 (hex) Apple, Inc.
+74E1B6 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-5C-97-F3 (hex) Apple, Inc.
-5C97F3 (base 16) Apple, Inc.
+0C-77-1A (hex) Apple, Inc.
+0C771A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-90-FD-61 (hex) Apple, Inc.
-90FD61 (base 16) Apple, Inc.
+00-F4-B9 (hex) Apple, Inc.
+00F4B9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-61-71 (hex) Apple, Inc.
-006171 (base 16) Apple, Inc.
+C8-33-4B (hex) Apple, Inc.
+C8334B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-80-E6-50 (hex) Apple, Inc.
-80E650 (base 16) Apple, Inc.
+B8-F6-B1 (hex) Apple, Inc.
+B8F6B1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-DC-2B-2A (hex) Apple, Inc.
-DC2B2A (base 16) Apple, Inc.
+C0-9F-42 (hex) Apple, Inc.
+C09F42 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-44-D9 (hex) Apple, Inc.
-B844D9 (base 16) Apple, Inc.
+18-9E-FC (hex) Apple, Inc.
+189EFC (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E0-F5-C6 (hex) Apple, Inc.
-E0F5C6 (base 16) Apple, Inc.
+6C-3E-6D (hex) Apple, Inc.
+6C3E6D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-94-94-26 (hex) Apple, Inc.
-949426 (base 16) Apple, Inc.
+8C-2D-AA (hex) Apple, Inc.
+8C2DAA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-CC-29-F5 (hex) Apple, Inc.
-CC29F5 (base 16) Apple, Inc.
+E4-E4-AB (hex) Apple, Inc.
+E4E4AB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
@@ -86135,74 +86831,86 @@ DC0C5C (base 16) Apple, Inc. Cupertino CA 95014
US
-DC-A4-CA (hex) Apple, Inc.
-DCA4CA (base 16) Apple, Inc.
+60-9A-C1 (hex) Apple, Inc.
+609AC1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-8C-8F-E9 (hex) Apple, Inc.
-8C8FE9 (base 16) Apple, Inc.
+F0-79-60 (hex) Apple, Inc.
+F07960 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-10-E8 (hex) Apple, Inc.
-9810E8 (base 16) Apple, Inc.
+9C-8B-A0 (hex) Apple, Inc.
+9C8BA0 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B4-9C-DF (hex) Apple, Inc.
-B49CDF (base 16) Apple, Inc.
+28-A0-2B (hex) Apple, Inc.
+28A02B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A4-E9-75 (hex) Apple, Inc.
-A4E975 (base 16) Apple, Inc.
+B4-4B-D2 (hex) Apple, Inc.
+B44BD2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C0-A5-3E (hex) Apple, Inc.
-C0A53E (base 16) Apple, Inc.
+9C-4F-DA (hex) Apple, Inc.
+9C4FDA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-00-C6 (hex) Apple, Inc.
-9800C6 (base 16) Apple, Inc.
+1C-5C-F2 (hex) Apple, Inc.
+1C5CF2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-7B-8A (hex) Apple, Inc.
-787B8A (base 16) Apple, Inc.
+38-71-DE (hex) Apple, Inc.
+3871DE (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-38-66-F0 (hex) Apple, Inc.
-3866F0 (base 16) Apple, Inc.
+BC-54-36 (hex) Apple, Inc.
+BC5436 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-20-EE-28 (hex) Apple, Inc.
-20EE28 (base 16) Apple, Inc.
+5C-F9-38 (hex) Apple, Inc.
+5CF938 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-08-F4-AB (hex) Apple, Inc.
-08F4AB (base 16) Apple, Inc.
+4C-32-75 (hex) Apple, Inc.
+4C3275 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-8C-85-90 (hex) Apple, Inc.
-8C8590 (base 16) Apple, Inc.
+2C-F0-A2 (hex) Apple, Inc.
+2CF0A2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+EC-AD-B8 (hex) Apple, Inc.
+ECADB8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-01-A7 (hex) Apple, Inc.
+9801A7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
@@ -86219,140 +86927,140 @@ E49A79 (base 16) Apple, Inc. Cupertino CA 95014
US
-28-A0-2B (hex) Apple, Inc.
-28A02B (base 16) Apple, Inc.
+40-6C-8F (hex) Apple, Inc.
+406C8F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B4-4B-D2 (hex) Apple, Inc.
-B44BD2 (base 16) Apple, Inc.
+00-C6-10 (hex) Apple, Inc.
+00C610 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-2C-F0-A2 (hex) Apple, Inc.
-2CF0A2 (base 16) Apple, Inc.
+70-DE-E2 (hex) Apple, Inc.
+70DEE2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-EC-AD-B8 (hex) Apple, Inc.
-ECADB8 (base 16) Apple, Inc.
+18-20-32 (hex) Apple, Inc.
+182032 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-01-A7 (hex) Apple, Inc.
-9801A7 (base 16) Apple, Inc.
+6C-C2-6B (hex) Apple, Inc.
+6CC26B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-60-9A-C1 (hex) Apple, Inc.
-609AC1 (base 16) Apple, Inc.
+10-40-F3 (hex) Apple, Inc.
+1040F3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-79-60 (hex) Apple, Inc.
-F07960 (base 16) Apple, Inc.
+00-1D-4F (hex) Apple, Inc.
+001D4F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-9C-8B-A0 (hex) Apple, Inc.
-9C8BA0 (base 16) Apple, Inc.
+00-1E-52 (hex) Apple, Inc.
+001E52 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-4C-32-75 (hex) Apple, Inc.
-4C3275 (base 16) Apple, Inc.
+00-1F-5B (hex) Apple, Inc.
+001F5B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E4-E4-AB (hex) Apple, Inc.
-E4E4AB (base 16) Apple, Inc.
+00-1F-F3 (hex) Apple, Inc.
+001FF3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-33-4B (hex) Apple, Inc.
-C8334B (base 16) Apple, Inc.
+00-21-E9 (hex) Apple, Inc.
+0021E9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-F4-B9 (hex) Apple, Inc.
-00F4B9 (base 16) Apple, Inc.
+00-23-6C (hex) Apple, Inc.
+00236C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-0C-77-1A (hex) Apple, Inc.
-0C771A (base 16) Apple, Inc.
+00-25-00 (hex) Apple, Inc.
+002500 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-74-E1-B6 (hex) Apple, Inc.
-74E1B6 (base 16) Apple, Inc.
+60-FB-42 (hex) Apple, Inc.
+60FB42 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-64-20-0C (hex) Apple, Inc.
-64200C (base 16) Apple, Inc.
+F8-1E-DF (hex) Apple, Inc.
+F81EDF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C0-84-7A (hex) Apple, Inc.
-C0847A (base 16) Apple, Inc.
+90-84-0D (hex) Apple, Inc.
+90840D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-18-34-51 (hex) Apple, Inc.
-183451 (base 16) Apple, Inc.
+D8-A2-5E (hex) Apple, Inc.
+D8A25E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-FC-25-3F (hex) Apple, Inc.
-FC253F (base 16) Apple, Inc.
+C8-BC-C8 (hex) Apple, Inc.
+C8BCC8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-10-40-F3 (hex) Apple, Inc.
-1040F3 (base 16) Apple, Inc.
+28-E7-CF (hex) Apple, Inc.
+28E7CF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-C2-6B (hex) Apple, Inc.
-6CC26B (base 16) Apple, Inc.
+D8-9E-3F (hex) Apple, Inc.
+D89E3F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-18-20-32 (hex) Apple, Inc.
-182032 (base 16) Apple, Inc.
+04-0C-CE (hex) Apple, Inc.
+040CCE (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-DE-E2 (hex) Apple, Inc.
-70DEE2 (base 16) Apple, Inc.
+A4-D1-D2 (hex) Apple, Inc.
+A4D1D2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-C6-10 (hex) Apple, Inc.
-00C610 (base 16) Apple, Inc.
+7C-FA-DF (hex) Apple, Inc.
+7CFADF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
@@ -86363,540 +87071,576 @@ FC253F (base 16) Apple, Inc. Cupertino CA 95014
US
-7C-FA-DF (hex) Apple, Inc.
-7CFADF (base 16) Apple, Inc.
+00-11-24 (hex) Apple, Inc.
+001124 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-5C-F9-38 (hex) Apple, Inc.
-5CF938 (base 16) Apple, Inc.
+80-C7-C5 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+80C7C5 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+FC-B7-F0 (hex) Idaho National Laboratory
+FCB7F0 (base 16) Idaho National Laboratory
+ 2525 N. Fremont Ave
+ Idaho Falls ID 83415
+ US
+
+E4-60-59 (hex) Pingtek Co., Ltd.
+E46059 (base 16) Pingtek Co., Ltd.
+ 5F., No.786, Zhongzheng Rd., Zhonghe Dist.
+ New Taipei City 235
+ TW
+
+6C-70-9F (hex) Apple, Inc.
+6C709F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-38-71-DE (hex) Apple, Inc.
-3871DE (base 16) Apple, Inc.
+0C-3E-9F (hex) Apple, Inc.
+0C3E9F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-BC-54-36 (hex) Apple, Inc.
-BC5436 (base 16) Apple, Inc.
+34-E2-FD (hex) Apple, Inc.
+34E2FD (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-9C-4F-DA (hex) Apple, Inc.
-9C4FDA (base 16) Apple, Inc.
+60-92-17 (hex) Apple, Inc.
+609217 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-1C-5C-F2 (hex) Apple, Inc.
-1C5CF2 (base 16) Apple, Inc.
+88-63-DF (hex) Apple, Inc.
+8863DF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-60-FB-42 (hex) Apple, Inc.
-60FB42 (base 16) Apple, Inc.
+80-E6-50 (hex) Apple, Inc.
+80E650 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-25-00 (hex) Apple, Inc.
-002500 (base 16) Apple, Inc.
+00-61-71 (hex) Apple, Inc.
+006171 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-23-6C (hex) Apple, Inc.
-00236C (base 16) Apple, Inc.
+90-FD-61 (hex) Apple, Inc.
+90FD61 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-21-E9 (hex) Apple, Inc.
-0021E9 (base 16) Apple, Inc.
+5C-97-F3 (hex) Apple, Inc.
+5C97F3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-1F-F3 (hex) Apple, Inc.
-001FF3 (base 16) Apple, Inc.
+6C-40-08 (hex) Apple, Inc.
+6C4008 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-1F-5B (hex) Apple, Inc.
-001F5B (base 16) Apple, Inc.
+24-A0-74 (hex) Apple, Inc.
+24A074 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-1E-52 (hex) Apple, Inc.
-001E52 (base 16) Apple, Inc.
+F0-24-75 (hex) Apple, Inc.
+F02475 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-1D-4F (hex) Apple, Inc.
-001D4F (base 16) Apple, Inc.
+20-A2-E4 (hex) Apple, Inc.
+20A2E4 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-11-24 (hex) Apple, Inc.
-001124 (base 16) Apple, Inc.
+5C-F5-DA (hex) Apple, Inc.
+5CF5DA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A8-FA-D8 (hex) Apple, Inc.
-A8FAD8 (base 16) Apple, Inc.
+64-9A-BE (hex) Apple, Inc.
+649ABE (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-5C-96-9D (hex) Apple, Inc.
-5C969D (base 16) Apple, Inc.
+94-E9-6A (hex) Apple, Inc.
+94E96A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E4-8B-7F (hex) Apple, Inc.
-E48B7F (base 16) Apple, Inc.
+AC-29-3A (hex) Apple, Inc.
+AC293A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-84-FC-FE (hex) Apple, Inc.
-84FCFE (base 16) Apple, Inc.
+10-41-7F (hex) Apple, Inc.
+10417F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-44-4C-0C (hex) Apple, Inc.
-444C0C (base 16) Apple, Inc.
+B8-44-D9 (hex) Apple, Inc.
+B844D9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-8C-2D-AA (hex) Apple, Inc.
-8C2DAA (base 16) Apple, Inc.
+DC-2B-2A (hex) Apple, Inc.
+DC2B2A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-3E-6D (hex) Apple, Inc.
-6C3E6D (base 16) Apple, Inc.
+14-20-5E (hex) Apple, Inc.
+14205E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-18-9E-FC (hex) Apple, Inc.
-189EFC (base 16) Apple, Inc.
+5C-1D-D9 (hex) Apple, Inc.
+5C1DD9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C0-9F-42 (hex) Apple, Inc.
-C09F42 (base 16) Apple, Inc.
+18-F1-D8 (hex) Apple, Inc.
+18F1D8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-F6-B1 (hex) Apple, Inc.
-B8F6B1 (base 16) Apple, Inc.
+F8-6F-C1 (hex) Apple, Inc.
+F86FC1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-40-6C-8F (hex) Apple, Inc.
-406C8F (base 16) Apple, Inc.
+F0-99-B6 (hex) Apple, Inc.
+F099B6 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A4-D1-D2 (hex) Apple, Inc.
-A4D1D2 (base 16) Apple, Inc.
+90-72-40 (hex) Apple, Inc.
+907240 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-0C-CE (hex) Apple, Inc.
-040CCE (base 16) Apple, Inc.
+0C-4D-E9 (hex) Apple, Inc.
+0C4DE9 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D8-9E-3F (hex) Apple, Inc.
-D89E3F (base 16) Apple, Inc.
+D8-96-95 (hex) Apple, Inc.
+D89695 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-28-E7-CF (hex) Apple, Inc.
-28E7CF (base 16) Apple, Inc.
+0C-30-21 (hex) Apple, Inc.
+0C3021 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-BC-C8 (hex) Apple, Inc.
-C8BCC8 (base 16) Apple, Inc.
+F0-F6-1C (hex) Apple, Inc.
+F0F61C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D8-A2-5E (hex) Apple, Inc.
-D8A25E (base 16) Apple, Inc.
+B0-34-95 (hex) Apple, Inc.
+B03495 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-90-84-0D (hex) Apple, Inc.
-90840D (base 16) Apple, Inc.
+84-8E-0C (hex) Apple, Inc.
+848E0C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F8-1E-DF (hex) Apple, Inc.
-F81EDF (base 16) Apple, Inc.
+94-94-26 (hex) Apple, Inc.
+949426 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B0-CA-68 (hex) Apple, Inc.
-B0CA68 (base 16) Apple, Inc.
+E0-F5-C6 (hex) Apple, Inc.
+E0F5C6 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-CA-33 (hex) Apple, Inc.
-98CA33 (base 16) Apple, Inc.
+28-E1-4C (hex) Apple, Inc.
+28E14C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-EF-43 (hex) Apple, Inc.
-68EF43 (base 16) Apple, Inc.
+54-E4-3A (hex) Apple, Inc.
+54E43A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-CC-2D-B7 (hex) Apple, Inc.
-CC2DB7 (base 16) Apple, Inc.
+C8-E0-EB (hex) Apple, Inc.
+C8E0EB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D4-A3-3D (hex) Apple, Inc.
-D4A33D (base 16) Apple, Inc.
+A8-88-08 (hex) Apple, Inc.
+A88808 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E4-E0-A6 (hex) Apple, Inc.
-E4E0A6 (base 16) Apple, Inc.
+44-4C-0C (hex) Apple, Inc.
+444C0C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-EF-00 (hex) Apple, Inc.
-70EF00 (base 16) Apple, Inc.
+84-FC-FE (hex) Apple, Inc.
+84FCFE (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A0-39-EE (hex) Sagemcom Broadband SAS
-A039EE (base 16) Sagemcom Broadband SAS
- 250, route de l'Empereur
- Rueil Malmaison Cedex hauts de seine 92848
- FR
+E4-8B-7F (hex) Apple, Inc.
+E48B7F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-A4-40-27 (hex) zte corporation
-A44027 (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
- CN
+5C-96-9D (hex) Apple, Inc.
+5C969D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-1C-11-61 (hex) Ciena Corporation
-1C1161 (base 16) Ciena Corporation
- 7035 Ridge Road
- Hanover MD 21076
+A8-FA-D8 (hex) Apple, Inc.
+A8FAD8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-4C-82-CF (hex) Dish Technologies Corp
-4C82CF (base 16) Dish Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
+70-14-A6 (hex) Apple, Inc.
+7014A6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-F0-C9-D1 (hex) GD Midea Air-Conditioning Equipment Co.,Ltd.
-F0C9D1 (base 16) GD Midea Air-Conditioning Equipment Co.,Ltd.
- Midea Global Innovation Center,Beijiao Town,Shunde
- Foshan Guangdong 528311
- CN
+A8-66-7F (hex) Apple, Inc.
+A8667F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-D4-9C-F4 (hex) Palo Alto Networks
-D49CF4 (base 16) Palo Alto Networks
- 3000 Tannery Way
- Santa Clara CA 95054
+D0-25-98 (hex) Apple, Inc.
+D02598 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-3C-57-4F (hex) China Mobile Group Device Co.,Ltd.
-3C574F (base 16) China Mobile Group Device Co.,Ltd.
- 32 Xuanwumen West Street,Xicheng District
- Beijing 100053
- CN
+CC-29-F5 (hex) Apple, Inc.
+CC29F5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-50-6B-4B (hex) Mellanox Technologies, Inc.
-506B4B (base 16) Mellanox Technologies, Inc.
- 350 Oakmead Parkway, Suite 100
- Sunnyvale CA 94085
+DC-D3-A2 (hex) Apple, Inc.
+DCD3A2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-F8-C1-20 (hex) Xi'an Link-Science Technology Co.,Ltd
-F8C120 (base 16) Xi'an Link-Science Technology Co.,Ltd
- 1/F,Block F,Building zhichao Weilai,No.999,10#Caotan Road,Xi'an
- xi'an 710016
- CN
+40-FC-89 (hex) ARRIS Group, Inc.
+40FC89 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-90-3A-72 (hex) Ruckus Wireless
-903A72 (base 16) Ruckus Wireless
- 350 West Java Drive
- Sunnyvale CA 94089
+00-24-93 (hex) ARRIS Group, Inc.
+002493 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-3C-E8-24 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-3CE824 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+E4-64-49 (hex) ARRIS Group, Inc.
+E46449 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-E8-AB-F3 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-E8ABF3 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+74-56-12 (hex) ARRIS Group, Inc.
+745612 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-70-06-AC (hex) Eastcompeace Technology Co., Ltd
-7006AC (base 16) Eastcompeace Technology Co., Ltd
- Number 8 Pinggong Zhong Road,Nanping S&T Industry Community,Zhuhai,Guangdong,519060 China
- Zhuhai Guangdong 519060
- CN
+74-EA-E8 (hex) ARRIS Group, Inc.
+74EAE8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-50-6F-77 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-506F77 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
+A8-11-FC (hex) ARRIS Group, Inc.
+A811FC (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-2C-95-69 (hex) ARRIS Group, Inc.
-2C9569 (base 16) ARRIS Group, Inc.
+04-4E-5A (hex) ARRIS Group, Inc.
+044E5A (base 16) ARRIS Group, Inc.
6450 Sequence Drive
San Diego CA 92121
US
-50-95-51 (hex) ARRIS Group, Inc.
-509551 (base 16) ARRIS Group, Inc.
+94-E8-C5 (hex) ARRIS Group, Inc.
+94E8C5 (base 16) ARRIS Group, Inc.
6450 Sequence Drive
San Diego CA 92121
US
-60-98-13 (hex) Shanghai Visking Digital Technology Co. LTD
-609813 (base 16) Shanghai Visking Digital Technology Co. LTD
- Room 1301, Building A8, No.1688 Guoquan North Road, Yangpu District
- Shanghai 200082
- CN
+F8-A0-97 (hex) ARRIS Group, Inc.
+F8A097 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-8C-4C-AD (hex) Evoluzn Inc.
-8C4CAD (base 16) Evoluzn Inc.
- 34 Samoset Lane
- Schaumburg IL 60193
+B0-DA-F9 (hex) ARRIS Group, Inc.
+B0DAF9 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-A4-D4-B2 (hex) Shenzhen MeiG Smart Technology Co.,Ltd
-A4D4B2 (base 16) Shenzhen MeiG Smart Technology Co.,Ltd
- #88 Qinjiang Road, Xuhui District
- Shanghai 200233
- CN
+18-B8-1F (hex) ARRIS Group, Inc.
+18B81F (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-DC-E5-33 (hex) IEEE Registration Authority
-DCE533 (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
+BC-2E-48 (hex) ARRIS Group, Inc.
+BC2E48 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-8C-F7-10 (hex) AMPAK Technology, Inc.
-8CF710 (base 16) AMPAK Technology, Inc.
- No.1,Jen Ai Road Hsinchu Industrial Park, Hukou
- Hsinchu Taiwan ROC. 30352
- TW
+58-19-F8 (hex) ARRIS Group, Inc.
+5819F8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-38-E1-AA (hex) zte corporation
-38E1AA (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
- CN
+2C-95-69 (hex) ARRIS Group, Inc.
+2C9569 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-18-A2-8A (hex) Essel-T Co., Ltd
-18A28A (base 16) Essel-T Co., Ltd
- 1211 kranztechno, 388 Dunchon-daero
- Seongnam-si Jungwon-gu, Gyeonggi-do 13403
- KR
+50-95-51 (hex) ARRIS Group, Inc.
+509551 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-38-DE-AD (hex) Intel Corporate
-38DEAD (base 16) Intel Corporate
- Lot 8, Jalan Hi-Tech 2/3
- Kulim Kedah 09000
- MY
+24-0A-63 (hex) ARRIS Group, Inc.
+240A63 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-74-E1-82 (hex) Texas Instruments
-74E182 (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
+00-1E-8D (hex) ARRIS Group, Inc.
+001E8D (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-40-BD-32 (hex) Texas Instruments
-40BD32 (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
+00-23-0B (hex) ARRIS Group, Inc.
+00230B (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-3C-17-10 (hex) Sagemcom Broadband SAS
-3C1710 (base 16) Sagemcom Broadband SAS
- 250, route de l'Empereur
- Rueil Malmaison Cedex hauts de seine 92848
- FR
+00-1B-52 (hex) ARRIS Group, Inc.
+001B52 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-C8-FA-E1 (hex) ARQ Digital LLC
-C8FAE1 (base 16) ARQ Digital LLC
- 2430 Auto Park Way
- Escondido CA 92029
+00-23-ED (hex) ARRIS Group, Inc.
+0023ED (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-80-AD-16 (hex) Xiaomi Communications Co Ltd
-80AD16 (base 16) Xiaomi Communications Co Ltd
- The Rainbow City of China Resources
- NO.68, Qinghe Middle Street Haidian District, Beijing 100085
- CN
+00-23-95 (hex) ARRIS Group, Inc.
+002395 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-04-4E-AF (hex) LG Innotek
-044EAF (base 16) LG Innotek
- 26, Hanamsandan 5beon-ro
- Gwangju Gwangsan-gu 506-731
- KR
+00-22-B4 (hex) ARRIS Group, Inc.
+0022B4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-DC-A3-33 (hex) Shenzhen YOUHUA Technology Co., Ltd
-DCA333 (base 16) Shenzhen YOUHUA Technology Co., Ltd
- Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
- Shenzhen Guangdong 518055
- CN
+00-21-36 (hex) ARRIS Group, Inc.
+002136 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-BC-DD-C2 (hex) Espressif Inc.
-BCDDC2 (base 16) Espressif Inc.
- Room 204, Building 2, 690 Bibo Road, Pudong New Area
- Shanghai Shanghai 201203
- CN
+00-24-C1 (hex) ARRIS Group, Inc.
+0024C1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-FC-7C-02 (hex) Phicomm (Shanghai) Co., Ltd.
-FC7C02 (base 16) Phicomm (Shanghai) Co., Ltd.
- 3666 SiXian Rd.,Songjiang District
- Shanghai Shanghai 201616
- CN
+3C-75-4A (hex) ARRIS Group, Inc.
+3C754A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-88-A9-A7 (hex) IEEE Registration Authority
-88A9A7 (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
+A4-7A-A4 (hex) ARRIS Group, Inc.
+A47AA4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-F0-E3-DC (hex) Tecon MT, LLC
-F0E3DC (base 16) Tecon MT, LLC
- 3rd Khoroshevskaya st - 20
- Moscow 123298
- RU
+00-1A-AD (hex) ARRIS Group, Inc.
+001AAD (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-30-B2-16 (hex) ABB AG - Power Grids - Grid Automation
-30B216 (base 16) ABB AG - Power Grids - Grid Automation
- Kallstadter Strasse 1
- Mannheim 68309
- DE
+00-19-5E (hex) ARRIS Group, Inc.
+00195E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-00-D0-CE (hex) iSystem Labs
-00D0CE (base 16) iSystem Labs
- BRODISCE 7, 10C
- Trzin 1236
- SI
+00-14-04 (hex) ARRIS Group, Inc.
+001404 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-00-BE-75 (hex) Cisco Systems, Inc
-00BE75 (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
+00-1B-DD (hex) ARRIS Group, Inc.
+001BDD (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-50-4E-DC (hex) Ping Communication
-504EDC (base 16) Ping Communication
- Brenden 18
- Appenzell Meistersrüte AI 9050
- CH
+00-23-A2 (hex) ARRIS Group, Inc.
+0023A2 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-20-67-7C (hex) Hewlett Packard Enterprise
-20677C (base 16) Hewlett Packard Enterprise
- 8000 Foothills Blvd.
- Roseville CA 95747
+BC-64-4B (hex) ARRIS Group, Inc.
+BC644B (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-C4-2C-4F (hex) Qingdao Hisense Mobile Communication Technology Co,Ltd
-C42C4F (base 16) Qingdao Hisense Mobile Communication Technology Co,Ltd
- No.399, Song Ling Road
- Qingdao Shandong 266100
- CN
+34-7A-60 (hex) ARRIS Group, Inc.
+347A60 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-24-CA-CB (hex) Fiberhome Telecommunication Technologies Co.,LTD
-24CACB (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
+84-E0-58 (hex) ARRIS Group, Inc.
+84E058 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-24-0A-63 (hex) ARRIS Group, Inc.
-240A63 (base 16) ARRIS Group, Inc.
+00-36-76 (hex) ARRIS Group, Inc.
+003676 (base 16) ARRIS Group, Inc.
6450 Sequence Drive
San Diego CA 92121
US
-44-FF-BA (hex) zte corporation
-44FFBA (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
- CN
+70-7E-43 (hex) ARRIS Group, Inc.
+707E43 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-00-23-A8 (hex) Marshall Electronics
-0023A8 (base 16) Marshall Electronics
- 20608 Madrona Ave
- Torrance CA 90503
+1C-14-48 (hex) ARRIS Group, Inc.
+1C1448 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-B4-81-BF (hex) Meta-Networks, LLC
-B481BF (base 16) Meta-Networks, LLC
- Office 106C, 5/2, Varshavskaya street
- Saint-Petersburg Saint-Petersburg 196128
- RU
+00-12-25 (hex) ARRIS Group, Inc.
+001225 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-10-1D-51 (hex) 8Mesh Networks
-101D51 (base 16) 8Mesh Networks
- Unit 607, 6/F, Yen Sheng Centre,
- 64 Hoi Yuen Road Kwun Tong 000
- HK
+00-12-8A (hex) ARRIS Group, Inc.
+00128A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-0C-AE-7D (hex) Texas Instruments
-0CAE7D (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
+00-03-E0 (hex) ARRIS Group, Inc.
+0003E0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
+70-C8-33 (hex) Wirepas Oy
+70C833 (base 16) Wirepas Oy
+ Visiokatu 4
+ Tampere 33720
+ FI
+
+E8-FA-F7 (hex) Guangdong Uniteddata Holding Group Co., Ltd.
+E8FAF7 (base 16) Guangdong Uniteddata Holding Group Co., Ltd.
+ 39L, Pearl River Tower, No.15 Zhujiang West Road,Tianhe District
+ GUANGZHOU GUANGDONG 510623
+ CN
+
+94-87-E0 (hex) Xiaomi Communications Co Ltd
+9487E0 (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
D8-6C-E9 (hex) Sagemcom Broadband SAS
D86CE9 (base 16) Sagemcom Broadband SAS
250 route de l'Empereur
@@ -91016,12 +91760,6 @@ DCC0DB (base 16) Shenzhen Kaiboer Technology Co., Ltd. Birkeroed DK-3460
DK
-E8-9A-FF (hex) Fujian Landi Commercial Equipment Co.,Ltd
-E89AFF (base 16) Fujian Landi Commercial Equipment Co.,Ltd
- No.68, Hong Shan Yuan Road, Gulou District
- Fuzhou Municipality Fujian Province 350001
- CN
-
68-3B-1E (hex) Countwise LTD
683B1E (base 16) Countwise LTD
1149 Sawgrass Corporate Parkway
@@ -91322,12 +92060,6 @@ C8C791 (base 16) Zero1.tv GmbH Oulu 90570
FI
-30-78-C2 (hex) Innowireless, Co. Ltd.
-3078C2 (base 16) Innowireless, Co. Ltd.
- 1-301, Pangyo Seven Venture Valley 2-danji
- Seongnam-Si Gyeonggi-do 463-400
- KR
-
7C-FE-28 (hex) Salutron Inc.
7CFE28 (base 16) Salutron Inc.
40979 Encyclopedia Circle
@@ -95798,12 +96530,6 @@ EC3091 (base 16) Cisco Systems, Inc Ceska Skalice Nachod 55203
CZ
-00-23-3D (hex) Novero holding B.V.
-00233D (base 16) Novero holding B.V.
- Parsevalstrasse 7A
- Düsseldorf 40468
- DE
-
00-23-30 (hex) DIZIPIA, INC.
002330 (base 16) DIZIPIA, INC.
15th Floor, East Wing, IT Venture Tower
@@ -102449,12 +103175,6 @@ EC3091 (base 16) Cisco Systems, Inc Hoechberg Bavaria 97204
DE
-00-07-A8 (hex) Haier Group Technologies Ltd.
-0007A8 (base 16) Haier Group Technologies Ltd.
- No. 1 Haier Road, Hi-tech Zone
-
- CN
-
00-09-4A (hex) Homenet Communications
00094A (base 16) Homenet Communications
Innovation Centre
@@ -106736,12 +107456,6 @@ EC3091 (base 16) Cisco Systems, Inc Sunnyvale, CA 94089
US
-00-A0-21 (hex) General Dynamics
-00A021 (base 16) General Dynamics
- C4 Systems
- Needham Heights MA 02494-2892
- US
-
00-A0-A8 (hex) RENEX CORPORATION
00A0A8 (base 16) RENEX CORPORATION
2750 KILLARNEY DRIVE
@@ -112970,294 +113684,12 @@ A0C9A0 (base 16) Murata Manufacturing Co., Ltd. Nagaokakyo-shi Kyoto 617-8555
JP
-00-1C-C3 (hex) ARRIS Group, Inc.
-001CC3 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-64-12-69 (hex) ARRIS Group, Inc.
-641269 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-28-7A-EE (hex) ARRIS Group, Inc.
-287AEE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-FC-51-A4 (hex) ARRIS Group, Inc.
-FC51A4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-38-70-0C (hex) ARRIS Group, Inc.
-38700C (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-A4-15-88 (hex) ARRIS Group, Inc.
-A41588 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-B8-16-19 (hex) ARRIS Group, Inc.
-B81619 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-B0-77-AC (hex) ARRIS Group, Inc.
-B077AC (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-14-5B-D1 (hex) ARRIS Group, Inc.
-145BD1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-6C-C1-D2 (hex) ARRIS Group, Inc.
-6CC1D2 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-F8-0B-BE (hex) ARRIS Group, Inc.
-F80BBE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-DC-45-17 (hex) ARRIS Group, Inc.
-DC4517 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-74-F6-12 (hex) ARRIS Group, Inc.
-74F612 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-74-E7-C6 (hex) ARRIS Group, Inc.
-74E7C6 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-25-F2 (hex) ARRIS Group, Inc.
-0025F2 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-A8 (hex) ARRIS Group, Inc.
-0015A8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-0E-5C (hex) ARRIS Group, Inc.
-000E5C (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-0C-E5 (hex) ARRIS Group, Inc.
-000CE5 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-04-BD (hex) ARRIS Group, Inc.
-0004BD (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-E0-6F (hex) ARRIS Group, Inc.
-00E06F (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-38-6B-BB (hex) ARRIS Group, Inc.
-386BBB (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-CF (hex) ARRIS Group, Inc.
-0015CF (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-CF (hex) ARRIS Group, Inc.
-001DCF (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-D5 (hex) ARRIS Group, Inc.
-001DD5 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-D0 (hex) ARRIS Group, Inc.
-001DD0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-5C-57-1A (hex) ARRIS Group, Inc.
-5C571A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-D8-25-22 (hex) ARRIS Group, Inc.
-D82522 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-70-B1-4E (hex) ARRIS Group, Inc.
-70B14E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-14-D4-FE (hex) ARRIS Group, Inc.
-14D4FE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-23-74 (hex) ARRIS Group, Inc.
-002374 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-26-41 (hex) ARRIS Group, Inc.
-002641 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-26-BA (hex) ARRIS Group, Inc.
-0026BA (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-21-80 (hex) ARRIS Group, Inc.
-002180 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-19-C0 (hex) ARRIS Group, Inc.
-0019C0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-14-E8 (hex) ARRIS Group, Inc.
-0014E8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-19-A6 (hex) ARRIS Group, Inc.
-0019A6 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-17-00 (hex) ARRIS Group, Inc.
-001700 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-90-1A-CA (hex) ARRIS Group, Inc.
-901ACA (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E8-ED-05 (hex) ARRIS Group, Inc.
-E8ED05 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-70-76-30 (hex) ARRIS Group, Inc.
-707630 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-90-C7-92 (hex) ARRIS Group, Inc.
-90C792 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-78-96-84 (hex) ARRIS Group, Inc.
-789684 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-CC-65-AD (hex) ARRIS Group, Inc.
-CC65AD (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-98-6B-3D (hex) ARRIS Group, Inc.
-986B3D (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-5C-E3-0E (hex) ARRIS Group, Inc.
-5CE30E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-78-23-AE (hex) ARRIS Group, Inc.
-7823AE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
44-7F-77 (hex) Connected Home
447F77 (base 16) Connected Home
19-22, Rathbone Place
London W1T 1HY
GB
-2C-7E-81 (hex) ARRIS Group, Inc.
-2C7E81 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
00-9A-D2 (hex) Cisco Systems, Inc
009AD2 (base 16) Cisco Systems, Inc
80 West Tasman Drive
@@ -113282,12 +113714,6 @@ CC65AD (base 16) ARRIS Group, Inc. Shenzhen Guangdong 518057
CN
-F4-0E-83 (hex) ARRIS Group, Inc.
-F40E83 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
7C-8B-CA (hex) TP-LINK TECHNOLOGIES CO.,LTD.
7C8BCA (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
@@ -114110,12 +114536,6 @@ D86162 (base 16) Wistron Neweb Corporation Yokohama-shi Kanagawa 224-8502
JP
-60-8C-E6 (hex) ARRIS Group, Inc.
-608CE6 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
8C-D2-E9 (hex) YOKOTE SEIKO CO., LTD.
8CD2E9 (base 16) YOKOTE SEIKO CO., LTD.
10-18 Minami-Gosyono Yasumoto
@@ -114410,12 +114830,6 @@ F04F7C (base 16) Private shenzhen guangdong 518000
CN
-E8-82-5B (hex) ARRIS Group, Inc.
-E8825B (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
5C-86-5C (hex) Samsung Electronics Co.,Ltd
5C865C (base 16) Samsung Electronics Co.,Ltd
129, Samsung-ro, Youngtongl-Gu
@@ -114530,24 +114944,6 @@ D4AD2D (base 16) Fiberhome Telecommunication Technologies Co.,LTD Hangzhou Zhejiang 310012
CN
-F0-B0-E7 (hex) Apple, Inc.
-F0B0E7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-20-9B-CD (hex) Apple, Inc.
-209BCD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-CC-20-E8 (hex) Apple, Inc.
-CC20E8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
10-C2-5A (hex) Technicolor CH USA Inc.
10C25A (base 16) Technicolor CH USA Inc.
101 West 103rd St.
@@ -114644,18 +115040,6 @@ D4F786 (base 16) Fiberhome Telecommunication Technologies Co.,LTD Wuhan Hubei 430074
CN
-64-02-CB (hex) ARRIS Group, Inc.
-6402CB (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-F0-FC-C8 (hex) ARRIS Group, Inc.
-F0FCC8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
EC-7F-C6 (hex) ECCEL CORPORATION SAS
EC7FC6 (base 16) ECCEL CORPORATION SAS
CRA 106 15A 25 LT 88 MZ 17 BG 1, ZONA FRANCA BOGOTA
@@ -114740,6 +115124,426 @@ A067BE (base 16) Sicon srl Isola Vicentina Vicenza 36033
IT
+08-97-34 (hex) Hewlett Packard Enterprise
+089734 (base 16) Hewlett Packard Enterprise
+ 8000 Foothills Blvd.
+ Roseville CA 95747
+ US
+
+F8-E4-4E (hex) MCOT INC.
+F8E44E (base 16) MCOT INC.
+ Yogohigashi 1-5-12
+ Matsuyama Ehime 790-0044
+ JP
+
+90-3D-68 (hex) G-Printec, Inc.
+903D68 (base 16) G-Printec, Inc.
+ Kawasaki Tech Center 5F, 580-16, Horikawacho
+ Saiwai-ku, Kawasaki-shi Kanagawa 212-0013
+ JP
+
+F0-0E-1D (hex) Megafone Limited
+F00E1D (base 16) Megafone Limited
+ Unit 702,7/F,Bankok Bank Building,NO.18 Bonham Strand West
+ Hong Kong 999077
+ HK
+
+CC-C0-79 (hex) Murata Manufacturing Co., Ltd.
+CCC079 (base 16) Murata Manufacturing Co., Ltd.
+ 1-10-1, Higashikotari
+ Nagaokakyo-shi Kyoto 617-8555
+ JP
+
+34-8B-75 (hex) LAVA INTERNATIONAL(H.K) LIMITED
+348B75 (base 16) LAVA INTERNATIONAL(H.K) LIMITED
+ UNIT L 1/F MAU LAM COMM BLDG 16-18 MAU LAM ST, JORDAN KL, HK
+ Hong kong 999077
+ CN
+
+E8-9A-FF (hex) Fujian LANDI Commercial Equipment Co.,Ltd
+E89AFF (base 16) Fujian LANDI Commercial Equipment Co.,Ltd
+ Building 17,the 1st Section ,Fuzhou Software Park
+ No.89 Software Road Fuzhou ,Fujian 350003
+ CN
+
+00-07-A8 (hex) Haier Group Technologies Ltd
+0007A8 (base 16) Haier Group Technologies Ltd
+ No. 1 Haier Road, Hi-tech Zone
+
+ CN
+
+E4-43-4B (hex) Dell Inc.
+E4434B (base 16) Dell Inc.
+ One Dell Way
+ Round Rock TX 78682
+ US
+
+68-89-75 (hex) nuoxc
+688975 (base 16) nuoxc
+ 龙岗区横岗街道西坑社区西坑梧岗路9号2栋
+ 深圳市 广东省 518173
+ CN
+
+44-1E-98 (hex) Ruckus Wireless
+441E98 (base 16) Ruckus Wireless
+ 350 West Java Drive
+ Sunnyvale CA 94089
+ US
+
+08-E6-89 (hex) Apple, Inc.
+08E689 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-E7-C6 (hex) ARRIS Group, Inc.
+74E7C6 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+74-F6-12 (hex) ARRIS Group, Inc.
+74F612 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+DC-45-17 (hex) ARRIS Group, Inc.
+DC4517 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+F8-0B-BE (hex) ARRIS Group, Inc.
+F80BBE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+6C-C1-D2 (hex) ARRIS Group, Inc.
+6CC1D2 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+14-5B-D1 (hex) ARRIS Group, Inc.
+145BD1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+B0-77-AC (hex) ARRIS Group, Inc.
+B077AC (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+B8-16-19 (hex) ARRIS Group, Inc.
+B81619 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+A4-15-88 (hex) ARRIS Group, Inc.
+A41588 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+38-70-0C (hex) ARRIS Group, Inc.
+38700C (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+FC-51-A4 (hex) ARRIS Group, Inc.
+FC51A4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+28-7A-EE (hex) ARRIS Group, Inc.
+287AEE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+CC-65-AD (hex) ARRIS Group, Inc.
+CC65AD (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+78-96-84 (hex) ARRIS Group, Inc.
+789684 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+90-C7-92 (hex) ARRIS Group, Inc.
+90C792 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+E8-ED-05 (hex) ARRIS Group, Inc.
+E8ED05 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-0C-E5 (hex) ARRIS Group, Inc.
+000CE5 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-0E-5C (hex) ARRIS Group, Inc.
+000E5C (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-15-A8 (hex) ARRIS Group, Inc.
+0015A8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-17-00 (hex) ARRIS Group, Inc.
+001700 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-19-A6 (hex) ARRIS Group, Inc.
+0019A6 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-21-80 (hex) ARRIS Group, Inc.
+002180 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-26-BA (hex) ARRIS Group, Inc.
+0026BA (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-26-41 (hex) ARRIS Group, Inc.
+002641 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-23-74 (hex) ARRIS Group, Inc.
+002374 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-25-F2 (hex) ARRIS Group, Inc.
+0025F2 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-15-CF (hex) ARRIS Group, Inc.
+0015CF (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+38-6B-BB (hex) ARRIS Group, Inc.
+386BBB (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-E0-6F (hex) ARRIS Group, Inc.
+00E06F (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-04-BD (hex) ARRIS Group, Inc.
+0004BD (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+5C-57-1A (hex) ARRIS Group, Inc.
+5C571A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1D-D0 (hex) ARRIS Group, Inc.
+001DD0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1D-D5 (hex) ARRIS Group, Inc.
+001DD5 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1D-CF (hex) ARRIS Group, Inc.
+001DCF (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-14-E8 (hex) ARRIS Group, Inc.
+0014E8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-19-C0 (hex) ARRIS Group, Inc.
+0019C0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+98-6B-3D (hex) ARRIS Group, Inc.
+986B3D (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+90-1A-CA (hex) ARRIS Group, Inc.
+901ACA (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+64-12-69 (hex) ARRIS Group, Inc.
+641269 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1C-C3 (hex) ARRIS Group, Inc.
+001CC3 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+14-D4-FE (hex) ARRIS Group, Inc.
+14D4FE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+70-B1-4E (hex) ARRIS Group, Inc.
+70B14E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+D8-25-22 (hex) ARRIS Group, Inc.
+D82522 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+70-76-30 (hex) ARRIS Group, Inc.
+707630 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+F4-0E-83 (hex) ARRIS Group, Inc.
+F40E83 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+60-8C-E6 (hex) ARRIS Group, Inc.
+608CE6 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+E8-82-5B (hex) ARRIS Group, Inc.
+E8825B (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+64-02-CB (hex) ARRIS Group, Inc.
+6402CB (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+F0-FC-C8 (hex) ARRIS Group, Inc.
+F0FCC8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+FC-69-47 (hex) Texas Instruments
+FC6947 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+E0-7D-EA (hex) Texas Instruments
+E07DEA (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+F0-B5-D1 (hex) Texas Instruments
+F0B5D1 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+FC-E6-6A (hex) Industrial Software Co
+FCE66A (base 16) Industrial Software Co
+ 85, Aleksandyr Malinov Blvd. Office 6
+ Sofia 1715
+ BG
+
+78-36-CC (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+7836CC (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+30-78-C2 (hex) Innowireless / QUCELL Networks
+3078C2 (base 16) Innowireless / QUCELL Networks
+ Innowireless Bldg. 190 Seohyeon-ro
+ Bundang-gu, Seongnam-si Gyeonggi-do 13590
+ KR
+
+00-23-3D (hex) Laird Technologies
+00233D (base 16) Laird Technologies
+ Meesmannstrasse 103
+ Bochum 44807
+ DE
+
+D8-18-D3 (hex) Juniper Networks
+D818D3 (base 16) Juniper Networks
+ 1133 Innovation Way
+ Sunnyvale CA 94089
+ US
+
+6C-AF-15 (hex) Webasto SE
+6CAF15 (base 16) Webasto SE
+ Kraillinger Straße 5
+ Stockdorf Bayern 82131
+ DE
+
54-C5-7A (hex) Sunnovo International Limited
54C57A (base 16) Sunnovo International Limited
1717 Haitai Building
@@ -115079,644 +115883,914 @@ B42D56 (base 16) Extreme Networks, Inc. Seongnam-si Gyeonggi-do 463-875
KR
-48-74-6E (hex) Apple, Inc.
-48746E (base 16) Apple, Inc.
+B4-F7-A1 (hex) LG Electronics (Mobile Communications)
+B4F7A1 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+C0-A8-F0 (hex) Adamson Systems Engineering
+C0A8F0 (base 16) Adamson Systems Engineering
+ 1401 Scugog Line 6
+ Port Perry Ontario L9L 1B2
+ CA
+
+38-C9-A9 (hex) SMART High Reliability Solutions, Inc.
+38C9A9 (base 16) SMART High Reliability Solutions, Inc.
+ 1325 N Fiesta Blvd., #101
+ Gilbert AZ 85233
+ US
+
+28-3B-82 (hex) D-Link International
+283B82 (base 16) D-Link International
+ 1 Internal Business Park, #03-12,The Synergy, Singapore
+ Singapore Singapore 609917
+ SG
+
+C4-00-AD (hex) Advantech Technology (CHINA) Co., Ltd.
+C400AD (base 16) Advantech Technology (CHINA) Co., Ltd.
+ No.666, Han-Pu Rd. Yu-Shan
+ Kun-Shan Jiang Su 215316
+ CN
+
+34-5A-06 (hex) SHARP Corporation
+345A06 (base 16) SHARP Corporation
+ 1 Takumi-cho, Sakai-ku
+ Sakai City Osaka 590-8522
+ JP
+
+0C-8B-D3 (hex) ITEL MOBILE LIMITED
+0C8BD3 (base 16) ITEL MOBILE LIMITED
+ RM B3 & B4 BLOCK B, KO FAI INDUSTRIAL BUILDING NO.7 KO FAI ROAD, YAU TONG, KLN, H.K
+ Hong Kong KOWLOON 999077
+ HK
+
+04-AC-44 (hex) Holtek Semiconductor Inc.
+04AC44 (base 16) Holtek Semiconductor Inc.
+ No.3, Creation Rd. II, Science Park
+ Hsinchu 300
+ TW
+
+F4-DC-A5 (hex) DAWON DNS
+F4DCA5 (base 16) DAWON DNS
+ 217ho, Sauphwajiwon-dong, KETI, 226, Cheomdangwagi-ro, Buk-gu
+ Gwangju 61011
+ KR
+
+50-1C-B0 (hex) Cisco Systems, Inc
+501CB0 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+C4-FF-BC (hex) IEEE Registration Authority
+C4FFBC (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+78-58-60 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+785860 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+F8-90-66 (hex) Nain Inc.
+F89066 (base 16) Nain Inc.
+ Aoyamadai building 902, Shibuya 2-9-10, Shibuya-ku
+ Tokyo 150-0002
+ JP
+
+B4-FB-F9 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+B4FBF9 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+B4-2E-F8 (hex) Eline Technology co.Ltd
+B42EF8 (base 16) Eline Technology co.Ltd
+ kangcheng Road, Pharmaceutical Industrical Park, Yuanzhou District
+ Yichun Jiangxi 336000
+ CN
+
+D8-44-5C (hex) DEV Tecnologia Ind Com Man Eq LTDA
+D8445C (base 16) DEV Tecnologia Ind Com Man Eq LTDA
+ Av Prof Lineu Prestes 2242 SL 23
+ Sao Paulo SP 05508000
+ BR
+
+78-5D-C8 (hex) LG Electronics
+785DC8 (base 16) LG Electronics
+ 222 LG-ro, JINWI-MYEON
+ Pyeongtaek-si Gyeonggi-do 451-713
+ KR
+
+7C-39-53 (hex) zte corporation
+7C3953 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+48-C7-96 (hex) Samsung Electronics Co.,Ltd
+48C796 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+80-4E-70 (hex) Samsung Electronics Co.,Ltd
+804E70 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+4C-EF-C0 (hex) Amazon Technologies Inc.
+4CEFC0 (base 16) Amazon Technologies Inc.
+ P.O Box 8102
+ Reno NV 89507
+ US
+
+D4-6D-6D (hex) Intel Corporate
+D46D6D (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+CC-8E-71 (hex) Cisco Systems, Inc
+CC8E71 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+CC-3B-58 (hex) Curiouser Products Inc
+CC3B58 (base 16) Curiouser Products Inc
+ 712 Broadway #4
+ New York NY 10003
+ US
+
+38-F5-54 (hex) HISENSE ELECTRIC CO.,LTD
+38F554 (base 16) HISENSE ELECTRIC CO.,LTD
+ No. 218, Qianwangang Rd
+ Qingdao Shandong 266555
+ CN
+
+18-94-C6 (hex) ShenZhen Chenyee Technology Co., Ltd.
+1894C6 (base 16) ShenZhen Chenyee Technology Co., Ltd.
+ 32F, Tower A, East Pacific International Center, No.7888, Shennan Avenue, Futian District
+ Shenzhen 518040
+ CN
+
+14-A7-2B (hex) currentoptronics Pvt.Ltd
+14A72B (base 16) currentoptronics Pvt.Ltd
+ CRT Building, Jupitor Jn , Near Time kids Koothattukulam - Piravom Rd
+ ERNAKULAM Time Kids day care 686662
+ IN
+
+AC-07-5F (hex) HUAWEI TECHNOLOGIES CO.,LTD
+AC075F (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+88-17-A3 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
+8817A3 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
+ Phase 3, Bayan Lepas FIZ
+ Bayan Lepas Penang 11900
+ MY
+
+00-71-47 (hex) Amazon Technologies Inc.
+007147 (base 16) Amazon Technologies Inc.
+ P.O Box 8102
+ Reno NV 89507
+ US
+
+78-8C-54 (hex) Ping Communication
+788C54 (base 16) Ping Communication
+ Brenden 18
+ Appenzell Meistersrüte AI 9050
+ CH
+
+D4-66-A8 (hex) Riedo Networks Ltd
+D466A8 (base 16) Riedo Networks Ltd
+ Route de la Fonderie 6
+ Fribourg 1700
+ CH
+
+30-B7-D4 (hex) Hitron Technologies. Inc
+30B7D4 (base 16) Hitron Technologies. Inc
+ No. 1-8, Lising 1st Rd. Hsinchu Science Park, Hsinchu, 300, Taiwan, R.O.C
+ Hsin-chu Taiwan 300
+ TW
+
+38-80-DF (hex) Motorola Mobility LLC, a Lenovo Company
+3880DF (base 16) Motorola Mobility LLC, a Lenovo Company
+ 222 West Merchandise Mart Plaza
+ Chicago IL 60654
+ US
+
+7C-B2-32 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+7CB232 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+2C-D9-74 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
+2CD974 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
+ No.75,Zhongkai High-Tech Development District,Huizhou
+ Hui Zhou Guangdong 516006
+ CN
+
+58-B3-FC (hex) SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
+58B3FC (base 16) SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
+ Bldg56A,6/F,Baotian Rd3,Xixiang Town,Baoan District,
+ Shenzhen Guangdong 518000
+ CN
+
+BC-AB-7C (hex) TRnP KOREA Co Ltd
+BCAB7C (base 16) TRnP KOREA Co Ltd
+ room1308,239 SoHyungRo,WonMiGu,
+ BuChunCity KyungKiDo 1135
+ KR
+
+00-A0-21 (hex) General Dynamics Mission Systems
+00A021 (base 16) General Dynamics Mission Systems
+ 150 Rustcraft Road
+ Dedham MA 02026
+ US
+
+94-99-90 (hex) VTC Telecommunications
+949990 (base 16) VTC Telecommunications
+ 750 (3rd Floor) Dien Bien Phu, District 10
+ Ho Chi Minh Ho Chi Minh 70000
+ VN
+
+0C-80-63 (hex) TP-LINK TECHNOLOGIES CO.,LTD.
+0C8063 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
+ Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
+ Shenzhen Guangdong 518057
+ CN
+
+3C-15-FB (hex) HUAWEI TECHNOLOGIES CO.,LTD
+3C15FB (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+B0-41-6F (hex) Shenzhen Maxtang Computer Co.,Ltd
+B0416F (base 16) Shenzhen Maxtang Computer Co.,Ltd
+ 6/F, Bldg.3, Honghui Industrial Park, Liuxian 2nd Rd., Bao'an Dist.
+ Shenzhen Guangdong 518101
+ CN
+
+F8-98-EF (hex) HUAWEI TECHNOLOGIES CO.,LTD
+F898EF (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+14-09-DC (hex) HUAWEI TECHNOLOGIES CO.,LTD
+1409DC (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+DC-41-5F (hex) Apple, Inc.
+DC415F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-54-72-4F (hex) Apple, Inc.
-54724F (base 16) Apple, Inc.
+30-63-6B (hex) Apple, Inc.
+30636B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-F1-3E (hex) Apple, Inc.
-04F13E (base 16) Apple, Inc.
+F4-5C-89 (hex) Apple, Inc.
+F45C89 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-60-03-08 (hex) Apple, Inc.
-600308 (base 16) Apple, Inc.
+68-DB-CA (hex) Apple, Inc.
+68DBCA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-80-EA-96 (hex) Apple, Inc.
-80EA96 (base 16) Apple, Inc.
+04-4B-ED (hex) Apple, Inc.
+044BED (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-24-A2-E1 (hex) Apple, Inc.
-24A2E1 (base 16) Apple, Inc.
+6C-8D-C1 (hex) Apple, Inc.
+6C8DC1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-90-B9-31 (hex) Apple, Inc.
-90B931 (base 16) Apple, Inc.
+38-CA-DA (hex) Apple, Inc.
+38CADA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-28-0B-5C (hex) Apple, Inc.
-280B5C (base 16) Apple, Inc.
+A4-D1-8C (hex) Apple, Inc.
+A4D18C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A8-96-8A (hex) Apple, Inc.
-A8968A (base 16) Apple, Inc.
+18-65-90 (hex) Apple, Inc.
+186590 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-9C-04-EB (hex) Apple, Inc.
-9C04EB (base 16) Apple, Inc.
+64-B0-A6 (hex) Apple, Inc.
+64B0A6 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-88-53-95 (hex) Apple, Inc.
-885395 (base 16) Apple, Inc.
+84-FC-AC (hex) Apple, Inc.
+84FCAC (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-80-92-9F (hex) Apple, Inc.
-80929F (base 16) Apple, Inc.
+6C-19-C0 (hex) Apple, Inc.
+6C19C0 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-B8-E3 (hex) Apple, Inc.
-98B8E3 (base 16) Apple, Inc.
+20-AB-37 (hex) Apple, Inc.
+20AB37 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D8-00-4D (hex) Apple, Inc.
-D8004D (base 16) Apple, Inc.
+20-3C-AE (hex) Apple, Inc.
+203CAE (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-FE-94 (hex) Apple, Inc.
-98FE94 (base 16) Apple, Inc.
+74-8D-08 (hex) Apple, Inc.
+748D08 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-64-4B (hex) Apple, Inc.
-68644B (base 16) Apple, Inc.
+A0-3B-E3 (hex) Apple, Inc.
+A03BE3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F0-99-BF (hex) Apple, Inc.
-F099BF (base 16) Apple, Inc.
+7C-6D-62 (hex) Apple, Inc.
+7C6D62 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-FC-E9-98 (hex) Apple, Inc.
-FCE998 (base 16) Apple, Inc.
+40-D3-2D (hex) Apple, Inc.
+40D32D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-48-E9-F1 (hex) Apple, Inc.
-48E9F1 (base 16) Apple, Inc.
+D8-30-62 (hex) Apple, Inc.
+D83062 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-4C-7C-5F (hex) Apple, Inc.
-4C7C5F (base 16) Apple, Inc.
+C4-2C-03 (hex) Apple, Inc.
+C42C03 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-60-F8-1D (hex) Apple, Inc.
-60F81D (base 16) Apple, Inc.
+7C-C5-37 (hex) Apple, Inc.
+7CC537 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-9C-70 (hex) Apple, Inc.
-689C70 (base 16) Apple, Inc.
+70-CD-60 (hex) Apple, Inc.
+70CD60 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-2C-B4-3A (hex) Apple, Inc.
-2CB43A (base 16) Apple, Inc.
+C0-D0-12 (hex) Apple, Inc.
+C0D012 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-26-65 (hex) Apple, Inc.
-042665 (base 16) Apple, Inc.
+D4-DC-CD (hex) Apple, Inc.
+D4DCCD (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F4-F1-5A (hex) Apple, Inc.
-F4F15A (base 16) Apple, Inc.
+48-4B-AA (hex) Apple, Inc.
+484BAA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-20-7D-74 (hex) Apple, Inc.
-207D74 (base 16) Apple, Inc.
+F8-03-77 (hex) Apple, Inc.
+F80377 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-4C-8D-79 (hex) Apple, Inc.
-4C8D79 (base 16) Apple, Inc.
+14-BD-61 (hex) Apple, Inc.
+14BD61 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-FC-FC-48 (hex) Apple, Inc.
-FCFC48 (base 16) Apple, Inc.
+CC-25-EF (hex) Apple, Inc.
+CC25EF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-38-C9-86 (hex) Apple, Inc.
-38C986 (base 16) Apple, Inc.
+B8-78-2E (hex) Apple, Inc.
+B8782E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-EC-E4 (hex) Apple, Inc.
-70ECE4 (base 16) Apple, Inc.
+00-05-02 (hex) Apple, Inc.
+000502 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D8-1D-72 (hex) Apple, Inc.
-D81D72 (base 16) Apple, Inc.
+00-10-FA (hex) Apple, Inc.
+0010FA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-94-F6-A3 (hex) Apple, Inc.
-94F6A3 (base 16) Apple, Inc.
+00-03-93 (hex) Apple, Inc.
+000393 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-FD-94 (hex) Apple, Inc.
-78FD94 (base 16) Apple, Inc.
+00-16-CB (hex) Apple, Inc.
+0016CB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-48-D7-05 (hex) Apple, Inc.
-48D705 (base 16) Apple, Inc.
+40-9C-28 (hex) Apple, Inc.
+409C28 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-7C-6D-F8 (hex) Apple, Inc.
-7C6DF8 (base 16) Apple, Inc.
+78-88-6D (hex) Apple, Inc.
+78886D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-3C-AB-8E (hex) Apple, Inc.
-3CAB8E (base 16) Apple, Inc.
+A8-5C-2C (hex) Apple, Inc.
+A85C2C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-7E-61 (hex) Apple, Inc.
-787E61 (base 16) Apple, Inc.
+00-DB-70 (hex) Apple, Inc.
+00DB70 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D4-F4-6F (hex) Apple, Inc.
-D4F46F (base 16) Apple, Inc.
+0C-51-01 (hex) Apple, Inc.
+0C5101 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-85-50 (hex) Apple, Inc.
-C88550 (base 16) Apple, Inc.
+08-6D-41 (hex) Apple, Inc.
+086D41 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-AC-7F-3E (hex) Apple, Inc.
-AC7F3E (base 16) Apple, Inc.
+04-D3-CF (hex) Apple, Inc.
+04D3CF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A4-C3-61 (hex) Apple, Inc.
-A4C361 (base 16) Apple, Inc.
+BC-EC-5D (hex) Apple, Inc.
+BCEC5D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-08-70-45 (hex) Apple, Inc.
-087045 (base 16) Apple, Inc.
+80-B0-3D (hex) Apple, Inc.
+80B03D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-40-33-1A (hex) Apple, Inc.
-40331A (base 16) Apple, Inc.
+C8-3C-85 (hex) Apple, Inc.
+C83C85 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-DC-37-14 (hex) Apple, Inc.
-DC3714 (base 16) Apple, Inc.
+A0-4E-A7 (hex) Apple, Inc.
+A04EA7 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-9F-70 (hex) Apple, Inc.
-789F70 (base 16) Apple, Inc.
+00-17-F2 (hex) Apple, Inc.
+0017F2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-64-B0-A6 (hex) Apple, Inc.
-64B0A6 (base 16) Apple, Inc.
+00-1B-63 (hex) Apple, Inc.
+001B63 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-84-FC-AC (hex) Apple, Inc.
-84FCAC (base 16) Apple, Inc.
+00-1E-C2 (hex) Apple, Inc.
+001EC2 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-19-C0 (hex) Apple, Inc.
-6C19C0 (base 16) Apple, Inc.
+00-26-08 (hex) Apple, Inc.
+002608 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-20-AB-37 (hex) Apple, Inc.
-20AB37 (base 16) Apple, Inc.
+A4-C3-61 (hex) Apple, Inc.
+A4C361 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C0-D0-12 (hex) Apple, Inc.
-C0D012 (base 16) Apple, Inc.
+AC-7F-3E (hex) Apple, Inc.
+AC7F3E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D4-DC-CD (hex) Apple, Inc.
-D4DCCD (base 16) Apple, Inc.
+28-0B-5C (hex) Apple, Inc.
+280B5C (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-48-4B-AA (hex) Apple, Inc.
-484BAA (base 16) Apple, Inc.
+90-B9-31 (hex) Apple, Inc.
+90B931 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F8-03-77 (hex) Apple, Inc.
-F80377 (base 16) Apple, Inc.
+24-A2-E1 (hex) Apple, Inc.
+24A2E1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-14-BD-61 (hex) Apple, Inc.
-14BD61 (base 16) Apple, Inc.
+80-EA-96 (hex) Apple, Inc.
+80EA96 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-78-88-6D (hex) Apple, Inc.
-78886D (base 16) Apple, Inc.
+60-03-08 (hex) Apple, Inc.
+600308 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A8-5C-2C (hex) Apple, Inc.
-A85C2C (base 16) Apple, Inc.
+04-F1-3E (hex) Apple, Inc.
+04F13E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-DB-70 (hex) Apple, Inc.
-00DB70 (base 16) Apple, Inc.
+54-72-4F (hex) Apple, Inc.
+54724F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-BC-EC-5D (hex) Apple, Inc.
-BCEC5D (base 16) Apple, Inc.
+48-74-6E (hex) Apple, Inc.
+48746E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-DC-41-5F (hex) Apple, Inc.
-DC415F (base 16) Apple, Inc.
+D4-F4-6F (hex) Apple, Inc.
+D4F46F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-30-63-6B (hex) Apple, Inc.
-30636B (base 16) Apple, Inc.
+78-7E-61 (hex) Apple, Inc.
+787E61 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-0C-51-01 (hex) Apple, Inc.
-0C5101 (base 16) Apple, Inc.
+60-F8-1D (hex) Apple, Inc.
+60F81D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-08-6D-41 (hex) Apple, Inc.
-086D41 (base 16) Apple, Inc.
+4C-7C-5F (hex) Apple, Inc.
+4C7C5F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-D3-CF (hex) Apple, Inc.
-04D3CF (base 16) Apple, Inc.
+48-E9-F1 (hex) Apple, Inc.
+48E9F1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-20-3C-AE (hex) Apple, Inc.
-203CAE (base 16) Apple, Inc.
+FC-E9-98 (hex) Apple, Inc.
+FCE998 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-74-8D-08 (hex) Apple, Inc.
-748D08 (base 16) Apple, Inc.
+F0-99-BF (hex) Apple, Inc.
+F099BF (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A0-3B-E3 (hex) Apple, Inc.
-A03BE3 (base 16) Apple, Inc.
+68-64-4B (hex) Apple, Inc.
+68644B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-18-65-90 (hex) Apple, Inc.
-186590 (base 16) Apple, Inc.
+78-9F-70 (hex) Apple, Inc.
+789F70 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-10-FA (hex) Apple, Inc.
-0010FA (base 16) Apple, Inc.
+24-AB-81 (hex) Apple, Inc.
+24AB81 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-05-02 (hex) Apple, Inc.
-000502 (base 16) Apple, Inc.
+58-1F-AA (hex) Apple, Inc.
+581FAA (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-78-2E (hex) Apple, Inc.
-B8782E (base 16) Apple, Inc.
+A4-67-06 (hex) Apple, Inc.
+A46706 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A4-D1-8C (hex) Apple, Inc.
-A4D18C (base 16) Apple, Inc.
+3C-07-54 (hex) Apple, Inc.
+3C0754 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-CC-25-EF (hex) Apple, Inc.
-CC25EF (base 16) Apple, Inc.
+E4-CE-8F (hex) Apple, Inc.
+E4CE8F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-68-DB-CA (hex) Apple, Inc.
-68DBCA (base 16) Apple, Inc.
+E8-04-0B (hex) Apple, Inc.
+E8040B (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-04-4B-ED (hex) Apple, Inc.
-044BED (base 16) Apple, Inc.
+B8-C7-5D (hex) Apple, Inc.
+B8C75D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-6C-8D-C1 (hex) Apple, Inc.
-6C8DC1 (base 16) Apple, Inc.
+40-3C-FC (hex) Apple, Inc.
+403CFC (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-38-CA-DA (hex) Apple, Inc.
-38CADA (base 16) Apple, Inc.
+98-FE-94 (hex) Apple, Inc.
+98FE94 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-F4-5C-89 (hex) Apple, Inc.
-F45C89 (base 16) Apple, Inc.
+D8-00-4D (hex) Apple, Inc.
+D8004D (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-58-1F-AA (hex) Apple, Inc.
-581FAA (base 16) Apple, Inc.
+98-B8-E3 (hex) Apple, Inc.
+98B8E3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-24-AB-81 (hex) Apple, Inc.
-24AB81 (base 16) Apple, Inc.
+80-92-9F (hex) Apple, Inc.
+80929F (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-70-CD-60 (hex) Apple, Inc.
-70CD60 (base 16) Apple, Inc.
+88-53-95 (hex) Apple, Inc.
+885395 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-7C-C5-37 (hex) Apple, Inc.
-7CC537 (base 16) Apple, Inc.
+9C-04-EB (hex) Apple, Inc.
+9C04EB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C4-2C-03 (hex) Apple, Inc.
-C42C03 (base 16) Apple, Inc.
+A8-96-8A (hex) Apple, Inc.
+A8968A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-D8-30-62 (hex) Apple, Inc.
-D83062 (base 16) Apple, Inc.
+DC-37-14 (hex) Apple, Inc.
+DC3714 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-40-D3-2D (hex) Apple, Inc.
-40D32D (base 16) Apple, Inc.
+40-33-1A (hex) Apple, Inc.
+40331A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-7C-6D-62 (hex) Apple, Inc.
-7C6D62 (base 16) Apple, Inc.
+94-F6-A3 (hex) Apple, Inc.
+94F6A3 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-28-6A-B8 (hex) Apple, Inc.
-286AB8 (base 16) Apple, Inc.
+D8-1D-72 (hex) Apple, Inc.
+D81D72 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-40-3C-FC (hex) Apple, Inc.
-403CFC (base 16) Apple, Inc.
+70-EC-E4 (hex) Apple, Inc.
+70ECE4 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B8-C7-5D (hex) Apple, Inc.
-B8C75D (base 16) Apple, Inc.
+38-C9-86 (hex) Apple, Inc.
+38C986 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E8-04-0B (hex) Apple, Inc.
-E8040B (base 16) Apple, Inc.
+FC-FC-48 (hex) Apple, Inc.
+FCFC48 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-E4-CE-8F (hex) Apple, Inc.
-E4CE8F (base 16) Apple, Inc.
+4C-8D-79 (hex) Apple, Inc.
+4C8D79 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-3C-07-54 (hex) Apple, Inc.
-3C0754 (base 16) Apple, Inc.
+20-7D-74 (hex) Apple, Inc.
+207D74 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A4-67-06 (hex) Apple, Inc.
-A46706 (base 16) Apple, Inc.
+F4-F1-5A (hex) Apple, Inc.
+F4F15A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-80-B0-3D (hex) Apple, Inc.
-80B03D (base 16) Apple, Inc.
+04-26-65 (hex) Apple, Inc.
+042665 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-C8-3C-85 (hex) Apple, Inc.
-C83C85 (base 16) Apple, Inc.
+2C-B4-3A (hex) Apple, Inc.
+2CB43A (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-A0-4E-A7 (hex) Apple, Inc.
-A04EA7 (base 16) Apple, Inc.
+68-9C-70 (hex) Apple, Inc.
+689C70 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-40-9C-28 (hex) Apple, Inc.
-409C28 (base 16) Apple, Inc.
+08-70-45 (hex) Apple, Inc.
+087045 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-08-E6-89 (hex) Apple, Inc.
-08E689 (base 16) Apple, Inc.
+3C-AB-8E (hex) Apple, Inc.
+3CAB8E (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-4C-B1-99 (hex) Apple, Inc.
-4CB199 (base 16) Apple, Inc.
+7C-6D-F8 (hex) Apple, Inc.
+7C6DF8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-98-D6-BB (hex) Apple, Inc.
-98D6BB (base 16) Apple, Inc.
+48-D7-05 (hex) Apple, Inc.
+48D705 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-3C-D0-F8 (hex) Apple, Inc.
-3CD0F8 (base 16) Apple, Inc.
+78-FD-94 (hex) Apple, Inc.
+78FD94 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-7C-C3-A1 (hex) Apple, Inc.
-7CC3A1 (base 16) Apple, Inc.
+C8-85-50 (hex) Apple, Inc.
+C88550 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-26-08 (hex) Apple, Inc.
-002608 (base 16) Apple, Inc.
+28-6A-B8 (hex) Apple, Inc.
+286AB8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-1E-C2 (hex) Apple, Inc.
-001EC2 (base 16) Apple, Inc.
+7C-C3-A1 (hex) Apple, Inc.
+7CC3A1 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-1B-63 (hex) Apple, Inc.
-001B63 (base 16) Apple, Inc.
+3C-D0-F8 (hex) Apple, Inc.
+3CD0F8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-17-F2 (hex) Apple, Inc.
-0017F2 (base 16) Apple, Inc.
+98-D6-BB (hex) Apple, Inc.
+98D6BB (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-16-CB (hex) Apple, Inc.
-0016CB (base 16) Apple, Inc.
+4C-B1-99 (hex) Apple, Inc.
+4CB199 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-00-03-93 (hex) Apple, Inc.
-000393 (base 16) Apple, Inc.
+64-E6-82 (hex) Apple, Inc.
+64E682 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
@@ -115727,240 +116801,138 @@ A04EA7 (base 16) Apple, Inc. Cupertino CA 95014
US
-64-E6-82 (hex) Apple, Inc.
-64E682 (base 16) Apple, Inc.
+CC-20-E8 (hex) Apple, Inc.
+CC20E8 (base 16) Apple, Inc.
1 Infinite Loop
Cupertino CA 95014
US
-B4-F7-A1 (hex) LG Electronics (Mobile Communications)
-B4F7A1 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-C0-A8-F0 (hex) Adamson Systems Engineering
-C0A8F0 (base 16) Adamson Systems Engineering
- 1401 Scugog Line 6
- Port Perry Ontario L9L 1B2
- CA
-
-38-C9-A9 (hex) SMART High Reliability Solutions, Inc.
-38C9A9 (base 16) SMART High Reliability Solutions, Inc.
- 1325 N Fiesta Blvd., #101
- Gilbert AZ 85233
+20-9B-CD (hex) Apple, Inc.
+209BCD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-28-3B-82 (hex) D-Link International
-283B82 (base 16) D-Link International
- 1 Internal Business Park, #03-12,The Synergy, Singapore
- Singapore Singapore 609917
- SG
-
-C4-00-AD (hex) Advantech Technology (CHINA) Co., Ltd.
-C400AD (base 16) Advantech Technology (CHINA) Co., Ltd.
- No.666, Han-Pu Rd. Yu-Shan
- Kun-Shan Jiang Su 215316
- CN
-
-34-5A-06 (hex) SHARP Corporation
-345A06 (base 16) SHARP Corporation
- 1 Takumi-cho, Sakai-ku
- Sakai City Osaka 590-8522
- JP
-
-0C-8B-D3 (hex) ITEL MOBILE LIMITED
-0C8BD3 (base 16) ITEL MOBILE LIMITED
- RM B3 & B4 BLOCK B, KO FAI INDUSTRIAL BUILDING NO.7 KO FAI ROAD, YAU TONG, KLN, H.K
- Hong Kong KOWLOON 999077
- HK
-
-04-AC-44 (hex) Holtek Semiconductor Inc.
-04AC44 (base 16) Holtek Semiconductor Inc.
- No.3, Creation Rd. II, Science Park
- Hsinchu 300
- TW
-
-F4-DC-A5 (hex) DAWON DNS
-F4DCA5 (base 16) DAWON DNS
- 217ho, Sauphwajiwon-dong, KETI, 226, Cheomdangwagi-ro, Buk-gu
- Gwangju 61011
- KR
-
-50-1C-B0 (hex) Cisco Systems, Inc
-501CB0 (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
+F0-B0-E7 (hex) Apple, Inc.
+F0B0E7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-C4-FF-BC (hex) IEEE Registration Authority
-C4FFBC (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
+A0-56-F3 (hex) Apple, Inc.
+A056F3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-78-58-60 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-785860 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
-
-F8-90-66 (hex) Nain Inc.
-F89066 (base 16) Nain Inc.
- Aoyamadai building 902, Shibuya 2-9-10, Shibuya-ku
- Tokyo 150-0002
- JP
-
-B4-FB-F9 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-B4FBF9 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
-
-B4-2E-F8 (hex) Eline Technology co.Ltd
-B42EF8 (base 16) Eline Technology co.Ltd
- kangcheng Road, Pharmaceutical Industrical Park, Yuanzhou District
- Yichun Jiangxi 336000
- CN
-
-D8-44-5C (hex) DEV Tecnologia Ind Com Man Eq LTDA
-D8445C (base 16) DEV Tecnologia Ind Com Man Eq LTDA
- Av Prof Lineu Prestes 2242 SL 23
- Sao Paulo SP 05508000
- BR
-
-78-5D-C8 (hex) LG Electronics
-785DC8 (base 16) LG Electronics
- 222 LG-ro, JINWI-MYEON
- Pyeongtaek-si Gyeonggi-do 451-713
- KR
+54-99-63 (hex) Apple, Inc.
+549963 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-7C-39-53 (hex) zte corporation
-7C3953 (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
- CN
+28-FF-3C (hex) Apple, Inc.
+28FF3C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-48-C7-96 (hex) Samsung Electronics Co.,Ltd
-48C796 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
+10-94-BB (hex) Apple, Inc.
+1094BB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-80-4E-70 (hex) Samsung Electronics Co.,Ltd
-804E70 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
+F0-18-98 (hex) Apple, Inc.
+F01898 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
-4C-EF-C0 (hex) Amazon Technologies Inc.
-4CEFC0 (base 16) Amazon Technologies Inc.
- P.O Box 8102
- Reno NV 89507
+48-A9-1C (hex) Apple, Inc.
+48A91C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
US
-D4-6D-6D (hex) Intel Corporate
-D46D6D (base 16) Intel Corporate
- Lot 8, Jalan Hi-Tech 2/3
- Kulim Kedah 09000
- MY
+2C-7E-81 (hex) ARRIS Group, Inc.
+2C7E81 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
-CC-8E-71 (hex) Cisco Systems, Inc
-CC8E71 (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
+5C-E3-0E (hex) ARRIS Group, Inc.
+5CE30E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-CC-3B-58 (hex) Curiouser Products Inc
-CC3B58 (base 16) Curiouser Products Inc
- 712 Broadway #4
- New York NY 10003
+78-23-AE (hex) ARRIS Group, Inc.
+7823AE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-38-F5-54 (hex) HISENSE ELECTRIC CO.,LTD
-38F554 (base 16) HISENSE ELECTRIC CO.,LTD
- No. 218, Qianwangang Rd
- Qingdao Shandong 266555
+40-62-31 (hex) GIFA
+406231 (base 16) GIFA
+ 11th Fl., Suojia Business Building , No.7 Hangkong Road , Baoan District
+ Shenzhen Guangdong 518000
CN
-18-94-C6 (hex) ShenZhen Chenyee Technology Co., Ltd.
-1894C6 (base 16) ShenZhen Chenyee Technology Co., Ltd.
- 32F, Tower A, East Pacific International Center, No.7888, Shennan Avenue, Futian District
- Shenzhen 518040
+04-8A-E1 (hex) FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.
+048AE1 (base 16) FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.
+ Xin Qing Science & Technology Industrial Park,Jin An Town,Doumen ,Zhuhai,Guangdong,PRC
+ Zhuhai Guangdong 519180
CN
-14-A7-2B (hex) currentoptronics Pvt.Ltd
-14A72B (base 16) currentoptronics Pvt.Ltd
- CRT Building, Jupitor Jn , Near Time kids Koothattukulam - Piravom Rd
- ERNAKULAM Time Kids day care 686662
- IN
+0C-21-38 (hex) Hengstler GmbH
+0C2138 (base 16) Hengstler GmbH
+ Uhlandstrasse49
+ Aldingen BW 78554
+ DE
-AC-07-5F (hex) HUAWEI TECHNOLOGIES CO.,LTD
-AC075F (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
+CC-C2-E0 (hex) Raisecom Technology CO., LTD
+CCC2E0 (base 16) Raisecom Technology CO., LTD
+ No. 11, East Area, No. 10 Block, East Xibeiwang Road
+ Beijing 100094
CN
-88-17-A3 (hex) Integrated Device Technology (Malaysia) Sdn. Bhd.
-8817A3 (base 16) Integrated Device Technology (Malaysia) Sdn. Bhd.
- Phase 3, Bayan Lepas FIZ
- Bayan Lepas Penang 11900
- MY
+4C-C0-0A (hex) vivo Mobile Communication Co., Ltd.
+4CC00A (base 16) vivo Mobile Communication Co., Ltd.
+ #283,BBK Road
+ Wusha,Chang'An DongGuan City,Guangdong, 523860
+ CN
-00-71-47 (hex) Amazon Technologies Inc.
-007147 (base 16) Amazon Technologies Inc.
- P.O Box 8102
- Reno NV 89507
+A0-75-EA (hex) BoxLock, Inc.
+A075EA (base 16) BoxLock, Inc.
+ 931 Monroe Dr Ste A 102-405
+ Atlanta GA 30308
US
-78-8C-54 (hex) Ping Communication
-788C54 (base 16) Ping Communication
- Brenden 18
- Appenzell Meistersrüte AI 9050
- CH
-
-D4-66-A8 (hex) Riedo Networks Ltd
-D466A8 (base 16) Riedo Networks Ltd
- Route de la Fonderie 6
- Fribourg 1700
- CH
-
-30-B7-D4 (hex) Hitron Technologies. Inc
-30B7D4 (base 16) Hitron Technologies. Inc
- No. 1-8, Lising 1st Rd. Hsinchu Science Park, Hsinchu, 300, Taiwan, R.O.C
- Hsin-chu Taiwan 300
- TW
-
-38-80-DF (hex) Motorola Mobility LLC, a Lenovo Company
-3880DF (base 16) Motorola Mobility LLC, a Lenovo Company
- 222 West Merchandise Mart Plaza
- Chicago IL 60654
+70-01-B5 (hex) Cisco Systems, Inc
+7001B5 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
US
-7C-B2-32 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-7CB232 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
- CN
-
-2C-D9-74 (hex) Hui Zhou Gaoshengda Technology Co.,LTD
-2CD974 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
- No.75,Zhongkai High-Tech Development District,Huizhou
- Hui Zhou Guangdong 516006
- CN
-
-58-B3-FC (hex) SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
-58B3FC (base 16) SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
- Bldg56A,6/F,Baotian Rd3,Xixiang Town,Baoan District,
- Shenzhen Guangdong 518000
- CN
+A0-B0-45 (hex) Halong Mining
+A0B045 (base 16) Halong Mining
+ 13/F TCL Tower, No.8 Tai Chung Road
+ Tsuen Wan New Territories Tsuen Wan New Territories
+ HK
-BC-AB-7C (hex) TRnP KOREA Co Ltd
-BCAB7C (base 16) TRnP KOREA Co Ltd
- room1308,239 SoHyungRo,WonMiGu,
- BuChunCity KyungKiDo 1135
+EC-AF-97 (hex) GIT
+ECAF97 (base 16) GIT
+ 05655, GIT Bldg., 87, Macheon-ro, Songpa-gu, Seoul, Korea
+ Songpa-gu Seoul 05655
KR
+6C-21-A2 (hex) AMPAK Technology, Inc.
+6C21A2 (base 16) AMPAK Technology, Inc.
+ No.1,Jen Ai Road Hsinchu Industrial Park, Hukou
+ Hsinchu Taiwan ROC. 30352
+ TW
+
2C-39-96 (hex) Sagemcom Broadband SAS
2C3996 (base 16) Sagemcom Broadband SAS
250 route de l'Empereur
@@ -116543,12 +117515,6 @@ B075D5 (base 16) zte corporation Shenzhen GUANGDONG 518057
CN
-B0-A3-7E (hex) Qingdao Haier Telecom Co.,Ltd
-B0A37E (base 16) Qingdao Haier Telecom Co.,Ltd
- No.1,Haier Road,Qingdao 266101 P.R.China
- Qingdao Shandong 266101
- CN
-
70-A8-E3 (hex) HUAWEI TECHNOLOGIES CO.,LTD
70A8E3 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
D1,Huawei Industrial Base,Bantian,Longgang,Shenzhen
@@ -126140,12 +127106,6 @@ DC3350 (base 16) TechSAT GmbH Shantou Guangdong 515041
CN
-00-1D-FA (hex) Fujian LANDI Commercial Equipment Co.,Ltd
-001DFA (base 16) Fujian LANDI Commercial Equipment Co.,Ltd
- Building 23,the 1st section,Software Garden
- Fuzhou Fujian 350003
- CN
-
00-1D-F3 (hex) SBS Science & Technology Co., Ltd
001DF3 (base 16) SBS Science & Technology Co., Ltd
W2-B5/6 High-tech industrial park
@@ -141077,12 +142037,6 @@ FC3D93 (base 16) LONGCHEER TELECOMMUNICATION LIMITED Milpitas CA 95035
US
-00-14-8C (hex) General Dynamics Mission Systems
-00148C (base 16) General Dynamics Mission Systems
- 150 Rustcraft Road
- Dedham MA 02026
- US
-
A4-71-74 (hex) HUAWEI TECHNOLOGIES CO.,LTD
A47174 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
@@ -141641,6 +142595,2136 @@ C0E54E (base 16) ARIES Embedded GmbH Fürstenfeldbruck D-82256
DE
+B4-A3-82 (hex) Hangzhou Hikvision Digital Technology Co.,Ltd.
+B4A382 (base 16) Hangzhou Hikvision Digital Technology Co.,Ltd.
+ No.555 Qianmo Road
+ Hangzhou Zhejiang 310052
+ CN
+
+3C-A6-16 (hex) vivo Mobile Communication Co., Ltd.
+3CA616 (base 16) vivo Mobile Communication Co., Ltd.
+ #283,BBK Road
+ Wusha,Chang'An DongGuan City,Guangdong, 523860
+ CN
+
+88-B4-A6 (hex) Motorola Mobility LLC, a Lenovo Company
+88B4A6 (base 16) Motorola Mobility LLC, a Lenovo Company
+ 222 West Merchandise Mart Plaza
+ Chicago IL 60654
+ US
+
+74-28-57 (hex) Mayfield Robotics
+742857 (base 16) Mayfield Robotics
+ 400 Convention Way
+ Redwood City CA 94063
+ US
+
+00-CB-00 (hex) Private
+00CB00 (base 16) Private
+
+60-9B-C8 (hex) Hipad Intelligent Technology Co., Ltd.
+609BC8 (base 16) Hipad Intelligent Technology Co., Ltd.
+ No. 688, East of Huangtang Street, LinkongEconomy District
+ Nanchang Jiangxi 330000
+ CN
+
+1C-0F-AF (hex) Lucid Vision Labs
+1C0FAF (base 16) Lucid Vision Labs
+ Unit 130 - 13200 Delf Place
+ Richmond BC V6V2A2
+ CA
+
+24-5C-CB (hex) AXIe Consortium, Inc.
+245CCB (base 16) AXIe Consortium, Inc.
+ P.O. Box 1016
+ Niwot CO 80544-1016
+ US
+
+F8-F2-1E (hex) Intel Corporate
+F8F21E (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+28-29-86 (hex) APC by Schneider Electric
+282986 (base 16) APC by Schneider Electric
+ 800 Federal St.
+ Andover MA 01810
+ US
+
+74-DA-38 (hex) Edimax Technology Co. Ltd.
+74DA38 (base 16) Edimax Technology Co. Ltd.
+ No. 278, Xinhu 1st Road
+ Taipei City Neihu Dist 248
+ TW
+
+38-6B-1C (hex) SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
+386B1C (base 16) SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
+ 3/F, Building R1-B, High-Tech Industrial Park, Nanshan District
+ Shenzhen Guangdong 518057
+ CN
+
+38-01-9F (hex) SHENZHEN FAST TECHNOLOGIES CO.,LTD
+38019F (base 16) SHENZHEN FAST TECHNOLOGIES CO.,LTD
+ Room 202,Building No.5,Section 30,No.2 of Kefa Road,Nanshan District,Shenzhen,P.R.China
+ Shenzhen Guangdong 518057
+ CN
+
+00-24-24 (hex) Ace Axis Limited
+002424 (base 16) Ace Axis Limited
+ 602 Delta Business Park, Welton Road
+ Swindon SN5 7XP
+ GB
+
+8C-83-9D (hex) SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD
+8C839D (base 16) SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD
+ ROOM 1505,BIT INNOVATION BUILDING,SCIENCE AND TECHNOLOGY PARK,NANSHAN DISTRICT
+ Shenzhen 518057
+ CN
+
+EC-FA-F4 (hex) SenRa Tech Pvt. Ltd
+ECFAF4 (base 16) SenRa Tech Pvt. Ltd
+ 133, First Floor, Lane No. 1, Westend Marg, Saidulajab
+ New Delhi 110030
+ IN
+
+70-99-1C (hex) Shenzhen Honesty Electronics Co.,Ltd
+70991C (base 16) Shenzhen Honesty Electronics Co.,Ltd
+ 5/F,Zone B,Chitat Industrial Park,West Longping Road
+ Shenzhen City Longgang District, Guangdong 518172
+ CN
+
+00-81-F9 (hex) Texas Instruments
+0081F9 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+58-7A-62 (hex) Texas Instruments
+587A62 (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+D0-67-26 (hex) Hewlett Packard Enterprise
+D06726 (base 16) Hewlett Packard Enterprise
+ 8000 Foothills Blvd.
+ Roseville CA 95747
+ US
+
+28-23-73 (hex) Digita
+282373 (base 16) Digita
+ Jämsänkatu 2
+ Helsinki Uusimaa 00520
+ FI
+
+44-CD-0E (hex) FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.
+44CD0E (base 16) FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.
+ Xin Qing Science & Technology Industrial Park,Jin An Town,Doumen ,Zhuhai,Guangdong,PRC
+ Zhuhai Guangdong 519180
+ CN
+
+08-84-66 (hex) Novartis Pharma AG
+088466 (base 16) Novartis Pharma AG
+ Lichtstrasse 35
+ Basel 4056
+ CH
+
+00-1F-7D (hex) Embedded Wireless GmbH
+001F7D (base 16) Embedded Wireless GmbH
+ Soeflinger Strasse 200
+ Ulm BW 89077
+ DE
+
+94-7B-BE (hex) Ubicquia
+947BBE (base 16) Ubicquia
+ 3281 Fairlane Farms Rd
+ Wellington FL 33449
+ US
+
+E8-2A-44 (hex) Liteon Technology Corporation
+E82A44 (base 16) Liteon Technology Corporation
+ 4F, 90, Chien 1 Road
+ New Taipei City Taiwan 23585
+ TW
+
+00-05-A7 (hex) HYPERCHIP Inc.
+0005A7 (base 16) HYPERCHIP Inc.
+ 180 Peel Street - Ste. #333
+ H3C 2G7
+ CA
+
+78-DD-D9 (hex) Guangzhou Shiyuan Electronics Co., Ltd.
+78DDD9 (base 16) Guangzhou Shiyuan Electronics Co., Ltd.
+ No.6, 4th Yunpu Road, Yunpu Industry District
+ Guangzhou Guangdong 510530
+ CN
+
+00-09-66 (hex) TRIMBLE EUROPE BV
+000966 (base 16) TRIMBLE EUROPE BV
+ Meerheide 45
+ Eersel DZ 5521
+ NL
+
+EC-B0-E1 (hex) Ciena Corporation
+ECB0E1 (base 16) Ciena Corporation
+ 7035 Ridge Road
+ Hanover MD 21076
+ US
+
+58-C1-7A (hex) Cambium Networks Limited
+58C17A (base 16) Cambium Networks Limited
+ Unit B2, Linhay Business Park,
+ Ashburton Devon TQ13 7UP
+ GB
+
+2C-54-91 (hex) Microsoft Corporation
+2C5491 (base 16) Microsoft Corporation
+ One Microsoft Way
+ REDMOND WA 98052
+ US
+
+04-50-DA (hex) Qiku Internet Network Scientific (Shenzhen) Co., Ltd
+0450DA (base 16) Qiku Internet Network Scientific (Shenzhen) Co., Ltd
+ Building A2, Chi Yuen Technology Park 1001 College Avenue, Nanshan District Shenzhen, Guangdong
+ Shenzhen Guangdong 518000
+ CN
+
+08-BC-20 (hex) Hangzhou Royal Cloud Technology Co., Ltd
+08BC20 (base 16) Hangzhou Royal Cloud Technology Co., Ltd
+ Hangzhou Xixi Road 957, 24, Unit 2, 302
+ Hangzhou 310030
+ CN
+
+5C-70-A3 (hex) LG Electronics (Mobile Communications)
+5C70A3 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+10-F9-6F (hex) LG Electronics (Mobile Communications)
+10F96F (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+F0-1C-13 (hex) LG Electronics (Mobile Communications)
+F01C13 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+00-AA-70 (hex) LG Electronics (Mobile Communications)
+00AA70 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+BC-F5-AC (hex) LG Electronics (Mobile Communications)
+BCF5AC (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+CC-FA-00 (hex) LG Electronics (Mobile Communications)
+CCFA00 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+F8-A9-D0 (hex) LG Electronics (Mobile Communications)
+F8A9D0 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+80-5A-04 (hex) LG Electronics (Mobile Communications)
+805A04 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+5C-AF-06 (hex) LG Electronics (Mobile Communications)
+5CAF06 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+B8-1D-AA (hex) LG Electronics (Mobile Communications)
+B81DAA (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+10-F1-F2 (hex) LG Electronics (Mobile Communications)
+10F1F2 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+00-25-E5 (hex) LG Electronics (Mobile Communications)
+0025E5 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+00-22-A9 (hex) LG Electronics (Mobile Communications)
+0022A9 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+C4-9A-02 (hex) LG Electronics (Mobile Communications)
+C49A02 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+34-4D-F7 (hex) LG Electronics (Mobile Communications)
+344DF7 (base 16) LG Electronics (Mobile Communications)
+ 60-39, Gasan-dong, Geumcheon-gu
+ Seoul 153-801
+ KR
+
+44-91-60 (hex) Murata Manufacturing Co., Ltd.
+449160 (base 16) Murata Manufacturing Co., Ltd.
+ 1-10-1, Higashikotari
+ Nagaokakyo-shi Kyoto 617-8555
+ JP
+
+44-D5-A5 (hex) AddOn Computer
+44D5A5 (base 16) AddOn Computer
+ 15775 Gateway cir
+ tustin CA 92780
+ US
+
+00-AE-CD (hex) Pensando Systems
+00AECD (base 16) Pensando Systems
+ 1730 Technology Drive, Suite 202
+ San Jose CA 95110
+ US
+
+44-AD-19 (hex) XINGFEI (H.K)LIMITED
+44AD19 (base 16) XINGFEI (H.K)LIMITED
+ 6/F North Tower Wandelai Building No.29 Kejinan 6th Road, Nanshan District,Shenzhen,China
+ Shenzhen 518057
+ CN
+
+D8-96-E0 (hex) Alibaba Cloud Computing Ltd.
+D896E0 (base 16) Alibaba Cloud Computing Ltd.
+ Yuhang District of Hangzhou Wenyi Road, Building 1, No. 969 Xixi Park, Zhejiang Province
+ Hangzhou Zhejiang 310000
+ CN
+
+30-EB-1F (hex) Skylab M&C Technology Co.,Ltd
+30EB1F (base 16) Skylab M&C Technology Co.,Ltd
+ 6 Floor,No.9 Building,Lijincheng Scientific&Technical park,Gongye East Road,Longhua District
+ Shenzhen Guangdong 518109
+ CN
+
+B0-B2-DC (hex) Zyxel Communications Corporation
+B0B2DC (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+00-23-F8 (hex) Zyxel Communications Corporation
+0023F8 (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+4C-9E-FF (hex) Zyxel Communications Corporation
+4C9EFF (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+5C-F4-AB (hex) Zyxel Communications Corporation
+5CF4AB (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+14-79-F3 (hex) China Mobile Group Device Co.,Ltd.
+1479F3 (base 16) China Mobile Group Device Co.,Ltd.
+ 32 Xuanwumen West Street,Xicheng District
+ Beijing 100053
+ CN
+
+90-EF-68 (hex) Zyxel Communications Corporation
+90EF68 (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+28-28-5D (hex) Zyxel Communications Corporation
+28285D (base 16) Zyxel Communications Corporation
+ No. 6 Innovation Road II, Science Park
+ Hsichu Taiwan 300
+ TW
+
+4C-AE-1C (hex) SaiNXT Technologies LLP
+4CAE1C (base 16) SaiNXT Technologies LLP
+ Shop No. 7, Sonawala Building, 1st Floor, Proctor Road, Grant Road (E)
+ Mumbai Maharashtra 400007
+ IN
+
+4C-91-0C (hex) Lanix Internacional, S.A. de C.V.
+4C910C (base 16) Lanix Internacional, S.A. de C.V.
+ Carretera Nogales Km8.5
+ Hermosillo Sonora 83160
+ MX
+
+2C-42-05 (hex) Lytx
+2C4205 (base 16) Lytx
+ 9785 Towne Centre Drive
+ San Diego CA 92121
+ US
+
+00-90-F1 (hex) Seagate Cloud Systems Inc
+0090F1 (base 16) Seagate Cloud Systems Inc
+ 6305 El Camino Real
+ Carlsbad CA 92009
+ US
+
+D4-5D-DF (hex) PEGATRON CORPORATION
+D45DDF (base 16) PEGATRON CORPORATION
+ 5F No. 76, Ligong St., Beitou District
+ Taipei City Taiwan 112
+ TW
+
+D4-1A-3F (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+D41A3F (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+ NO.18 HAIBIN ROAD,
+ DONG GUAN GUANG DONG 523860
+ CN
+
+00-50-13 (hex) Seagate Cloud Systems Inc
+005013 (base 16) Seagate Cloud Systems Inc
+ 7420 E. Dry Creek Parkway
+ Longmont CO 80503
+ US
+
+00-C0-FF (hex) Seagate Cloud Systems Inc
+00C0FF (base 16) Seagate Cloud Systems Inc
+ 6305 El Camino Real
+ Carlsbad CA 92009
+ US
+
+EC-81-93 (hex) Logitech, Inc
+EC8193 (base 16) Logitech, Inc
+ 4700 NW Camas Meadows Drive
+ Camas WA 98607
+ US
+
+D0-96-FB (hex) DASAN Network Solutions
+D096FB (base 16) DASAN Network Solutions
+ DASAN Tower 8F, 49 Daewangpangyo-ro644beon-gil Bundang-gu
+ Seongnam-si Gyeonggi-do 13493
+ KR
+
+5C-52-1E (hex) Nintendo Co.,Ltd
+5C521E (base 16) Nintendo Co.,Ltd
+ 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
+ KYOTO KYOTO 601-8501
+ JP
+
+A8-25-EB (hex) Cambridge Industries(Group) Co.,Ltd.
+A825EB (base 16) Cambridge Industries(Group) Co.,Ltd.
+ 5/F,Building 8, 2388 ChenHang Road, MinHang District
+ shanghai 201114
+ CN
+
+D8-C8-E9 (hex) Phicomm (Shanghai) Co., Ltd.
+D8C8E9 (base 16) Phicomm (Shanghai) Co., Ltd.
+ 3666 SiXian Rd.,Songjiang District
+ Shanghai Shanghai 201616
+ CN
+
+64-F8-8A (hex) China Mobile IOT Company Limited
+64F88A (base 16) China Mobile IOT Company Limited
+ NO.8 Yu Ma Road, NanAn Area Chongqing,China
+ Chongqing Chongqing 401336
+ CN
+
+6C-49-C1 (hex) o2ones Co., Ltd.
+6C49C1 (base 16) o2ones Co., Ltd.
+ 503 Glory Tower, 3-10, Gumi-ro 9beon-gil, Bundang-gu
+ Seongnam-si Gyeonggi-do 13637
+ KR
+
+68-DB-54 (hex) Phicomm (Shanghai) Co., Ltd.
+68DB54 (base 16) Phicomm (Shanghai) Co., Ltd.
+ 3666 SiXian Rd.,Songjiang District
+ Shanghai Shanghai 201616
+ CN
+
+E4-8F-34 (hex) Vodafone Italia S.p.A.
+E48F34 (base 16) Vodafone Italia S.p.A.
+ Via Lorenteggio nr. 240
+ Milan Italy 20147
+ IT
+
+2C-6B-7D (hex) Texas Instruments
+2C6B7D (base 16) Texas Instruments
+ 12500 TI Blvd
+ Dallas TX 75243
+ US
+
+78-80-38 (hex) FUNAI ELECTRIC CO., LTD.
+788038 (base 16) FUNAI ELECTRIC CO., LTD.
+ 7-1, NAKAGAITO 7-CHOME
+ DAITO OSAKA 5740013
+ JP
+
+00-01-30 (hex) Extreme Networks, Inc.
+000130 (base 16) Extreme Networks, Inc.
+ 3585 Monroe Street
+ Santa Clara CA 95051
+ US
+
+CC-6E-A4 (hex) Samsung Electronics Co.,Ltd
+CC6EA4 (base 16) Samsung Electronics Co.,Ltd
+ 129, Samsung-ro, Youngtongl-Gu
+ Suwon Gyeonggi-Do 16677
+ KR
+
+C4-77-AF (hex) Advanced Digital Broadcast SA
+C477AF (base 16) Advanced Digital Broadcast SA
+ Route de Crassier 21, B2
+ Eysins CH-1262
+ CH
+
+20-DF-B9 (hex) Google, Inc.
+20DFB9 (base 16) Google, Inc.
+ 1600 Amphitheatre Parkway
+ Mountain View CA 94043
+ US
+
+44-F0-34 (hex) Kaonmedia CO., LTD.
+44F034 (base 16) Kaonmedia CO., LTD.
+ 884-3, Seongnam-daero, Bundang-gu
+ Seongnam-si Gyeonggi-do 13517
+ KR
+
+14-78-0B (hex) Varex Imaging Deutschland AG
+14780B (base 16) Varex Imaging Deutschland AG
+ Zweigniederlassung/Branch Walluf
+ In der Rehbach 22 Walluf 65396
+ DE
+
+10-CD-6E (hex) FISYS
+10CD6E (base 16) FISYS
+ 303 Expotel, 44, Dunsan-daero 117beon-gil, Seo-gu, Daejeon, Korea
+ Daejeon, Korea KS015
+ KR
+
+A4-6C-F1 (hex) Samsung Electronics Co.,Ltd
+A46CF1 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+0C-A8-A7 (hex) Samsung Electronics Co.,Ltd
+0CA8A7 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+54-B8-02 (hex) Samsung Electronics Co.,Ltd
+54B802 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+28-2C-02 (hex) IEEE Registration Authority
+282C02 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+B8-C7-16 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+B8C716 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+D0-59-95 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+D05995 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+54-DF-24 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+54DF24 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+58-3B-D9 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+583BD9 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+BC-C0-0F (hex) Fiberhome Telecommunication Technologies Co.,LTD
+BCC00F (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+F0-40-7B (hex) Fiberhome Telecommunication Technologies Co.,LTD
+F0407B (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+F0-8C-FB (hex) Fiberhome Telecommunication Technologies Co.,LTD
+F08CFB (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan City Hubei Province 430074
+ CN
+
+EC-8A-C7 (hex) Fiberhome Telecommunication Technologies Co.,LTD
+EC8AC7 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
+ No.5 DongXin Road
+ Wuhan Hubei 430074
+ CN
+
+00-50-79 (hex) Private
+005079 (base 16) Private
+
+5C-00-38 (hex) Viasat Group S.p.A.
+5C0038 (base 16) Viasat Group S.p.A.
+ Via Aosta 23
+ Venaria Reale Torino 10078
+ IT
+
+E4-CB-59 (hex) Beijing Loveair Science and Technology Co. Ltd.
+E4CB59 (base 16) Beijing Loveair Science and Technology Co. Ltd.
+ 103,Block B, Kelin Building, No.107, Dongsi North Street, Dongcheng District,
+ Beijing 100000
+ CN
+
+C8-77-65 (hex) Tiesse SpA
+C87765 (base 16) Tiesse SpA
+ Via Asti
+ Ivrea TO 10015
+ IT
+
+60-5F-8D (hex) eero inc.
+605F8D (base 16) eero inc.
+ 500 Howard Street, Suite 900
+ SAN FRANCISCO CA 94105
+ US
+
+B4-DE-DF (hex) zte corporation
+B4DEDF (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+84-74-60 (hex) zte corporation
+847460 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+B4-A8-B9 (hex) Cisco Systems, Inc
+B4A8B9 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+88-B6-EE (hex) Dish Technologies Corp
+88B6EE (base 16) Dish Technologies Corp
+ 94 Inverness Terrace E
+ Englewood CO 80112
+ US
+
+38-E6-0A (hex) Xiaomi Communications Co Ltd
+38E60A (base 16) Xiaomi Communications Co Ltd
+ The Rainbow City of China Resources
+ NO.68, Qinghe Middle Street Haidian District, Beijing 100085
+ CN
+
+C0-42-D0 (hex) Juniper Networks
+C042D0 (base 16) Juniper Networks
+ 1133 Innovation Way
+ Sunnyvale CA 94089
+ US
+
+E8-33-0D (hex) Xaptec GmbH
+E8330D (base 16) Xaptec GmbH
+ Neidenburger Str. 10
+ Gelsenkirchen 45897
+ DE
+
+D8-D7-75 (hex) Sagemcom Broadband SAS
+D8D775 (base 16) Sagemcom Broadband SAS
+ 250, route de l'Empereur
+ Rueil Malmaison Cedex hauts de seine 92848
+ FR
+
+78-53-64 (hex) SHIFT GmbH
+785364 (base 16) SHIFT GmbH
+ Am Gänsemarkt 6
+ Wabern Falkenberg Hessen 34590
+ DE
+
+24-18-1D (hex) SAMSUNG ELECTRO-MECHANICS(THAILAND)
+24181D (base 16) SAMSUNG ELECTRO-MECHANICS(THAILAND)
+ 93Moo5T. Bangsamak SEMTHAI, WELLGROW INDUSTRIAL ESTATE
+ Bangpakong Chachoengsao 24180
+ TH
+
+54-B7-E5 (hex) Rayson Technology Co., Ltd.
+54B7E5 (base 16) Rayson Technology Co., Ltd.
+ 1F No.9 R&D Rd.II, Science-Based Industrial Park
+ Hsin-Chu 300
+ TW
+
+BC-0F-A7 (hex) Ouster
+BC0FA7 (base 16) Ouster
+ 350 Treat Ave
+ San Francisco CA 94110
+ US
+
+AC-F9-70 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+ACF970 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+0C-41-E9 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+0C41E9 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+58-D7-59 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+58D759 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+B4-1C-30 (hex) zte corporation
+B41C30 (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+F4-C2-48 (hex) Samsung Electronics Co.,Ltd
+F4C248 (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+A8-51-5B (hex) Samsung Electronics Co.,Ltd
+A8515B (base 16) Samsung Electronics Co.,Ltd
+ #94-1, Imsoo-Dong
+ Gumi Gyeongbuk 730-350
+ KR
+
+60-6B-FF (hex) Nintendo Co.,Ltd
+606BFF (base 16) Nintendo Co.,Ltd
+ 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
+ KYOTO KYOTO 601-8501
+ JP
+
+AC-17-C8 (hex) Cisco Meraki
+AC17C8 (base 16) Cisco Meraki
+ 500 Terry A. Francois Blvd
+ San Francisco 94158
+ US
+
+EC-9B-8B (hex) Hewlett Packard Enterprise
+EC9B8B (base 16) Hewlett Packard Enterprise
+ 8000 Foothills Blvd.
+ Roseville CA 95747
+ US
+
+70-D0-81 (hex) Beijing Netpower Technologies Inc.
+70D081 (base 16) Beijing Netpower Technologies Inc.
+ Room 201, Block B, NO. 15 Building, EastZone
+ Courtyard10, Xibeiwang East Road Haidian District, Beijing 100094
+ CN
+
+70-C9-4E (hex) Liteon Technology Corporation
+70C94E (base 16) Liteon Technology Corporation
+ 4F, 90, Chien 1 Road
+ New Taipei City Taiwan 23585
+ TW
+
+18-0F-76 (hex) D-Link International
+180F76 (base 16) D-Link International
+ 1 Internal Business Park, #03-12,The Synergy, Singapore
+ Singapore Singapore 609917
+ SG
+
+70-3A-73 (hex) Shenzhen Sundray Technologies Company Limited
+703A73 (base 16) Shenzhen Sundray Technologies Company Limited
+ 6th Floor,Block A1, Nanshan iPark, No.1001 XueYuan Road, Nanshan District
+ Shenzhen Guangdong 518057
+ CN
+
+18-4C-08 (hex) Rockwell Automation
+184C08 (base 16) Rockwell Automation
+ 1 Allen-Bradley Dr.
+ Mayfield Heights OH 44124-6118
+ US
+
+98-D8-63 (hex) Shanghai High-Flying Electronics Technology Co., Ltd
+98D863 (base 16) Shanghai High-Flying Electronics Technology Co., Ltd
+ Room 1002 ,#1Building,No.3000 Longdong Avenue,Pudong District,Shanghai,China
+ shanghai shanghai 201203
+ CN
+
+F0-0F-EC (hex) HUAWEI TECHNOLOGIES CO.,LTD
+F00FEC (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+0C-70-4A (hex) HUAWEI TECHNOLOGIES CO.,LTD
+0C704A (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+88-E9-0F (hex) innomdlelab
+88E90F (base 16) innomdlelab
+ Unnam 1 gil, 3
+ Seocho-gu Seoul 06778
+ KR
+
+54-A6-5C (hex) Technicolor CH USA Inc.
+54A65C (base 16) Technicolor CH USA Inc.
+ 101 West 103rd St.
+ Indianapolis IN 46290
+ US
+
+C0-98-DA (hex) China Mobile IOT Company Limited
+C098DA (base 16) China Mobile IOT Company Limited
+ NO.8 Yu Ma Road, NanAn Area Chongqing,China
+ Chongqing Chongqing 401336
+ CN
+
+94-9F-3E (hex) Sonos, Inc.
+949F3E (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+B8-E9-37 (hex) Sonos, Inc.
+B8E937 (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+78-28-CA (hex) Sonos, Inc.
+7828CA (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+34-7E-5C (hex) Sonos, Inc.
+347E5C (base 16) Sonos, Inc.
+ 614 Chapala St
+ Santa Barbara CA 93101
+ US
+
+C0-48-E6 (hex) Samsung Electronics Co.,Ltd
+C048E6 (base 16) Samsung Electronics Co.,Ltd
+ 129, Samsung-ro, Youngtongl-Gu
+ Suwon Gyeonggi-Do 16677
+ KR
+
+B0-26-80 (hex) Cisco Systems, Inc
+B02680 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+6C-E4-DA (hex) NEC Platforms, Ltd.
+6CE4DA (base 16) NEC Platforms, Ltd.
+ 2-3 Kandatsukasamachi
+ Chiyodaku Tokyo 101-8532
+ JP
+
+C8-8F-26 (hex) Skyworth Digital Technology(Shenzhen) Co.,Ltd
+C88F26 (base 16) Skyworth Digital Technology(Shenzhen) Co.,Ltd
+ 7F,Block A,Skyworth Building,
+ Shenzhen Guangdong 518057
+ CN
+
+48-BD-3D (hex) New H3C Technologies Co., Ltd
+48BD3D (base 16) New H3C Technologies Co., Ltd
+ 466 Changhe Road, Binjiang District
+ Hangzhou Zhejiang 310052
+ CN
+
+4C-AB-FC (hex) zte corporation
+4CABFC (base 16) zte corporation
+ 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
+ shenzhen guangdong 518057
+ CN
+
+20-0F-70 (hex) FOXTECH
+200F70 (base 16) FOXTECH
+ 152-160 City Road
+ LONDON KEMP HOUSE EC1V 2NX
+ GB
+
+00-3C-10 (hex) Cisco Systems, Inc
+003C10 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+90-83-4B (hex) BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD
+90834B (base 16) BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD
+ 1-411Room 19#Building No.26 Xihuan South Rd. BDA Daxing District,
+ BEIJING 100176
+ CN
+
+E8-1A-AC (hex) ORFEO SOUNDWORKS Inc.
+E81AAC (base 16) ORFEO SOUNDWORKS Inc.
+ 612, 11-41, Simin-daero 327beon-gil, Dongan-gu
+ Anyang 14055
+ KR
+
+A0-38-F8 (hex) OURA Health Oy
+A038F8 (base 16) OURA Health Oy
+ Elektroniikkatie 3
+ Oulu 90590
+ FI
+
+14-6B-9C (hex) SHENZHEN BILIAN ELECTRONIC CO.,LTD
+146B9C (base 16) SHENZHEN BILIAN ELECTRONIC CO.,LTD
+ NO.268, Fuqian Rd, Jutang community, Guanlan Town, Longhua New district
+ shenzhen guangdong 518000
+ CN
+
+D0-77-14 (hex) Motorola Mobility LLC, a Lenovo Company
+D07714 (base 16) Motorola Mobility LLC, a Lenovo Company
+ 222 West Merchandise Mart Plaza
+ Chicago IL 60654
+ US
+
+34-D7-12 (hex) Smartisan Digital Co., Ltd
+34D712 (base 16) Smartisan Digital Co., Ltd
+ 4F, China Digital Kingdom, No.1 Wangjing North Road, Chaoyang District
+ Beijing Beijing 100012
+ CN
+
+98-45-62 (hex) Shanghai Baud Data Communication Co.,Ltd.
+984562 (base 16) Shanghai Baud Data Communication Co.,Ltd.
+ NO.123 JULI RD
+ PUDONG ZHANGJIANG HIGH-TECH PARK SHANGHAI 201203
+ CN
+
+E8-98-6D (hex) Palo Alto Networks
+E8986D (base 16) Palo Alto Networks
+ 3000 Tannery Way
+ Santa Clara CA 95054
+ US
+
+F0-81-73 (hex) Amazon Technologies Inc.
+F08173 (base 16) Amazon Technologies Inc.
+ P.O Box 8102
+ Reno 89507
+ US
+
+24-29-FE (hex) KYOCERA Corporation
+2429FE (base 16) KYOCERA Corporation
+ 30 Hoji
+ Kitami, Hokkaido 099-1595
+ JP
+
+A4-93-3F (hex) HUAWEI TECHNOLOGIES CO.,LTD
+A4933F (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+88-11-96 (hex) HUAWEI TECHNOLOGIES CO.,LTD
+881196 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+F0-AF-50 (hex) Phantom Intelligence
+F0AF50 (base 16) Phantom Intelligence
+ 319 Rue Franquet Suite F
+ Quebec QC G1P 4R4
+ CA
+
+F4-BC-97 (hex) Shenzhen Crave Communication Co., LTD
+F4BC97 (base 16) Shenzhen Crave Communication Co., LTD
+ F3,8Building, DongFangMing IndustryZone, No.83 DabaoRD., 33 District BaoAn
+ Shenzhen 518000
+ CN
+
+28-FE-DE (hex) COMESTA, Inc.
+28FEDE (base 16) COMESTA, Inc.
+ Techno1-ro 61-7, Yuseong-gu,
+ Daejeon 34014
+ KR
+
+34-E8-94 (hex) TP-LINK TECHNOLOGIES CO.,LTD.
+34E894 (base 16) TP-LINK TECHNOLOGIES CO.,LTD.
+ Building 24(floors 1,3,4,5)and 28(floors 1-4)Central Science and Technology Park,Shennan Road,Nanshan
+ Shenzhen Guangdong 518057
+ CN
+
+00-14-8C (hex) General Dynamics Mission Systems
+00148C (base 16) General Dynamics Mission Systems
+ 150 Rustcraft Road
+ Dedham MA 02026
+ US
+
+E0-19-D8 (hex) BH TECHNOLOGIES
+E019D8 (base 16) BH TECHNOLOGIES
+ 12 RUE AMPERE
+ GRENOBLE 38000
+ FR
+
+94-E1-AC (hex) Hangzhou Hikvision Digital Technology Co.,Ltd.
+94E1AC (base 16) Hangzhou Hikvision Digital Technology Co.,Ltd.
+ No.555 Qianmo Road
+ Hangzhou Zhejiang 310052
+ CN
+
+24-F1-28 (hex) Telstra
+24F128 (base 16) Telstra
+ 231 Elisabeth St
+ SYDNEY NSW 2000
+ AU
+
+FC-9B-C6 (hex) Sumavision Technologies Co.,Ltd
+FC9BC6 (base 16) Sumavision Technologies Co.,Ltd
+ 6F, Block A2, Power Creative Building,No.1 Shangdi East Road, Haidian District
+ Beijing 100085
+ CN
+
+00-1D-FA (hex) Fujian LANDI Commercial Equipment Co.,Ltd
+001DFA (base 16) Fujian LANDI Commercial Equipment Co.,Ltd
+ Building 17,the 1st Section ,Fuzhou Software Park
+ No.89 Software Road Fuzhou ,Fujian 350003
+ CN
+
+48-0B-B2 (hex) IEEE Registration Authority
+480BB2 (base 16) IEEE Registration Authority
+ 445 Hoes Lane
+ Piscataway NJ 08554
+ US
+
+BC-26-43 (hex) Elprotronic Inc.
+BC2643 (base 16) Elprotronic Inc.
+ 35 Austin Rumble Crt.
+ King City ON L7B0B2
+ CA
+
+98-14-D2 (hex) Avonic
+9814D2 (base 16) Avonic
+ Distributieweg 60
+ Delfgauw 2645EJ
+ NL
+
+B0-A3-7E (hex) QING DAO HAIER TELECOM CO.,LTD.
+B0A37E (base 16) QING DAO HAIER TELECOM CO.,LTD.
+ No.1,Haier Road,Qingdao 266101 P.R.China
+ Qingdao Shandong 266101
+ CN
+
+68-2C-7B (hex) Cisco Systems, Inc
+682C7B (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+68-CA-E4 (hex) Cisco Systems, Inc
+68CAE4 (base 16) Cisco Systems, Inc
+ 80 West Tasman Drive
+ San Jose CA 94568
+ US
+
+CC-93-4A (hex) Sierra Wireless
+CC934A (base 16) Sierra Wireless
+ 1381 Wireless Way
+ Richmond BC CA V6V 3A4
+ GB
+
+EC-93-65 (hex) Mapper.ai, Inc.
+EC9365 (base 16) Mapper.ai, Inc.
+ 400 Treat Ave, Suite G
+ San Francisco CA 94110
+ US
+
+A8-F5-AC (hex) HUAWEI TECHNOLOGIES CO.,LTD
+A8F5AC (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+50-5D-AC (hex) HUAWEI TECHNOLOGIES CO.,LTD
+505DAC (base 16) HUAWEI TECHNOLOGIES CO.,LTD
+ No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
+ Dongguan 523808
+ CN
+
+28-16-A8 (hex) Microsoft Corporation
+2816A8 (base 16) Microsoft Corporation
+ One Microsoft Way
+ REDMOND WA 98052
+ US
+
+84-A1-34 (hex) Apple, Inc.
+84A134 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-91-48 (hex) Apple, Inc.
+1C9148 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-CC-F8 (hex) Apple, Inc.
+C0CCF8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-ED-2C (hex) Apple, Inc.
+80ED2C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E8-B2-AC (hex) Apple, Inc.
+E8B2AC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-89-AD (hex) Apple, Inc.
+8489AD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-76-8F (hex) Apple, Inc.
+20768F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-ED-6A (hex) Apple, Inc.
+28ED6A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-AB-37 (hex) Apple, Inc.
+34AB37 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-A3-7D (hex) Apple, Inc.
+60A37D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-56-CD (hex) Apple, Inc.
+0056CD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-A9-20 (hex) Apple, Inc.
+BCA920 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+50-82-D5 (hex) Apple, Inc.
+5082D5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-84-BF (hex) Apple, Inc.
+9C84BF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-B3-62 (hex) Apple, Inc.
+00B362 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F8-62-14 (hex) Apple, Inc.
+F86214 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-70-2D (hex) Apple, Inc.
+B0702D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-C5-F3 (hex) Apple, Inc.
+D0C5F3 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-23-DF (hex) Apple, Inc.
+0023DF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-25-BC (hex) Apple, Inc.
+0025BC (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-26-4A (hex) Apple, Inc.
+00264A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-26-B0 (hex) Apple, Inc.
+0026B0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-1E-64 (hex) Apple, Inc.
+041E64 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D4-9A-20 (hex) Apple, Inc.
+D49A20 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-27-E4 (hex) Apple, Inc.
+9027E4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-33-4B (hex) Apple, Inc.
+60334B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-59-48 (hex) Apple, Inc.
+5C5948 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+60-F4-45 (hex) Apple, Inc.
+60F445 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+5C-F7-E6 (hex) Apple, Inc.
+5CF7E6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-D7-95 (hex) Apple, Inc.
+A0D795 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+CC-08-8D (hex) Apple, Inc.
+CC088D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-8E-F2 (hex) Apple, Inc.
+8C8EF2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F4-0F-24 (hex) Apple, Inc.
+F40F24 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-F6-77 (hex) Apple, Inc.
+24F677 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-67-D7 (hex) Apple, Inc.
+7867D7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-33-CB (hex) Apple, Inc.
+5433CB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-D2-B0 (hex) Apple, Inc.
+D0D2B0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-8F-76 (hex) Apple, Inc.
+D88F76 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+3C-2E-F9 (hex) Apple, Inc.
+3C2EF9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-81-EB (hex) Apple, Inc.
+7081EB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+08-66-98 (hex) Apple, Inc.
+086698 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-60-F1 (hex) Apple, Inc.
+9060F1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-1B-B2 (hex) Apple, Inc.
+741BB2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-CF-E9 (hex) Apple, Inc.
+28CFE9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-25-E7 (hex) Apple, Inc.
+E425E7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-19-C6 (hex) Apple, Inc.
+B019C6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+58-E2-8F (hex) Apple, Inc.
+58E28F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-1F-74 (hex) Apple, Inc.
+AC1F74 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+48-BF-6B (hex) Apple, Inc.
+48BF6B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-5B-A7 (hex) Apple, Inc.
+245BA7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-56-E7 (hex) Apple, Inc.
+DC56E7 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-7C-25 (hex) Apple, Inc.
+347C25 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D4-90-9C (hex) Apple, Inc.
+D4909C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+08-00-07 (hex) Apple, Inc.
+080007 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-0A-95 (hex) Apple, Inc.
+000A95 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-22-41 (hex) Apple, Inc.
+002241 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-EE-69 (hex) Apple, Inc.
+18EE69 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-81-14 (hex) Apple, Inc.
+748114 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-F6-43 (hex) Apple, Inc.
+18F643 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-A6-37 (hex) Apple, Inc.
+D0A637 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-18-28 (hex) Apple, Inc.
+A01828 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-03-4B (hex) Apple, Inc.
+D0034B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-31-35 (hex) Apple, Inc.
+A43135 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-35-EB (hex) Apple, Inc.
+9C35EB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+50-7A-55 (hex) Apple, Inc.
+507A55 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-99-9B (hex) Apple, Inc.
+A0999B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+24-24-0E (hex) Apple, Inc.
+24240E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+90-3C-92 (hex) Apple, Inc.
+903C92 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-8E-24 (hex) Apple, Inc.
+A88E24 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E8-80-2E (hex) Apple, Inc.
+E8802E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-AE-20 (hex) Apple, Inc.
+68AE20 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-B5-2D (hex) Apple, Inc.
+E0B52D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-BE-05 (hex) Apple, Inc.
+80BE05 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-BB-2C (hex) Apple, Inc.
+D8BB2C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D0-4F-7E (hex) Apple, Inc.
+D04F7E (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+2C-1F-23 (hex) Apple, Inc.
+2C1F23 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-9F-13 (hex) Apple, Inc.
+549F13 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-09-8A (hex) Apple, Inc.
+B8098A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-DB-E2 (hex) Apple, Inc.
+F0DBE2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-29-37 (hex) Apple, Inc.
+8C2937 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-9B-9C (hex) Apple, Inc.
+DC9B9C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+98-F0-AB (hex) Apple, Inc.
+98F0AB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-DB-F8 (hex) Apple, Inc.
+F0DBF8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+AC-CF-5C (hex) Apple, Inc.
+ACCF5C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+3C-15-C2 (hex) Apple, Inc.
+3C15C2 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-48-9A (hex) Apple, Inc.
+04489A (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+D8-CF-9C (hex) Apple, Inc.
+D8CF9C (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A8-86-DD (hex) Apple, Inc.
+A886DD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+54-EA-A8 (hex) Apple, Inc.
+54EAA8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E4-C6-3D (hex) Apple, Inc.
+E4C63D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-38-35 (hex) Apple, Inc.
+843835 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C0-63-94 (hex) Apple, Inc.
+C06394 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+8C-00-6D (hex) Apple, Inc.
+8C006D (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B0-9F-BA (hex) Apple, Inc.
+B09FBA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-86-D8 (hex) Apple, Inc.
+DC86D8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+78-CA-39 (hex) Apple, Inc.
+78CA39 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+18-E7-F4 (hex) Apple, Inc.
+18E7F4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-FF-61 (hex) Apple, Inc.
+B8FF61 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+DC-2B-61 (hex) Apple, Inc.
+DC2B61 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+10-93-E9 (hex) Apple, Inc.
+1093E9 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+44-2A-60 (hex) Apple, Inc.
+442A60 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+E0-F8-47 (hex) Apple, Inc.
+E0F847 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+14-5A-05 (hex) Apple, Inc.
+145A05 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-CF-DA (hex) Apple, Inc.
+28CFDA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+14-8F-C6 (hex) Apple, Inc.
+148FC6 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+28-37-37 (hex) Apple, Inc.
+283737 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-54-53 (hex) Apple, Inc.
+045453 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F0-CB-A1 (hex) Apple, Inc.
+F0CBA1 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+30-F7-C5 (hex) Apple, Inc.
+30F7C5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+00-88-65 (hex) Apple, Inc.
+008865 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+40-B3-95 (hex) Apple, Inc.
+40B395 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+30-90-AB (hex) Apple, Inc.
+3090AB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+1C-E6-2B (hex) Apple, Inc.
+1CE62B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A0-ED-CD (hex) Apple, Inc.
+A0EDCD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-29-99 (hex) Apple, Inc.
+842999 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-E2-F5 (hex) Apple, Inc.
+74E2F5 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+20-C9-D0 (hex) Apple, Inc.
+20C9D0 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-73-CB (hex) Apple, Inc.
+7073CB (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-20-7B (hex) Apple, Inc.
+9C207B (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+34-12-98 (hex) Apple, Inc.
+341298 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+9C-29-3F (hex) Apple, Inc.
+9C293F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+7C-01-91 (hex) Apple, Inc.
+7C0191 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+70-48-0F (hex) Apple, Inc.
+70480F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+A4-B8-05 (hex) Apple, Inc.
+A4B805 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+58-7F-57 (hex) Apple, Inc.
+587F57 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+80-D6-05 (hex) Apple, Inc.
+80D605 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+C8-69-CD (hex) Apple, Inc.
+C869CD (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+BC-6C-21 (hex) Apple, Inc.
+BC6C21 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+04-69-F8 (hex) Apple, Inc.
+0469F8 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+74-9E-AF (hex) Apple, Inc.
+749EAF (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+B8-41-A4 (hex) Apple, Inc.
+B841A4 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+F8-95-EA (hex) Apple, Inc.
+F895EA (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+50-A6-7F (hex) Apple, Inc.
+50A67F (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+64-70-33 (hex) Apple, Inc.
+647033 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+84-68-78 (hex) Apple, Inc.
+846878 (base 16) Apple, Inc.
+ 1 Infinite Loop
+ Cupertino CA 95014
+ US
+
+68-D1-BA (hex) Shenzhen YOUHUA Technology Co., Ltd
+68D1BA (base 16) Shenzhen YOUHUA Technology Co., Ltd
+ Room 407 Shenzhen University-town Business Park,Lishan Road,Taoyuan Street,Nanshan District
+ Shenzhen Guangdong 518055
+ CN
+
+BC-CA-B5 (hex) ARRIS Group, Inc.
+BCCAB5 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+5C-8F-E0 (hex) ARRIS Group, Inc.
+5C8FE0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+6C-CA-08 (hex) ARRIS Group, Inc.
+6CCA08 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+54-65-DE (hex) ARRIS Group, Inc.
+5465DE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+AC-EC-80 (hex) ARRIS Group, Inc.
+ACEC80 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+3C-7A-8A (hex) ARRIS Group, Inc.
+3C7A8A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-0F-CC (hex) ARRIS Group, Inc.
+000FCC (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+2C-A1-7D (hex) ARRIS Group, Inc.
+2CA17D (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+7C-BF-B1 (hex) ARRIS Group, Inc.
+7CBFB1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+80-96-B1 (hex) ARRIS Group, Inc.
+8096B1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-90-9C (hex) ARRIS Group, Inc.
+00909C (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-11-80 (hex) ARRIS Group, Inc.
+001180 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-17-EE (hex) ARRIS Group, Inc.
+0017EE (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-D0-88 (hex) ARRIS Group, Inc.
+00D088 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-12-C9 (hex) ARRIS Group, Inc.
+0012C9 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1C-FB (hex) ARRIS Group, Inc.
+001CFB (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1C-12 (hex) ARRIS Group, Inc.
+001C12 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1F-C4 (hex) ARRIS Group, Inc.
+001FC4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-22-10 (hex) ARRIS Group, Inc.
+002210 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-21-1E (hex) ARRIS Group, Inc.
+00211E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+F8-ED-A5 (hex) ARRIS Group, Inc.
+F8EDA5 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+40-70-09 (hex) ARRIS Group, Inc.
+407009 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+94-87-7C (hex) ARRIS Group, Inc.
+94877C (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1D-D2 (hex) ARRIS Group, Inc.
+001DD2 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-17-E2 (hex) ARRIS Group, Inc.
+0017E2 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+CC-7D-37 (hex) ARRIS Group, Inc.
+CC7D37 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-1A-77 (hex) ARRIS Group, Inc.
+001A77 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+98-4B-4A (hex) ARRIS Group, Inc.
+984B4A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+9C-34-26 (hex) ARRIS Group, Inc.
+9C3426 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-15-A4 (hex) ARRIS Group, Inc.
+0015A4 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-15-A3 (hex) ARRIS Group, Inc.
+0015A3 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+C0-C5-22 (hex) ARRIS Group, Inc.
+C0C522 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+5C-B0-66 (hex) ARRIS Group, Inc.
+5CB066 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+E4-83-99 (hex) ARRIS Group, Inc.
+E48399 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-26-36 (hex) ARRIS Group, Inc.
+002636 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-24-A0 (hex) ARRIS Group, Inc.
+0024A0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-16-75 (hex) ARRIS Group, Inc.
+001675 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
+00-16-B5 (hex) ARRIS Group, Inc.
+0016B5 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
+ US
+
00-1D-72 (hex) Wistron Corporation
001D72 (base 16) Wistron Corporation
21F, 88, Sec.1, Hsin Tai Wu Rd., Hsichih,
@@ -142241,270 +145325,12 @@ AC2205 (base 16) Compal Broadband Networks, Inc. Shanghai 200333
CN
-00-12-C9 (hex) ARRIS Group, Inc.
-0012C9 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-98-4B-4A (hex) ARRIS Group, Inc.
-984B4A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1A-77 (hex) ARRIS Group, Inc.
-001A77 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-CC-7D-37 (hex) ARRIS Group, Inc.
-CC7D37 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-17-E2 (hex) ARRIS Group, Inc.
-0017E2 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-17-84 (hex) ARRIS Group, Inc.
-001784 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-16-B5 (hex) ARRIS Group, Inc.
-0016B5 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-16-75 (hex) ARRIS Group, Inc.
-001675 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-D0-88 (hex) ARRIS Group, Inc.
-00D088 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-17-EE (hex) ARRIS Group, Inc.
-0017EE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-11-80 (hex) ARRIS Group, Inc.
-001180 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-90-9C (hex) ARRIS Group, Inc.
-00909C (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-80-96-B1 (hex) ARRIS Group, Inc.
-8096B1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-7C-BF-B1 (hex) ARRIS Group, Inc.
-7CBFB1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-A3 (hex) ARRIS Group, Inc.
-0015A3 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-15-A4 (hex) ARRIS Group, Inc.
-0015A4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-9C-34-26 (hex) ARRIS Group, Inc.
-9C3426 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1D-D2 (hex) ARRIS Group, Inc.
-001DD2 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-21-1E (hex) ARRIS Group, Inc.
-00211E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-22-10 (hex) ARRIS Group, Inc.
-002210 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1F-C4 (hex) ARRIS Group, Inc.
-001FC4 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1C-12 (hex) ARRIS Group, Inc.
-001C12 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-1C-FB (hex) ARRIS Group, Inc.
-001CFB (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-D4-2C-0F (hex) ARRIS Group, Inc.
-D42C0F (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-84-96-D8 (hex) ARRIS Group, Inc.
-8496D8 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-80-F5-03 (hex) ARRIS Group, Inc.
-80F503 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-5C-B0-66 (hex) ARRIS Group, Inc.
-5CB066 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-C0-C5-22 (hex) ARRIS Group, Inc.
-C0C522 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-24-A0 (hex) ARRIS Group, Inc.
-0024A0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-26-36 (hex) ARRIS Group, Inc.
-002636 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E4-83-99 (hex) ARRIS Group, Inc.
-E48399 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-E0-B7-B1 (hex) ARRIS Group, Inc.
-E0B7B1 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-94-87-7C (hex) ARRIS Group, Inc.
-94877C (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-40-70-09 (hex) ARRIS Group, Inc.
-407009 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-F8-ED-A5 (hex) ARRIS Group, Inc.
-F8EDA5 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-54-65-DE (hex) ARRIS Group, Inc.
-5465DE (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-6C-CA-08 (hex) ARRIS Group, Inc.
-6CCA08 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-5C-8F-E0 (hex) ARRIS Group, Inc.
-5C8FE0 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
8C-39-5C (hex) Bit4id Srl
8C395C (base 16) Bit4id Srl
Via Diocleziano, 107
Naples 80125
IT
-BC-CA-B5 (hex) ARRIS Group, Inc.
-BCCAB5 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-00-0F-CC (hex) ARRIS Group, Inc.
-000FCC (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-3C-7A-8A (hex) ARRIS Group, Inc.
-3C7A8A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-AC-EC-80 (hex) ARRIS Group, Inc.
-ACEC80 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-2C-A1-7D (hex) ARRIS Group, Inc.
-2CA17D (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
04-71-4B (hex) IEEE Registration Authority
04714B (base 16) IEEE Registration Authority
445 Hoes Lane
@@ -142529,12 +145355,6 @@ ACEC80 (base 16) ARRIS Group, Inc. Menlo Park CA 94025
US
-98-F7-D7 (hex) ARRIS Group, Inc.
-98F7D7 (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
2C-41-A1 (hex) Bose Corporation
2C41A1 (base 16) Bose Corporation
The Mountain
@@ -142922,12 +145742,6 @@ F4B520 (base 16) Biostar Microtech international corp. 9C-93-E4 (hex) Private
9C93E4 (base 16) Private
-D4-B2-7A (hex) ARRIS Group, Inc.
-D4B27A (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
F0-F8-F2 (hex) Texas Instruments
F0F8F2 (base 16) Texas Instruments
12500 TI Blvd
@@ -142970,12 +145784,6 @@ F0F8F2 (base 16) Texas Instruments Beijing Beijing 100085
CN
-90-9D-7D (hex) ARRIS Group, Inc.
-909D7D (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
84-A1-D1 (hex) Sagemcom Broadband SAS
84A1D1 (base 16) Sagemcom Broadband SAS
250, route de l'Empereur
@@ -143426,18 +146234,6 @@ A07099 (base 16) Beijing Huacan Electronics Co., Ltd Beijing 100036
CN
-B0-93-5B (hex) ARRIS Group, Inc.
-B0935B (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
-20-F1-9E (hex) ARRIS Group, Inc.
-20F19E (base 16) ARRIS Group, Inc.
- 6450 Sequence Drive
- San Diego CA 92121
- US
-
38-9D-92 (hex) Seiko Epson Corporation
389D92 (base 16) Seiko Epson Corporation
2070 Kotobuki Koaka
@@ -143516,1730 +146312,116 @@ BC903A (base 16) Robert Bosch GmbH Bangalore Karnataka 560082
IN
-B4-A3-82 (hex) Hangzhou Hikvision Digital Technology Co.,Ltd.
-B4A382 (base 16) Hangzhou Hikvision Digital Technology Co.,Ltd.
- No.555 Qianmo Road
- Hangzhou Zhejiang 310052
- CN
-
-3C-A6-16 (hex) vivo Mobile Communication Co., Ltd.
-3CA616 (base 16) vivo Mobile Communication Co., Ltd.
- #283,BBK Road
- Wusha,Chang'An DongGuan City,Guangdong, 523860
- CN
-
-88-B4-A6 (hex) Motorola Mobility LLC, a Lenovo Company
-88B4A6 (base 16) Motorola Mobility LLC, a Lenovo Company
- 222 West Merchandise Mart Plaza
- Chicago IL 60654
- US
-
-74-28-57 (hex) Mayfield Robotics
-742857 (base 16) Mayfield Robotics
- 400 Convention Way
- Redwood City CA 94063
- US
-
-00-CB-00 (hex) Private
-00CB00 (base 16) Private
-
-60-9B-C8 (hex) Hipad Intelligent Technology Co., Ltd.
-609BC8 (base 16) Hipad Intelligent Technology Co., Ltd.
- No. 688, East of Huangtang Street, LinkongEconomy District
- Nanchang Jiangxi 330000
- CN
-
-1C-0F-AF (hex) Lucid Vision Labs
-1C0FAF (base 16) Lucid Vision Labs
- Unit 130 - 13200 Delf Place
- Richmond BC V6V2A2
- CA
-
-24-5C-CB (hex) AXIe Consortium, Inc.
-245CCB (base 16) AXIe Consortium, Inc.
- P.O. Box 1016
- Niwot CO 80544-1016
- US
-
-F8-F2-1E (hex) Intel Corporate
-F8F21E (base 16) Intel Corporate
- Lot 8, Jalan Hi-Tech 2/3
- Kulim Kedah 09000
- MY
-
-28-29-86 (hex) APC by Schneider Electric
-282986 (base 16) APC by Schneider Electric
- 800 Federal St.
- Andover MA 01810
- US
-
-74-DA-38 (hex) Edimax Technology Co. Ltd.
-74DA38 (base 16) Edimax Technology Co. Ltd.
- No. 278, Xinhu 1st Road
- Taipei City Neihu Dist 248
- TW
-
-38-6B-1C (hex) SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
-386B1C (base 16) SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
- 3/F, Building R1-B, High-Tech Industrial Park, Nanshan District
- Shenzhen Guangdong 518057
- CN
-
-38-01-9F (hex) SHENZHEN FAST TECHNOLOGIES CO.,LTD
-38019F (base 16) SHENZHEN FAST TECHNOLOGIES CO.,LTD
- Room 202,Building No.5,Section 30,No.2 of Kefa Road,Nanshan District,Shenzhen,P.R.China
- Shenzhen Guangdong 518057
- CN
-
-00-24-24 (hex) Ace Axis Limited
-002424 (base 16) Ace Axis Limited
- 602 Delta Business Park, Welton Road
- Swindon SN5 7XP
- GB
-
-8C-83-9D (hex) SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD
-8C839D (base 16) SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD
- ROOM 1505,BIT INNOVATION BUILDING,SCIENCE AND TECHNOLOGY PARK,NANSHAN DISTRICT
- Shenzhen 518057
- CN
-
-EC-FA-F4 (hex) SenRa Tech Pvt. Ltd
-ECFAF4 (base 16) SenRa Tech Pvt. Ltd
- 133, First Floor, Lane No. 1, Westend Marg, Saidulajab
- New Delhi 110030
- IN
-
-70-99-1C (hex) Shenzhen Honesty Electronics Co.,Ltd
-70991C (base 16) Shenzhen Honesty Electronics Co.,Ltd
- 5/F,Zone B,Chitat Industrial Park,West Longping Road
- Shenzhen City Longgang District, Guangdong 518172
- CN
-
-00-81-F9 (hex) Texas Instruments
-0081F9 (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
- US
-
-58-7A-62 (hex) Texas Instruments
-587A62 (base 16) Texas Instruments
- 12500 TI Blvd
- Dallas TX 75243
- US
-
-D0-67-26 (hex) Hewlett Packard Enterprise
-D06726 (base 16) Hewlett Packard Enterprise
- 8000 Foothills Blvd.
- Roseville CA 95747
- US
-
-28-23-73 (hex) Digita
-282373 (base 16) Digita
- Jämsänkatu 2
- Helsinki Uusimaa 00520
- FI
-
-44-CD-0E (hex) FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.
-44CD0E (base 16) FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.
- Xin Qing Science & Technology Industrial Park,Jin An Town,Doumen ,Zhuhai,Guangdong,PRC
- Zhuhai Guangdong 519180
- CN
-
-08-84-66 (hex) Novartis Pharma AG
-088466 (base 16) Novartis Pharma AG
- Lichtstrasse 35
- Basel 4056
- CH
-
-8C-5B-F0 (hex) ARRIS Group, Inc.
-8C5BF0 (base 16) ARRIS Group, Inc.
+80-F5-03 (hex) ARRIS Group, Inc.
+80F503 (base 16) ARRIS Group, Inc.
6450 Sequence Drive
San Diego CA 92121
US
-00-1F-7D (hex) Embedded Wireless GmbH
-001F7D (base 16) Embedded Wireless GmbH
- Soeflinger Strasse 200
- Ulm BW 89077
- DE
-
-94-7B-BE (hex) Ubicquia
-947BBE (base 16) Ubicquia
- 3281 Fairlane Farms Rd
- Wellington FL 33449
- US
-
-E8-2A-44 (hex) Liteon Technology Corporation
-E82A44 (base 16) Liteon Technology Corporation
- 4F, 90, Chien 1 Road
- New Taipei City Taiwan 23585
- TW
-
-00-05-A7 (hex) HYPERCHIP Inc.
-0005A7 (base 16) HYPERCHIP Inc.
- 180 Peel Street - Ste. #333
- H3C 2G7
- CA
-
-78-DD-D9 (hex) Guangzhou Shiyuan Electronics Co., Ltd.
-78DDD9 (base 16) Guangzhou Shiyuan Electronics Co., Ltd.
- No.6, 4th Yunpu Road, Yunpu Industry District
- Guangzhou Guangdong 510530
- CN
-
-00-09-66 (hex) TRIMBLE EUROPE BV
-000966 (base 16) TRIMBLE EUROPE BV
- Meerheide 45
- Eersel DZ 5521
- NL
-
-EC-B0-E1 (hex) Ciena Corporation
-ECB0E1 (base 16) Ciena Corporation
- 7035 Ridge Road
- Hanover MD 21076
- US
-
-58-C1-7A (hex) Cambium Networks Limited
-58C17A (base 16) Cambium Networks Limited
- Unit B2, Linhay Business Park,
- Ashburton Devon TQ13 7UP
- GB
-
-2C-54-91 (hex) Microsoft Corporation
-2C5491 (base 16) Microsoft Corporation
- One Microsoft Way
- REDMOND WA 98052
- US
-
-04-50-DA (hex) Qiku Internet Network Scientific (Shenzhen) Co., Ltd
-0450DA (base 16) Qiku Internet Network Scientific (Shenzhen) Co., Ltd
- Building A2, Chi Yuen Technology Park 1001 College Avenue, Nanshan District Shenzhen, Guangdong
- Shenzhen Guangdong 518000
- CN
-
-08-BC-20 (hex) Hangzhou Royal Cloud Technology Co., Ltd
-08BC20 (base 16) Hangzhou Royal Cloud Technology Co., Ltd
- Hangzhou Xixi Road 957, 24, Unit 2, 302
- Hangzhou 310030
- CN
-
-5C-70-A3 (hex) LG Electronics (Mobile Communications)
-5C70A3 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-10-F9-6F (hex) LG Electronics (Mobile Communications)
-10F96F (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-F0-1C-13 (hex) LG Electronics (Mobile Communications)
-F01C13 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-00-AA-70 (hex) LG Electronics (Mobile Communications)
-00AA70 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-BC-F5-AC (hex) LG Electronics (Mobile Communications)
-BCF5AC (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-CC-FA-00 (hex) LG Electronics (Mobile Communications)
-CCFA00 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-F8-A9-D0 (hex) LG Electronics (Mobile Communications)
-F8A9D0 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-80-5A-04 (hex) LG Electronics (Mobile Communications)
-805A04 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-5C-AF-06 (hex) LG Electronics (Mobile Communications)
-5CAF06 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-B8-1D-AA (hex) LG Electronics (Mobile Communications)
-B81DAA (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-10-F1-F2 (hex) LG Electronics (Mobile Communications)
-10F1F2 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-00-25-E5 (hex) LG Electronics (Mobile Communications)
-0025E5 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-00-22-A9 (hex) LG Electronics (Mobile Communications)
-0022A9 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-C4-9A-02 (hex) LG Electronics (Mobile Communications)
-C49A02 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-34-4D-F7 (hex) LG Electronics (Mobile Communications)
-344DF7 (base 16) LG Electronics (Mobile Communications)
- 60-39, Gasan-dong, Geumcheon-gu
- Seoul 153-801
- KR
-
-44-91-60 (hex) Murata Manufacturing Co., Ltd.
-449160 (base 16) Murata Manufacturing Co., Ltd.
- 1-10-1, Higashikotari
- Nagaokakyo-shi Kyoto 617-8555
- JP
-
-44-D5-A5 (hex) AddOn Computer
-44D5A5 (base 16) AddOn Computer
- 15775 Gateway cir
- tustin CA 92780
- US
-
-00-AE-CD (hex) Pensando Systems
-00AECD (base 16) Pensando Systems
- 1730 Technology Drive, Suite 202
- San Jose CA 95110
+84-96-D8 (hex) ARRIS Group, Inc.
+8496D8 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-44-AD-19 (hex) XINGFEI (H.K)LIMITED
-44AD19 (base 16) XINGFEI (H.K)LIMITED
- 6/F North Tower Wandelai Building No.29 Kejinan 6th Road, Nanshan District,Shenzhen,China
- Shenzhen 518057
- CN
-
-D8-96-E0 (hex) Alibaba Cloud Computing Ltd.
-D896E0 (base 16) Alibaba Cloud Computing Ltd.
- Yuhang District of Hangzhou Wenyi Road, Building 1, No. 969 Xixi Park, Zhejiang Province
- Hangzhou Zhejiang 310000
- CN
-
-30-EB-1F (hex) Skylab M&C Technology Co.,Ltd
-30EB1F (base 16) Skylab M&C Technology Co.,Ltd
- 6 Floor,No.9 Building,Lijincheng Scientific&Technical park,Gongye East Road,Longhua District
- Shenzhen Guangdong 518109
- CN
-
-B0-B2-DC (hex) Zyxel Communications Corporation
-B0B2DC (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-00-23-F8 (hex) Zyxel Communications Corporation
-0023F8 (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-4C-9E-FF (hex) Zyxel Communications Corporation
-4C9EFF (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-5C-F4-AB (hex) Zyxel Communications Corporation
-5CF4AB (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-14-79-F3 (hex) China Mobile Group Device Co.,Ltd.
-1479F3 (base 16) China Mobile Group Device Co.,Ltd.
- 32 Xuanwumen West Street,Xicheng District
- Beijing 100053
- CN
-
-90-EF-68 (hex) Zyxel Communications Corporation
-90EF68 (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-28-28-5D (hex) Zyxel Communications Corporation
-28285D (base 16) Zyxel Communications Corporation
- No. 6 Innovation Road II, Science Park
- Hsichu Taiwan 300
- TW
-
-4C-AE-1C (hex) SaiNXT Technologies LLP
-4CAE1C (base 16) SaiNXT Technologies LLP
- Shop No. 7, Sonawala Building, 1st Floor, Proctor Road, Grant Road (E)
- Mumbai Maharashtra 400007
- IN
-
-4C-91-0C (hex) Lanix Internacional, S.A. de C.V.
-4C910C (base 16) Lanix Internacional, S.A. de C.V.
- Carretera Nogales Km8.5
- Hermosillo Sonora 83160
- MX
-
-2C-42-05 (hex) Lytx
-2C4205 (base 16) Lytx
- 9785 Towne Centre Drive
+D4-2C-0F (hex) ARRIS Group, Inc.
+D42C0F (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
San Diego CA 92121
US
-00-90-F1 (hex) Seagate Cloud Systems Inc
-0090F1 (base 16) Seagate Cloud Systems Inc
- 6305 El Camino Real
- Carlsbad CA 92009
+E0-B7-B1 (hex) ARRIS Group, Inc.
+E0B7B1 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-D4-5D-DF (hex) PEGATRON CORPORATION
-D45DDF (base 16) PEGATRON CORPORATION
- 5F No. 76, Ligong St., Beitou District
- Taipei City Taiwan 112
- TW
-
-D4-1A-3F (hex) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-D41A3F (base 16) GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
- NO.18 HAIBIN ROAD,
- DONG GUAN GUANG DONG 523860
- CN
-
-00-50-13 (hex) Seagate Cloud Systems Inc
-005013 (base 16) Seagate Cloud Systems Inc
- 7420 E. Dry Creek Parkway
- Longmont CO 80503
+98-F7-D7 (hex) ARRIS Group, Inc.
+98F7D7 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-00-C0-FF (hex) Seagate Cloud Systems Inc
-00C0FF (base 16) Seagate Cloud Systems Inc
- 6305 El Camino Real
- Carlsbad CA 92009
+D4-B2-7A (hex) ARRIS Group, Inc.
+D4B27A (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-EC-81-93 (hex) Logitech, Inc
-EC8193 (base 16) Logitech, Inc
- 4700 NW Camas Meadows Drive
- Camas WA 98607
+90-9D-7D (hex) ARRIS Group, Inc.
+909D7D (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-D0-96-FB (hex) DASAN Network Solutions
-D096FB (base 16) DASAN Network Solutions
- DASAN Tower 8F, 49 Daewangpangyo-ro644beon-gil Bundang-gu
- Seongnam-si Gyeonggi-do 13493
- KR
-
-5C-52-1E (hex) Nintendo Co.,Ltd
-5C521E (base 16) Nintendo Co.,Ltd
- 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
- KYOTO KYOTO 601-8501
- JP
-
-A8-25-EB (hex) Cambridge Industries(Group) Co.,Ltd.
-A825EB (base 16) Cambridge Industries(Group) Co.,Ltd.
- 5/F,Building 8, 2388 ChenHang Road, MinHang District
- shanghai 201114
- CN
-
-D8-C8-E9 (hex) Phicomm (Shanghai) Co., Ltd.
-D8C8E9 (base 16) Phicomm (Shanghai) Co., Ltd.
- 3666 SiXian Rd.,Songjiang District
- Shanghai Shanghai 201616
- CN
-
-64-F8-8A (hex) China Mobile IOT Company Limited
-64F88A (base 16) China Mobile IOT Company Limited
- NO.8 Yu Ma Road, NanAn Area Chongqing,China
- Chongqing Chongqing 401336
- CN
-
-6C-49-C1 (hex) o2ones Co., Ltd.
-6C49C1 (base 16) o2ones Co., Ltd.
- 503 Glory Tower, 3-10, Gumi-ro 9beon-gil, Bundang-gu
- Seongnam-si Gyeonggi-do 13637
- KR
-
-68-DB-54 (hex) Phicomm (Shanghai) Co., Ltd.
-68DB54 (base 16) Phicomm (Shanghai) Co., Ltd.
- 3666 SiXian Rd.,Songjiang District
- Shanghai Shanghai 201616
- CN
-
-E4-8F-34 (hex) Vodafone Italia S.p.A.
-E48F34 (base 16) Vodafone Italia S.p.A.
- Via Lorenteggio nr. 240
- Milan Italy 20147
- IT
-
-2C-6B-7D (hex) Texas Instruments
-2C6B7D (base 16) Texas Instruments
+88-3F-4A (hex) Texas Instruments
+883F4A (base 16) Texas Instruments
12500 TI Blvd
Dallas TX 75243
US
-78-80-38 (hex) FUNAI ELECTRIC CO., LTD.
-788038 (base 16) FUNAI ELECTRIC CO., LTD.
- 7-1, NAKAGAITO 7-CHOME
- DAITO OSAKA 5740013
- JP
-
-00-01-30 (hex) Extreme Networks, Inc.
-000130 (base 16) Extreme Networks, Inc.
- 3585 Monroe Street
- Santa Clara CA 95051
- US
-
-CC-6E-A4 (hex) Samsung Electronics Co.,Ltd
-CC6EA4 (base 16) Samsung Electronics Co.,Ltd
- 129, Samsung-ro, Youngtongl-Gu
- Suwon Gyeonggi-Do 16677
- KR
-
-C4-77-AF (hex) Advanced Digital Broadcast SA
-C477AF (base 16) Advanced Digital Broadcast SA
- Route de Crassier 21, B2
- Eysins CH-1262
- CH
-
-20-DF-B9 (hex) Google, Inc.
-20DFB9 (base 16) Google, Inc.
- 1600 Amphitheatre Parkway
- Mountain View CA 94043
- US
-
-44-F0-34 (hex) Kaonmedia CO., LTD.
-44F034 (base 16) Kaonmedia CO., LTD.
- 884-3, Seongnam-daero, Bundang-gu
- Seongnam-si Gyeonggi-do 13517
- KR
-
-14-78-0B (hex) Varex Imaging Deutschland AG
-14780B (base 16) Varex Imaging Deutschland AG
- Zweigniederlassung/Branch Walluf
- In der Rehbach 22 Walluf 65396
- DE
-
-10-CD-6E (hex) FISYS
-10CD6E (base 16) FISYS
- 303 Expotel, 44, Dunsan-daero 117beon-gil, Seo-gu, Daejeon, Korea
- Daejeon, Korea KS015
- KR
-
-A4-6C-F1 (hex) Samsung Electronics Co.,Ltd
-A46CF1 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-0C-A8-A7 (hex) Samsung Electronics Co.,Ltd
-0CA8A7 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-54-B8-02 (hex) Samsung Electronics Co.,Ltd
-54B802 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-28-2C-02 (hex) IEEE Registration Authority
-282C02 (base 16) IEEE Registration Authority
- 445 Hoes Lane
- Piscataway NJ 08554
- US
-
-B8-C7-16 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-B8C716 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-D0-59-95 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-D05995 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-54-DF-24 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-54DF24 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-58-3B-D9 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-583BD9 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-F0-40-7B (hex) Fiberhome Telecommunication Technologies Co.,LTD
-F0407B (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-F0-8C-FB (hex) Fiberhome Telecommunication Technologies Co.,LTD
-F08CFB (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan City Hubei Province 430074
- CN
-
-EC-8A-C7 (hex) Fiberhome Telecommunication Technologies Co.,LTD
-EC8AC7 (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-BC-C0-0F (hex) Fiberhome Telecommunication Technologies Co.,LTD
-BCC00F (base 16) Fiberhome Telecommunication Technologies Co.,LTD
- No.5 DongXin Road
- Wuhan Hubei 430074
- CN
-
-00-50-79 (hex) Private
-005079 (base 16) Private
-
-5C-00-38 (hex) Viasat Group S.p.A.
-5C0038 (base 16) Viasat Group S.p.A.
- Via Aosta 23
- Venaria Reale Torino 10078
- IT
-
-04-69-F8 (hex) Apple, Inc.
-0469F8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-BC-6C-21 (hex) Apple, Inc.
-BC6C21 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C8-69-CD (hex) Apple, Inc.
-C869CD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-80-D6-05 (hex) Apple, Inc.
-80D605 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-58-7F-57 (hex) Apple, Inc.
-587F57 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A4-B8-05 (hex) Apple, Inc.
-A4B805 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-48-0F (hex) Apple, Inc.
-70480F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-7C-01-91 (hex) Apple, Inc.
-7C0191 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-29-3F (hex) Apple, Inc.
-9C293F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-34-12-98 (hex) Apple, Inc.
-341298 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-90-3C-92 (hex) Apple, Inc.
-903C92 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-24-0E (hex) Apple, Inc.
-24240E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A0-99-9B (hex) Apple, Inc.
-A0999B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-A6-37 (hex) Apple, Inc.
-D0A637 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-18-F6-43 (hex) Apple, Inc.
-18F643 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-74-81-14 (hex) Apple, Inc.
-748114 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-18-EE-69 (hex) Apple, Inc.
-18EE69 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-DB-E2 (hex) Apple, Inc.
-F0DBE2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B8-09-8A (hex) Apple, Inc.
-B8098A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-54-9F-13 (hex) Apple, Inc.
-549F13 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-2C-1F-23 (hex) Apple, Inc.
-2C1F23 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E4-CB-59 (hex) Beijing Loveair Science and Technology Co. Ltd.
-E4CB59 (base 16) Beijing Loveair Science and Technology Co. Ltd.
- 103,Block B, Kelin Building, No.107, Dongsi North Street, Dongcheng District,
- Beijing 100000
- CN
-
-C8-77-65 (hex) Tiesse SpA
-C87765 (base 16) Tiesse SpA
- Via Asti
- Ivrea TO 10015
- IT
-
-50-7A-55 (hex) Apple, Inc.
-507A55 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-35-EB (hex) Apple, Inc.
-9C35EB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A4-31-35 (hex) Apple, Inc.
-A43135 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-03-4B (hex) Apple, Inc.
-D0034B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A0-18-28 (hex) Apple, Inc.
-A01828 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-3C-15-C2 (hex) Apple, Inc.
-3C15C2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-AC-CF-5C (hex) Apple, Inc.
-ACCF5C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-DB-F8 (hex) Apple, Inc.
-F0DBF8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-98-F0-AB (hex) Apple, Inc.
-98F0AB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-9B-9C (hex) Apple, Inc.
-DC9B9C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-8C-29-37 (hex) Apple, Inc.
-8C2937 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-86-D8 (hex) Apple, Inc.
-DC86D8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E4-C6-3D (hex) Apple, Inc.
-E4C63D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-54-EA-A8 (hex) Apple, Inc.
-54EAA8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A8-86-DD (hex) Apple, Inc.
-A886DD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A0-ED-CD (hex) Apple, Inc.
-A0EDCD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-1C-E6-2B (hex) Apple, Inc.
-1CE62B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-30-90-AB (hex) Apple, Inc.
-3090AB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F0-CB-A1 (hex) Apple, Inc.
-F0CBA1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-04-54-53 (hex) Apple, Inc.
-045453 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-28-37-37 (hex) Apple, Inc.
-283737 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-14-8F-C6 (hex) Apple, Inc.
-148FC6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-28-CF-DA (hex) Apple, Inc.
-28CFDA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-14-5A-05 (hex) Apple, Inc.
-145A05 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-4F-7E (hex) Apple, Inc.
-D04F7E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D8-BB-2C (hex) Apple, Inc.
-D8BB2C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-80-BE-05 (hex) Apple, Inc.
-80BE05 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E0-B5-2D (hex) Apple, Inc.
-E0B52D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-68-AE-20 (hex) Apple, Inc.
-68AE20 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E8-80-2E (hex) Apple, Inc.
-E8802E (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A8-8E-24 (hex) Apple, Inc.
-A88E24 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D8-CF-9C (hex) Apple, Inc.
-D8CF9C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-04-48-9A (hex) Apple, Inc.
-04489A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B0-9F-BA (hex) Apple, Inc.
-B09FBA (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-8C-00-6D (hex) Apple, Inc.
-8C006D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C0-63-94 (hex) Apple, Inc.
-C06394 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-84-38-35 (hex) Apple, Inc.
-843835 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-20-C9-D0 (hex) Apple, Inc.
-20C9D0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-74-E2-F5 (hex) Apple, Inc.
-74E2F5 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-84-29-99 (hex) Apple, Inc.
-842999 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-20-7B (hex) Apple, Inc.
-9C207B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-40-B3-95 (hex) Apple, Inc.
-40B395 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-88-65 (hex) Apple, Inc.
-008865 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-30-F7-C5 (hex) Apple, Inc.
-30F7C5 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-73-CB (hex) Apple, Inc.
-7073CB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-B3-62 (hex) Apple, Inc.
-00B362 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F8-62-14 (hex) Apple, Inc.
-F86214 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B0-70-2D (hex) Apple, Inc.
-B0702D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-C5-F3 (hex) Apple, Inc.
-D0C5F3 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-F4-45 (hex) Apple, Inc.
-60F445 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-50-82-D5 (hex) Apple, Inc.
-5082D5 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-9C-84-BF (hex) Apple, Inc.
-9C84BF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-48-BF-6B (hex) Apple, Inc.
-48BF6B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-5B-A7 (hex) Apple, Inc.
-245BA7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-BC-A9-20 (hex) Apple, Inc.
-BCA920 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B0-19-C6 (hex) Apple, Inc.
-B019C6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-58-E2-8F (hex) Apple, Inc.
-58E28F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-AC-1F-74 (hex) Apple, Inc.
-AC1F74 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-20-76-8F (hex) Apple, Inc.
-20768F (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-C0-CC-F8 (hex) Apple, Inc.
-C0CCF8 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-80-ED-2C (hex) Apple, Inc.
-80ED2C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E8-B2-AC (hex) Apple, Inc.
-E8B2AC (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-84-89-AD (hex) Apple, Inc.
-8489AD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-8C-8E-F2 (hex) Apple, Inc.
-8C8EF2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-F4-0F-24 (hex) Apple, Inc.
-F40F24 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-84-A1-34 (hex) Apple, Inc.
-84A134 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-1C-91-48 (hex) Apple, Inc.
-1C9148 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-5C-F7-E6 (hex) Apple, Inc.
-5CF7E6 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-A0-D7-95 (hex) Apple, Inc.
-A0D795 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-CC-08-8D (hex) Apple, Inc.
-CC088D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-08-00-07 (hex) Apple, Inc.
-080007 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E4-25-E7 (hex) Apple, Inc.
-E425E7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-28-CF-E9 (hex) Apple, Inc.
-28CFE9 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-90-60-F1 (hex) Apple, Inc.
-9060F1 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-74-1B-B2 (hex) Apple, Inc.
-741BB2 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-28-ED-6A (hex) Apple, Inc.
-28ED6A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-34-AB-37 (hex) Apple, Inc.
-34AB37 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-A3-7D (hex) Apple, Inc.
-60A37D (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-56-CD (hex) Apple, Inc.
-0056CD (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-70-81-EB (hex) Apple, Inc.
-7081EB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-08-66-98 (hex) Apple, Inc.
-086698 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-E0-F8-47 (hex) Apple, Inc.
-E0F847 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-44-2A-60 (hex) Apple, Inc.
-442A60 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-10-93-E9 (hex) Apple, Inc.
-1093E9 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-2B-61 (hex) Apple, Inc.
-DC2B61 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-B8-FF-61 (hex) Apple, Inc.
-B8FF61 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-18-E7-F4 (hex) Apple, Inc.
-18E7F4 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-78-CA-39 (hex) Apple, Inc.
-78CA39 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-5C-59-48 (hex) Apple, Inc.
-5C5948 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-33-4B (hex) Apple, Inc.
-60334B (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-90-27-E4 (hex) Apple, Inc.
-9027E4 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-24-F6-77 (hex) Apple, Inc.
-24F677 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-78-67-D7 (hex) Apple, Inc.
-7867D7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-54-33-CB (hex) Apple, Inc.
-5433CB (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D0-D2-B0 (hex) Apple, Inc.
-D0D2B0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D8-8F-76 (hex) Apple, Inc.
-D88F76 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-3C-2E-F9 (hex) Apple, Inc.
-3C2EF9 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-DC-56-E7 (hex) Apple, Inc.
-DC56E7 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-34-7C-25 (hex) Apple, Inc.
-347C25 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D4-90-9C (hex) Apple, Inc.
-D4909C (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-D4-9A-20 (hex) Apple, Inc.
-D49A20 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-04-1E-64 (hex) Apple, Inc.
-041E64 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-26-B0 (hex) Apple, Inc.
-0026B0 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-26-4A (hex) Apple, Inc.
-00264A (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-25-BC (hex) Apple, Inc.
-0025BC (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-23-DF (hex) Apple, Inc.
-0023DF (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-22-41 (hex) Apple, Inc.
-002241 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-00-0A-95 (hex) Apple, Inc.
-000A95 (base 16) Apple, Inc.
- 1 Infinite Loop
- Cupertino CA 95014
- US
-
-60-5F-8D (hex) eero inc.
-605F8D (base 16) eero inc.
- 500 Howard Street, Suite 900
- SAN FRANCISCO CA 94105
- US
-
-B4-DE-DF (hex) zte corporation
-B4DEDF (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
- CN
-
-84-74-60 (hex) zte corporation
-847460 (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
- CN
-
-B4-A8-B9 (hex) Cisco Systems, Inc
-B4A8B9 (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
- US
-
-88-B6-EE (hex) Dish Technologies Corp
-88B6EE (base 16) Dish Technologies Corp
- 94 Inverness Terrace E
- Englewood CO 80112
- US
-
-38-E6-0A (hex) Xiaomi Communications Co Ltd
-38E60A (base 16) Xiaomi Communications Co Ltd
- The Rainbow City of China Resources
- NO.68, Qinghe Middle Street Haidian District, Beijing 100085
- CN
-
-C0-42-D0 (hex) Juniper Networks
-C042D0 (base 16) Juniper Networks
- 1133 Innovation Way
- Sunnyvale CA 94089
- US
-
-E8-33-0D (hex) Xaptec GmbH
-E8330D (base 16) Xaptec GmbH
- Neidenburger Str. 10
- Gelsenkirchen 45897
- DE
-
-D8-D7-75 (hex) Sagemcom Broadband SAS
-D8D775 (base 16) Sagemcom Broadband SAS
- 250, route de l'Empereur
- Rueil Malmaison Cedex hauts de seine 92848
- FR
-
-78-53-64 (hex) SHIFT GmbH
-785364 (base 16) SHIFT GmbH
- Am Gänsemarkt 6
- Wabern Falkenberg Hessen 34590
- DE
-
-24-18-1D (hex) SAMSUNG ELECTRO-MECHANICS(THAILAND)
-24181D (base 16) SAMSUNG ELECTRO-MECHANICS(THAILAND)
- 93Moo5T. Bangsamak SEMTHAI, WELLGROW INDUSTRIAL ESTATE
- Bangpakong Chachoengsao 24180
- TH
-
-54-B7-E5 (hex) Rayson Technology Co., Ltd.
-54B7E5 (base 16) Rayson Technology Co., Ltd.
- 1F No.9 R&D Rd.II, Science-Based Industrial Park
- Hsin-Chu 300
- TW
-
-BC-0F-A7 (hex) Ouster
-BC0FA7 (base 16) Ouster
- 350 Treat Ave
- San Francisco CA 94110
- US
-
-AC-F9-70 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-ACF970 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
-
-0C-41-E9 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-0C41E9 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
-
-58-D7-59 (hex) HUAWEI TECHNOLOGIES CO.,LTD
-58D759 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
-
-B4-1C-30 (hex) zte corporation
-B41C30 (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
- CN
-
-F4-C2-48 (hex) Samsung Electronics Co.,Ltd
-F4C248 (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-A8-51-5B (hex) Samsung Electronics Co.,Ltd
-A8515B (base 16) Samsung Electronics Co.,Ltd
- #94-1, Imsoo-Dong
- Gumi Gyeongbuk 730-350
- KR
-
-60-6B-FF (hex) Nintendo Co.,Ltd
-606BFF (base 16) Nintendo Co.,Ltd
- 11-1 HOKOTATE-CHO KAMITOBA,MINAMI-KU
- KYOTO KYOTO 601-8501
- JP
-
-AC-17-C8 (hex) Cisco Meraki
-AC17C8 (base 16) Cisco Meraki
- 500 Terry A. Francois Blvd
- San Francisco 94158
- US
-
-EC-9B-8B (hex) Hewlett Packard Enterprise
-EC9B8B (base 16) Hewlett Packard Enterprise
- 8000 Foothills Blvd.
- Roseville CA 95747
- US
-
-70-C9-4E (hex) Liteon Technology Corporation
-70C94E (base 16) Liteon Technology Corporation
- 4F, 90, Chien 1 Road
- New Taipei City Taiwan 23585
- TW
-
-70-D0-81 (hex) Beijing Netpower Technologies Inc.
-70D081 (base 16) Beijing Netpower Technologies Inc.
- Room 201, Block B, NO. 15 Building, EastZone
- Courtyard10, Xibeiwang East Road Haidian District, Beijing 100094
- CN
-
-70-3A-73 (hex) Shenzhen Sundray Technologies Company Limited
-703A73 (base 16) Shenzhen Sundray Technologies Company Limited
- 6th Floor,Block A1, Nanshan iPark, No.1001 XueYuan Road, Nanshan District
- Shenzhen Guangdong 518057
- CN
-
-18-0F-76 (hex) D-Link International
-180F76 (base 16) D-Link International
- 1 Internal Business Park, #03-12,The Synergy, Singapore
- Singapore Singapore 609917
- SG
-
-18-4C-08 (hex) Rockwell Automation
-184C08 (base 16) Rockwell Automation
- 1 Allen-Bradley Dr.
- Mayfield Heights OH 44124-6118
- US
-
-88-E9-0F (hex) innomdlelab
-88E90F (base 16) innomdlelab
- Unnam 1 gil, 3
- Seocho-gu Seoul 06778
- KR
-
-C0-98-DA (hex) China Mobile IOT Company Limited
-C098DA (base 16) China Mobile IOT Company Limited
- NO.8 Yu Ma Road, NanAn Area Chongqing,China
- Chongqing Chongqing 401336
- CN
-
-98-D8-63 (hex) Shanghai High-Flying Electronics Technology Co., Ltd
-98D863 (base 16) Shanghai High-Flying Electronics Technology Co., Ltd
- Room 1002 ,#1Building,No.3000 Longdong Avenue,Pudong District,Shanghai,China
- shanghai shanghai 201203
- CN
-
-F0-0F-EC (hex) HUAWEI TECHNOLOGIES CO.,LTD
-F00FEC (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
-
-0C-70-4A (hex) HUAWEI TECHNOLOGIES CO.,LTD
-0C704A (base 16) HUAWEI TECHNOLOGIES CO.,LTD
- No.2 Xin Cheng Road, Room R6,Songshan Lake Technology Park
- Dongguan 523808
- CN
-
-54-A6-5C (hex) Technicolor CH USA Inc.
-54A65C (base 16) Technicolor CH USA Inc.
- 101 West 103rd St.
- Indianapolis IN 46290
- US
-
-94-9F-3E (hex) Sonos, Inc.
-949F3E (base 16) Sonos, Inc.
- 614 Chapala St
- Santa Barbara CA 93101
+B0-93-5B (hex) ARRIS Group, Inc.
+B0935B (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-B8-E9-37 (hex) Sonos, Inc.
-B8E937 (base 16) Sonos, Inc.
- 614 Chapala St
- Santa Barbara CA 93101
+20-F1-9E (hex) ARRIS Group, Inc.
+20F19E (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-78-28-CA (hex) Sonos, Inc.
-7828CA (base 16) Sonos, Inc.
- 614 Chapala St
- Santa Barbara CA 93101
+8C-5B-F0 (hex) ARRIS Group, Inc.
+8C5BF0 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-34-7E-5C (hex) Sonos, Inc.
-347E5C (base 16) Sonos, Inc.
- 614 Chapala St
- Santa Barbara CA 93101
+00-17-84 (hex) ARRIS Group, Inc.
+001784 (base 16) ARRIS Group, Inc.
+ 6450 Sequence Drive
+ San Diego CA 92121
US
-C0-48-E6 (hex) Samsung Electronics Co.,Ltd
-C048E6 (base 16) Samsung Electronics Co.,Ltd
- 129, Samsung-ro, Youngtongl-Gu
- Suwon Gyeonggi-Do 16677
+04-6B-1B (hex) SYSDINE Co., Ltd.
+046B1B (base 16) SYSDINE Co., Ltd.
+ 506 Convergence technology research commercialization center 218 Gajung-Ro, Yuseong-gu
+ Daejeon-City Daejeon-City 34129
KR
-6C-E4-DA (hex) NEC Platforms, Ltd.
-6CE4DA (base 16) NEC Platforms, Ltd.
- 2-3 Kandatsukasamachi
- Chiyodaku Tokyo 101-8532
- JP
-
-C8-8F-26 (hex) Skyworth Digital Technology(Shenzhen) Co.,Ltd
-C88F26 (base 16) Skyworth Digital Technology(Shenzhen) Co.,Ltd
- 7F,Block A,Skyworth Building,
- Shenzhen Guangdong 518057
+14-9B-2F (hex) JiangSu ZhongXie Intelligent Technology co., LTD
+149B2F (base 16) JiangSu ZhongXie Intelligent Technology co., LTD
+ Room 201,building 15, 16,FengJi set avenue (C08),YuHua district economic development zone ,NanJing city,JiangSu province,China,PRC.
+ NanJing JiangSu 210000
CN
-B0-26-80 (hex) Cisco Systems, Inc
-B02680 (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
- US
-
-00-3C-10 (hex) Cisco Systems, Inc
-003C10 (base 16) Cisco Systems, Inc
- 80 West Tasman Drive
- San Jose CA 94568
- US
-
-90-83-4B (hex) BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD
-90834B (base 16) BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD
- 1-411Room 19#Building No.26 Xihuan South Rd. BDA Daxing District,
- BEIJING 100176
- CN
-
-48-BD-3D (hex) New H3C Technologies Co., Ltd
-48BD3D (base 16) New H3C Technologies Co., Ltd
- 466 Changhe Road, Binjiang District
- Hangzhou Zhejiang 310052
- CN
-
-4C-AB-FC (hex) zte corporation
-4CABFC (base 16) zte corporation
- 12/F.,zte R&D building ,kejinan Road,Shenzhen,P.R.China
- shenzhen guangdong 518057
- CN
-
-20-0F-70 (hex) FOXTECH
-200F70 (base 16) FOXTECH
- 152-160 City Road
- LONDON KEMP HOUSE EC1V 2NX
- GB
-
-E8-1A-AC (hex) ORFEO SOUNDWORKS Inc.
-E81AAC (base 16) ORFEO SOUNDWORKS Inc.
- 612, 11-41, Simin-daero 327beon-gil, Dongan-gu
- Anyang 14055
- KR
-
-A0-38-F8 (hex) OURA Health Oy
-A038F8 (base 16) OURA Health Oy
- Elektroniikkatie 3
- Oulu 90590
- FI
-
-14-6B-9C (hex) SHENZHEN BILIAN ELECTRONIC CO.,LTD
-146B9C (base 16) SHENZHEN BILIAN ELECTRONIC CO.,LTD
- NO.268, Fuqian Rd, Jutang community, Guanlan Town, Longhua New district
- shenzhen guangdong 518000
+38-AF-29 (hex) Zhejiang Dahua Technology Co., Ltd.
+38AF29 (base 16) Zhejiang Dahua Technology Co., Ltd.
+ No.1199,Waterfront Road
+ Hangzhou Zhejiang 310053
CN
-D0-77-14 (hex) Motorola Mobility LLC, a Lenovo Company
-D07714 (base 16) Motorola Mobility LLC, a Lenovo Company
- 222 West Merchandise Mart Plaza
- Chicago IL 60654
- US
+88-DE-7C (hex) Askey Computer Corp.
+88DE7C (base 16) Askey Computer Corp.
+ 10F, No.119, JIANKANG RD.,ZHINGHE DIST,
+ NEW TAIPEI CITY 23585
+ TW
-34-D7-12 (hex) Smartisan Digital Co., Ltd
-34D712 (base 16) Smartisan Digital Co., Ltd
- 4F, China Digital Kingdom, No.1 Wangjing North Road, Chaoyang District
- Beijing Beijing 100012
+BC-32-5F (hex) Zhejiang Dahua Technology Co., Ltd.
+BC325F (base 16) Zhejiang Dahua Technology Co., Ltd.
+ No.1199,Waterfront Road
+ Hangzhou Zhejiang 310053
CN
-98-45-62 (hex) Shanghai Baud Data Communication Co.,Ltd.
-984562 (base 16) Shanghai Baud Data Communication Co.,Ltd.
- NO.123 JULI RD
- PUDONG ZHANGJIANG HIGH-TECH PARK SHANGHAI 201203
+E4-E1-30 (hex) TCT mobile ltd
+E4E130 (base 16) TCT mobile ltd
+ No.86 hechang 7th road, zhongkai, Hi-Tech District
+ Hui Zhou Guang Dong 516006
CN
-E8-98-6D (hex) Palo Alto Networks
-E8986D (base 16) Palo Alto Networks
- 3000 Tannery Way
- Santa Clara CA 95054
- US
-
-F0-81-73 (hex) Amazon Technologies Inc.
-F08173 (base 16) Amazon Technologies Inc.
- P.O Box 8102
- Reno 89507
+88-D6-52 (hex) AMERGINT Technologies
+88D652 (base 16) AMERGINT Technologies
+ 2315 Briargate Pkwy, Suite 100
+ Colorado Springs CO 80920
US
-
-24-29-FE (hex) KYOCERA Corporation
-2429FE (base 16) KYOCERA Corporation
- 30 Hoji
- Kitami, Hokkaido 099-1595
- JP
diff --git a/hwdb/ma-medium.txt b/hwdb/ma-medium.txt index 89577b9cf8..9c97afffdc 100644 --- a/hwdb/ma-medium.txt +++ b/hwdb/ma-medium.txt @@ -1319,12 +1319,6 @@ D00000-DFFFFF (base 16) optilink networks pvt ltd mumbai maharashtra 400071
IN
-74-19-F8 (hex) Heptagon Systems PTY. LTD.
-700000-7FFFFF (base 16) Heptagon Systems PTY. LTD.
- 7 Tyrone Street
- Camberwell 3124
- AU
-
50-0B-91 (hex) thumbzup UK Limited
B00000-BFFFFF (base 16) thumbzup UK Limited
6th Floor, 94 Wigmore Street
@@ -2000,42 +1994,6 @@ F00000-FFFFFF (base 16) Private NishiTokyo-city Tokyo 202-0022
JP
-9C-43-1E (hex) HK ELEPHONE Communication Tech Co.,Limited
-D00000-DFFFFF (base 16) HK ELEPHONE Communication Tech Co.,Limited
- Unit 04, 7/F Bright Way Tower No.33 Mong Kok Rd KL
- Hong Kong 999077
- HK
-
-9C-43-1E (hex) Wireless Environment, LLC
-400000-4FFFFF (base 16) Wireless Environment, LLC
- 600 Beta Drive Unit 100 Mayfield Village, OH 44143,US
- Mayfield Village OH 44143
- US
-
-28-2C-02 (hex) ThirdReality, Inc
-B00000-BFFFFF (base 16) ThirdReality, Inc
- 647 East Longhua Road, Huangpu District
- Shanghai Shanghai 200023
- CN
-
-9C-43-1E (hex) HAESUNG DS
-200000-2FFFFF (base 16) HAESUNG DS
- 8F, Haesung 2 Building, 508, Teheran-ro, Gangnam-gu
- Seoul 06178
- KR
-
-28-2C-02 (hex) Tokin Limited
-A00000-AFFFFF (base 16) Tokin Limited
- Unit 513-4, Block A, Focal Industrial Centre, 21 Man Lok Street, Hung Hom
- Kowloon 0000
- HK
-
-F0-41-C8 (hex) Shenzhen Medica Technology Development Co., Ltd.
-200000-2FFFFF (base 16) Shenzhen Medica Technology Development Co., Ltd.
- 2F Building A, Tongfang Information Harbor, No.11, East Langshan Road, Nanshan District
- Shenzhen 518000
- CN
-
C4-FF-BC (hex) Danego BV
000000-0FFFFF (base 16) Danego BV
Protonenlaan 24
@@ -2099,6 +2057,138 @@ F0-41-C8 (hex) LINPA ACOUSTIC TECHNOLOGY CO.,LTD Dongguan Guandong 523648
CN
+F0-41-C8 (hex) DongGuan Siyoto Electronics Co., Ltd
+100000-1FFFFF (base 16) DongGuan Siyoto Electronics Co., Ltd
+ Hecheng Industrial District, QiaoTou Town, DongGuan City,Guangdong,China
+ DongGuan 523520
+ CN
+
+74-19-F8 (hex) Heptagon Systems PTY. LTD.
+700000-7FFFFF (base 16) Heptagon Systems PTY. LTD.
+ 625-627 Ringwood Warrandyte Road
+ Ringwood North VIC 3124
+ AU
+
+F0-41-C8 (hex) Shenzhen Umind Technology Co., Ltd.
+E00000-EFFFFF (base 16) Shenzhen Umind Technology Co., Ltd.
+ Add: D2-6A, TCL Science Park, 1001 ZhongshanYuan Road, Nanshan District
+ Shenzhen Guangdong 581055
+ CN
+
+30-1F-9A (hex) Shenzhen Fengliyuan Energy Conservating Technology Co. Ltd
+E00000-EFFFFF (base 16) Shenzhen Fengliyuan Energy Conservating Technology Co. Ltd
+ 8th floor of building A, Baoshan Industrial Estate, Longhua District, Shenzhen
+ Shenzhen Guangdong 518131
+ CN
+
+88-5F-E8 (hex) Sonnet Labs Inc.
+300000-3FFFFF (base 16) Sonnet Labs Inc.
+ 8 The Green Suite #6290
+ Dover DE 19901
+ US
+
+88-5F-E8 (hex) Changsha Xiangji-Haidun Technology Co., Ltd
+800000-8FFFFF (base 16) Changsha Xiangji-Haidun Technology Co., Ltd
+ NO.5 Dongsan Rd, Changsha Economic & Technical Zone
+ Changsha HuNan 410100
+ CN
+
+9C-43-1E (hex) HK ELEPHONE Communication Tech Co.,Limited
+D00000-DFFFFF (base 16) HK ELEPHONE Communication Tech Co.,Limited
+ Unit 04, 7/F Bright Way Tower No.33 Mong Kok Rd KL
+ Hong Kong 999077
+ HK
+
+9C-43-1E (hex) Wireless Environment, LLC
+400000-4FFFFF (base 16) Wireless Environment, LLC
+ 600 Beta Drive Unit 100 Mayfield Village, OH 44143,US
+ Mayfield Village OH 44143
+ US
+
+28-2C-02 (hex) ThirdReality, Inc
+B00000-BFFFFF (base 16) ThirdReality, Inc
+ 647 East Longhua Road, Huangpu District
+ Shanghai Shanghai 200023
+ CN
+
+9C-43-1E (hex) HAESUNG DS
+200000-2FFFFF (base 16) HAESUNG DS
+ 8F, Haesung 2 Building, 508, Teheran-ro, Gangnam-gu
+ Seoul 06178
+ KR
+
+28-2C-02 (hex) Tokin Limited
+A00000-AFFFFF (base 16) Tokin Limited
+ Unit 513-4, Block A, Focal Industrial Centre, 21 Man Lok Street, Hung Hom
+ Kowloon 0000
+ HK
+
+F0-41-C8 (hex) Shenzhen Medica Technology Development Co., Ltd.
+200000-2FFFFF (base 16) Shenzhen Medica Technology Development Co., Ltd.
+ 2F Building A, Tongfang Information Harbor, No.11, East Langshan Road, Nanshan District
+ Shenzhen 518000
+ CN
+
+48-0B-B2 (hex) SHENZHEN TOPWELL TECHNOLOGY CO..LTD
+C00000-CFFFFF (base 16) SHENZHEN TOPWELL TECHNOLOGY CO..LTD
+ 5th Floor, Building 10 Changyuan New Material
+ Port,No.2,Middle Road 1, High Tech Park, Nanshan District,Shenzhen 518001
+ CN
+
+88-5F-E8 (hex) Lisle Design Ltd
+A00000-AFFFFF (base 16) Lisle Design Ltd
+ New Technology Centre, North Haugh
+ St. Andrews Fife KY16 9SR
+ GB
+
+88-5F-E8 (hex) Sowee
+900000-9FFFFF (base 16) Sowee
+ 4 place des Vosges
+ Courbevoie 92400
+ FR
+
+0C-73-EB (hex) Beijing L&S Lancom Platform Tech. Co., Ltd.
+900000-9FFFFF (base 16) Beijing L&S Lancom Platform Tech. Co., Ltd.
+ 1st Floor, Xingtianhaiyuan Building, Xianghuangqi Eaast Rd, Nondda South Rd,Haidian District
+ Beijing 100193
+ CN
+
+3C-24-F0 (hex) Swissdotnet SA
+700000-7FFFFF (base 16) Swissdotnet SA
+ Route Saint-Nicolas-de-Flüe 2
+ Fribourg 1700
+ CH
+
+0C-73-EB (hex) Green Fox Electro AS
+600000-6FFFFF (base 16) Green Fox Electro AS
+ Wessels veg 63
+ STJORDAL NO-7502
+ NO
+
+3C-24-F0 (hex) Authentico Technologies
+C00000-CFFFFF (base 16) Authentico Technologies
+ Erikdahlbergsgatan 4
+ Göteborg 41126
+ SE
+
+3C-24-F0 (hex) Siemens AG - Siemens Deutschland Mobility
+900000-9FFFFF (base 16) Siemens AG - Siemens Deutschland Mobility
+ Otto-Hahn-Ring 6
+ Munich 81379
+ DE
+
+3C-24-F0 (hex) Inter-Coastal Electronics
+400000-4FFFFF (base 16) Inter-Coastal Electronics
+ 5750 E McKellips Rd
+ Mesa AZ 85215
+ US
+
+0C-73-EB (hex) Shenzhen Samchung Video Technology Co., Ltd.
+C00000-CFFFFF (base 16) Shenzhen Samchung Video Technology Co., Ltd.
+ Xixiang Street 4016 Bao'an Avenue
+ Yong Kai Business Building A, Bao'an District of Shenzhen City Guangdong 528470
+ CN
+
1C-87-76 (hex) Strone Technology
C00000-CFFFFF (base 16) Strone Technology
13 Ellis Street
@@ -3542,6 +3632,288 @@ A00000-AFFFFF (base 16) Integrated Design Ltd Feltham Middlesex TW137EQ
GB
+CC-22-37 (hex) Apeiron Data Systems
+200000-2FFFFF (base 16) Apeiron Data Systems
+ 81 Blue Ravine Road
+ Folsom CA 95630
+ US
+
+04-71-4B (hex) Shenzhen WayOS Technology Crop., Ltd.
+200000-2FFFFF (base 16) Shenzhen WayOS Technology Crop., Ltd.
+ F18, Yousong Business Building, Longhua New Districe, Shenzhen, China
+ Shenzhen Guangdong 518109
+ CN
+
+74-1A-E0 (hex) Revl Inc.
+400000-4FFFFF (base 16) Revl Inc.
+ 325 9th St.
+ San Francisco CA 94103
+ US
+
+74-1A-E0 (hex) Private
+900000-9FFFFF (base 16) Private
+
+74-1A-E0 (hex) SHEN ZHEN YINGJIACHUANG ELECTRONICS TECHNOLOGY CO.,LTD.
+B00000-BFFFFF (base 16) SHEN ZHEN YINGJIACHUANG ELECTRONICS TECHNOLOGY CO.,LTD.
+ Building A,Baishunjia Industrial Park,Guangming New District
+ Shenzhen 518107
+ CN
+
+74-1A-E0 (hex) FUJIAN TAILI COMMUNICATION TECHNOLOGY CO.,LTD
+500000-5FFFFF (base 16) FUJIAN TAILI COMMUNICATION TECHNOLOGY CO.,LTD
+ Cangshan science and technology park, Baihuting,Cangshan District, Fuzhou
+ FUZHOU 350026
+ CN
+
+74-1A-E0 (hex) bistos.co.ltd
+C00000-CFFFFF (base 16) bistos.co.ltd
+ 7floor, worim lions vally 5cha
+ sungnam kyeunggi-do 13201
+ KR
+
+00-55-DA (hex) Private
+F00000-FFFFFF (base 16) Private
+
+D0-22-12 (hex) Private
+F00000-FFFFFF (base 16) Private
+
+AC-1D-DF (hex) Elekon AG
+D00000-DFFFFF (base 16) Elekon AG
+ Cheerstrasse 16
+ Luzern 6014
+ CH
+
+34-D0-B8 (hex) Captec Ltd
+000000-0FFFFF (base 16) Captec Ltd
+ 7 Whittle Avenue
+ Fareham Hampshire PO15 5SH
+ GB
+
+EC-9F-0D (hex) SKS Control Oy
+D00000-DFFFFF (base 16) SKS Control Oy
+ Martinkyläntie 50
+ Vantaa 01720
+ FI
+
+EC-9F-0D (hex) Bei jing Lian Shan times Techonology Co.Ltd
+700000-7FFFFF (base 16) Bei jing Lian Shan times Techonology Co.Ltd
+ Beijing Haidian.No.2 of Yong Cheng North Road Building 1.402
+ Beijing 100094
+ CN
+
+EC-9F-0D (hex) Shenzhen Compare Electronics Co., Ltd
+600000-6FFFFF (base 16) Shenzhen Compare Electronics Co., Ltd
+ 18F 5D First Area, Shenzhen Bay Eco-tech Park, Nanshan District, Shenzhen 518057, China
+ Shenzhen City (深圳市) Guangdong 518057
+ CN
+
+EC-9F-0D (hex) CRRC QINGDAO SIFANG ROLLING STOCK RESEARCH INSTITUTE CO.,LTD
+B00000-BFFFFF (base 16) CRRC QINGDAO SIFANG ROLLING STOCK RESEARCH INSTITUTE CO.,LTD
+ No.231 Ruichang Road Qingdao City
+ Qingdao Shandong 266000
+ CN
+
+EC-9F-0D (hex) Simula Technology Inc.
+100000-1FFFFF (base 16) Simula Technology Inc.
+ 14 F, 1351, Zhong-Zheng Rd.
+ Taoyuan 330
+ TW
+
+EC-9F-0D (hex) MAX Technologies
+E00000-EFFFFF (base 16) MAX Technologies
+ 2051 Victoria Av.
+ St-Lambert Quebec J4S1H1
+ CA
+
+38-73-EA (hex) Live Sentinel
+600000-6FFFFF (base 16) Live Sentinel
+ 27 Armthorpe Rd.
+ Brampton Ontario L6T 5M4
+ CA
+
+38-73-EA (hex) PingGPS Inc
+700000-7FFFFF (base 16) PingGPS Inc
+ 19825 North Cove Road, #173
+ CORNELIUS NC 28031
+ US
+
+38-73-EA (hex) Shanghai ZoomSmart Technology Co., Ltd.
+B00000-BFFFFF (base 16) Shanghai ZoomSmart Technology Co., Ltd.
+ ROOM 802, No. 189, Hengxi Road, Pujiang Town, Minhang District, Shanghai PRC
+ Shanghai 200000
+ CN
+
+40-48-FD (hex) Dorel Juvenile
+800000-8FFFFF (base 16) Dorel Juvenile
+ 25 Forbes Blvd
+ Foxborough MA 02035
+ US
+
+F8-B5-68 (hex) Package Guard, Inc
+600000-6FFFFF (base 16) Package Guard, Inc
+ 2819 33rd ave so
+ seattle WA 98144
+ US
+
+F8-B5-68 (hex) CloudMinds (Shenzhen) Holdings Co., Ltd
+700000-7FFFFF (base 16) CloudMinds (Shenzhen) Holdings Co., Ltd
+ Tower 3, 33F, Unit B, Wangjing SOHO,Wangjing Street No.10
+ beijing 100102
+ CN
+
+28-2C-02 (hex) Astronics AES
+100000-1FFFFF (base 16) Astronics AES
+ 12950 Willows Rd NE
+ Kirkland WA 98034
+ US
+
+10-07-23 (hex) Private
+F00000-FFFFFF (base 16) Private
+
+28-2C-02 (hex) LLC MICROTEH
+500000-5FFFFF (base 16) LLC MICROTEH
+ pl.5 bldg.2/3 Akademika Anokhina str.
+ Moscow 119602
+ RU
+
+9C-43-1E (hex) Wunda Group plc
+800000-8FFFFF (base 16) Wunda Group plc
+ Unit 1-5, Hawthorn, Crick
+ Caldicot Monmouthshire NP26 5UT
+ GB
+
+9C-43-1E (hex) Advanced Logic Technology (ALT) sa
+300000-3FFFFF (base 16) Advanced Logic Technology (ALT) sa
+ Route de Niederpallen, 30H
+ Redange-sur-Attert Luxembourg 8506
+ LU
+
+C4-FF-BC (hex) GSM Innovations Pty Ltd
+900000-9FFFFF (base 16) GSM Innovations Pty Ltd
+ 142-144 Fullarton Road
+ Rose Park SA 5067
+ AU
+
+C4-FF-BC (hex) SHENZHEN KALIF ELECTRONICS CO.,LTD
+300000-3FFFFF (base 16) SHENZHEN KALIF ELECTRONICS CO.,LTD
+ 1、2 and 3 Floor, No.114, Haochong No.2 Industry Area, Hongxing Community, Songgang, Baoan, Shenzhen
+ SHENZHEN GuangDong 518105
+ CN
+
+C4-FF-BC (hex) Beijing KDF information technology co. LTD.
+D00000-DFFFFF (base 16) Beijing KDF information technology co. LTD.
+ Room14C,TowerA,,LindaBuilding,No.8,Dongtucheng Road,Chaoyang District, Beijing.
+ Beijing 100013
+ CN
+
+9C-43-1E (hex) Optris GmbH
+700000-7FFFFF (base 16) Optris GmbH
+ Ferdinand-Buisson-Str. 14
+ Berlin 13127
+ DE
+
+C4-FF-BC (hex) viRaTec GmbH
+E00000-EFFFFF (base 16) viRaTec GmbH
+ Phorusgasse 8/1
+ Wien 1040
+ AT
+
+DC-E5-33 (hex) Controls Inc
+500000-5FFFFF (base 16) Controls Inc
+ 5204 Portside Drive
+ Medina OH 44256
+ US
+
+C4-FF-BC (hex) Shenzhen C & D Electronics Co., Ltd.
+600000-6FFFFF (base 16) Shenzhen C & D Electronics Co., Ltd.
+ 9th FIoor, Building 9, No.1 Qingxiang road, BaoNeng Science and TechnoIogy Industrial Park, Longhua New District
+ ShenZhen GuangDong 518000
+ CN
+
+DC-E5-33 (hex) FLYHT Aerospace
+000000-0FFFFF (base 16) FLYHT Aerospace
+ 300E 1144 - 29th St. N.E.
+ Calgary AB T2E7P1
+ CA
+
+DC-E5-33 (hex) Private
+A00000-AFFFFF (base 16) Private
+
+A4-DA-22 (hex) Shen Zhen City YaKun Electronics Co., Ltd
+D00000-DFFFFF (base 16) Shen Zhen City YaKun Electronics Co., Ltd
+ SOUTHERN BUILDING 5388 Shang Bu Industrial Zone Huaqiang North Road Futian District
+ shen zhen city Guang Dong Province 518000
+ CN
+
+A4-DA-22 (hex) Abetechs GmbH
+A00000-AFFFFF (base 16) Abetechs GmbH
+ Niermannsweg 11
+ Erkrath North Rhine-Westphalia 40699
+ DE
+
+A4-DA-22 (hex) T2T System
+100000-1FFFFF (base 16) T2T System
+ #316, HYUNDAI Knowledge Industry Center, 70, Dusan-ro
+ Geumcheon-gu Seoul 08584
+ KR
+
+A4-DA-22 (hex) Quuppa Oy
+E00000-EFFFFF (base 16) Quuppa Oy
+ Keilaranta 1
+ Espoo 02150
+ FI
+
+88-A9-A7 (hex) AndroVideo Inc.
+C00000-CFFFFF (base 16) AndroVideo Inc.
+ 2f-4, 17, Lane 91, Nei Hu Rd., Sec. 1
+ Taipei 11441
+ TW
+
+F0-41-C8 (hex) Shenzhen Nufilo Electronic Technology Co., Ltd.
+900000-9FFFFF (base 16) Shenzhen Nufilo Electronic Technology Co., Ltd.
+ Tianliao Building West Unit F1315, (New Materials Industrial Park), Xueyuan Road, Nanshan District
+ Shenzhen Guangdong 518055
+ CN
+
+F0-41-C8 (hex) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+300000-3FFFFF (base 16) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+ No.826,Zone 1,Block B,Famous industrial product display purchasing center,Baoyuan Road,Xixiang,Bao'an Dis., Shenzhen,P.R.China
+ shenzhen China 518102
+ CN
+
+F0-41-C8 (hex) Shanghai Think-Force Electronic Technology Co. Ltd
+C00000-CFFFFF (base 16) Shanghai Think-Force Electronic Technology Co. Ltd
+ North ZhongShan Road, No. 3000, Room 2608
+ Shanghai 200000
+ CN
+
+30-1F-9A (hex) ILSAN ELECTRONICS
+000000-0FFFFF (base 16) ILSAN ELECTRONICS
+ 433Beon-gil 52,Sasang-ro,Sasang-gu
+ Busan 46923
+ KR
+
+30-1F-9A (hex) YiSheng technology co.,LTD
+600000-6FFFFF (base 16) YiSheng technology co.,LTD
+ Xintian road no:71, F#202
+ shenzhen baoan 518103
+ CN
+
+30-1F-9A (hex) Private
+900000-9FFFFF (base 16) Private
+
+88-5F-E8 (hex) Opto Engineering
+200000-2FFFFF (base 16) Opto Engineering
+ Circonvallazione Sud, 15
+ Mantova 46100
+ IT
+
+88-5F-E8 (hex) Jungheinrich Norderstedt AG & Co. KG
+000000-0FFFFF (base 16) Jungheinrich Norderstedt AG & Co. KG
+ Lawaetzstr. 9-13
+ Norderstedt 22844
+ DE
+
34-04-9E (hex) uikismart
D00000-DFFFFF (base 16) uikismart
Nanshan
@@ -3902,260 +4274,65 @@ B00000-BFFFFF (base 16) Private Singapore Singapore 608579
SG
-CC-22-37 (hex) Apeiron Data Systems
-200000-2FFFFF (base 16) Apeiron Data Systems
- 81 Blue Ravine Road
- Folsom CA 95630
- US
-
-04-71-4B (hex) Shenzhen WayOS Technology Crop., Ltd.
-200000-2FFFFF (base 16) Shenzhen WayOS Technology Crop., Ltd.
- F18, Yousong Business Building, Longhua New Districe, Shenzhen, China
- Shenzhen Guangdong 518109
- CN
-
-74-1A-E0 (hex) Revl Inc.
-400000-4FFFFF (base 16) Revl Inc.
- 325 9th St.
- San Francisco CA 94103
- US
-
-74-1A-E0 (hex) Private
-900000-9FFFFF (base 16) Private
-
-74-1A-E0 (hex) SHEN ZHEN YINGJIACHUANG ELECTRONICS TECHNOLOGY CO.,LTD.
-B00000-BFFFFF (base 16) SHEN ZHEN YINGJIACHUANG ELECTRONICS TECHNOLOGY CO.,LTD.
- Building A,Baishunjia Industrial Park,Guangming New District
- Shenzhen 518107
- CN
-
-74-1A-E0 (hex) FUJIAN TAILI COMMUNICATION TECHNOLOGY CO.,LTD
-500000-5FFFFF (base 16) FUJIAN TAILI COMMUNICATION TECHNOLOGY CO.,LTD
- Cangshan science and technology park, Baihuting,Cangshan District, Fuzhou
- FUZHOU 350026
- CN
-
-74-1A-E0 (hex) bistos.co.ltd
-C00000-CFFFFF (base 16) bistos.co.ltd
- 7floor, worim lions vally 5cha
- sungnam kyeunggi-do 13201
- KR
-
-00-55-DA (hex) Private
-F00000-FFFFFF (base 16) Private
-
-D0-22-12 (hex) Private
-F00000-FFFFFF (base 16) Private
-
-AC-1D-DF (hex) Elekon AG
-D00000-DFFFFF (base 16) Elekon AG
- Cheerstrasse 16
- Luzern 6014
- CH
-
-34-D0-B8 (hex) Captec Ltd
-000000-0FFFFF (base 16) Captec Ltd
- 7 Whittle Avenue
- Fareham Hampshire PO15 5SH
- GB
-
-EC-9F-0D (hex) SKS Control Oy
-D00000-DFFFFF (base 16) SKS Control Oy
- Martinkyläntie 50
- Vantaa 01720
- FI
-
-EC-9F-0D (hex) Bei jing Lian Shan times Techonology Co.Ltd
-700000-7FFFFF (base 16) Bei jing Lian Shan times Techonology Co.Ltd
- Beijing Haidian.No.2 of Yong Cheng North Road Building 1.402
- Beijing 100094
+88-5F-E8 (hex) Apoidea Technology Co., Ltd.
+100000-1FFFFF (base 16) Apoidea Technology Co., Ltd.
+ No. 111, Boyun Road
+ Shanghai 201203
CN
-EC-9F-0D (hex) Shenzhen Compare Electronics Co., Ltd
-600000-6FFFFF (base 16) Shenzhen Compare Electronics Co., Ltd
- 18F 5D First Area, Shenzhen Bay Eco-tech Park, Nanshan District, Shenzhen 518057, China
- Shenzhen City (深圳市) Guangdong 518057
+88-5F-E8 (hex) zhejiang yuanwang communication technolgy co.,ltd
+D00000-DFFFFF (base 16) zhejiang yuanwang communication technolgy co.,ltd
+ No. 6 of shen shi lei lu Road
+ ZhuJi Zhejiang 311800
CN
-EC-9F-0D (hex) CRRC QINGDAO SIFANG ROLLING STOCK RESEARCH INSTITUTE CO.,LTD
-B00000-BFFFFF (base 16) CRRC QINGDAO SIFANG ROLLING STOCK RESEARCH INSTITUTE CO.,LTD
- No.231 Ruichang Road Qingdao City
- Qingdao Shandong 266000
+48-0B-B2 (hex) Thales CETCA Avionics CO., Ltd
+200000-2FFFFF (base 16) Thales CETCA Avionics CO., Ltd
+ NO.9 Baichuan road,Hi-tech industry west zone park, Chengdu, Sichuan
+ Chengdu Sichuan 611731
CN
-EC-9F-0D (hex) Simula Technology Inc.
-100000-1FFFFF (base 16) Simula Technology Inc.
- 14 F, 1351, Zhong-Zheng Rd.
- Taoyuan 330
- TW
-
-EC-9F-0D (hex) MAX Technologies
-E00000-EFFFFF (base 16) MAX Technologies
- 2051 Victoria Av.
- St-Lambert Quebec J4S1H1
- CA
-
-38-73-EA (hex) Live Sentinel
-600000-6FFFFF (base 16) Live Sentinel
- 27 Armthorpe Rd.
- Brampton Ontario L6T 5M4
- CA
-
-38-73-EA (hex) PingGPS Inc
-700000-7FFFFF (base 16) PingGPS Inc
- 19825 North Cove Road, #173
- CORNELIUS NC 28031
- US
+48-0B-B2 (hex) M2Lab Ltd.
+D00000-DFFFFF (base 16) M2Lab Ltd.
+ 148 Des Voeux Rd Central
+ Hong Kong HK
+ HK
-38-73-EA (hex) Shanghai ZoomSmart Technology Co., Ltd.
-B00000-BFFFFF (base 16) Shanghai ZoomSmart Technology Co., Ltd.
- ROOM 802, No. 189, Hengxi Road, Pujiang Town, Minhang District, Shanghai PRC
- Shanghai 200000
+48-0B-B2 (hex) Beijing MFOX technology Co., Ltd.
+E00000-EFFFFF (base 16) Beijing MFOX technology Co., Ltd.
+ B zone,floor 2,NO.A5 east Rongchang street .BDA (yizhuang) BeiJing
+ BeiJing BeiJing 100176
CN
-40-48-FD (hex) Dorel Juvenile
-800000-8FFFFF (base 16) Dorel Juvenile
- 25 Forbes Blvd
- Foxborough MA 02035
- US
-
-F8-B5-68 (hex) Package Guard, Inc
-600000-6FFFFF (base 16) Package Guard, Inc
- 2819 33rd ave so
- seattle WA 98144
- US
-
-F8-B5-68 (hex) CloudMinds (Shenzhen) Holdings Co., Ltd
-700000-7FFFFF (base 16) CloudMinds (Shenzhen) Holdings Co., Ltd
- Tower 3, 33F, Unit B, Wangjing SOHO,Wangjing Street No.10
- beijing 100102
+0C-73-EB (hex) EVERSEC TECHNOLOGY CORPORATION
+100000-1FFFFF (base 16) EVERSEC TECHNOLOGY CORPORATION
+ F5,Tower D,JingYi Technology Building NO.9 Dazhongsi East Road.,Beijing,P.R.China
+ BEIJING BEIJING 100086
CN
-28-2C-02 (hex) Astronics AES
-100000-1FFFFF (base 16) Astronics AES
- 12950 Willows Rd NE
- Kirkland WA 98034
+0C-73-EB (hex) Pi Innovo LLC
+A00000-AFFFFF (base 16) Pi Innovo LLC
+ 47023 Five Mile Rd
+ Plymouth MI 48170
US
-10-07-23 (hex) Private
-F00000-FFFFFF (base 16) Private
-
-28-2C-02 (hex) LLC MICROTEH
-500000-5FFFFF (base 16) LLC MICROTEH
- pl.5 bldg.2/3 Akademika Anokhina str.
- Moscow 119602
- RU
-
-9C-43-1E (hex) Wunda Group plc
-800000-8FFFFF (base 16) Wunda Group plc
- Unit 1-5, Hawthorn, Crick
- Caldicot Monmouthshire NP26 5UT
+0C-73-EB (hex) Gemini Data Loggers (UK) Limited
+000000-0FFFFF (base 16) Gemini Data Loggers (UK) Limited
+ Scientific House, Terminus Road
+ Chichester West Sussex PO19 8UJ
GB
-9C-43-1E (hex) Advanced Logic Technology (ALT) sa
-300000-3FFFFF (base 16) Advanced Logic Technology (ALT) sa
- Route de Niederpallen, 30H
- Redange-sur-Attert Luxembourg 8506
- LU
-
-C4-FF-BC (hex) GSM Innovations Pty Ltd
-900000-9FFFFF (base 16) GSM Innovations Pty Ltd
- 142-144 Fullarton Road
- Rose Park SA 5067
- AU
-
-C4-FF-BC (hex) SHENZHEN KALIF ELECTRONICS CO.,LTD
-300000-3FFFFF (base 16) SHENZHEN KALIF ELECTRONICS CO.,LTD
- 1、2 and 3 Floor, No.114, Haochong No.2 Industry Area, Hongxing Community, Songgang, Baoan, Shenzhen
- SHENZHEN GuangDong 518105
- CN
-
-C4-FF-BC (hex) Beijing KDF information technology co. LTD.
-D00000-DFFFFF (base 16) Beijing KDF information technology co. LTD.
- Room14C,TowerA,,LindaBuilding,No.8,Dongtucheng Road,Chaoyang District, Beijing.
- Beijing 100013
- CN
-
-9C-43-1E (hex) Optris GmbH
-700000-7FFFFF (base 16) Optris GmbH
- Ferdinand-Buisson-Str. 14
- Berlin 13127
- DE
-
-C4-FF-BC (hex) viRaTec GmbH
-E00000-EFFFFF (base 16) viRaTec GmbH
- Phorusgasse 8/1
- Wien 1040
- AT
-
-DC-E5-33 (hex) Controls Inc
-500000-5FFFFF (base 16) Controls Inc
- 5204 Portside Drive
- Medina OH 44256
- US
-
-C4-FF-BC (hex) Shenzhen C & D Electronics Co., Ltd.
-600000-6FFFFF (base 16) Shenzhen C & D Electronics Co., Ltd.
- 9th FIoor, Building 9, No.1 Qingxiang road, BaoNeng Science and TechnoIogy Industrial Park, Longhua New District
- ShenZhen GuangDong 518000
- CN
-
-DC-E5-33 (hex) FLYHT Aerospace
-000000-0FFFFF (base 16) FLYHT Aerospace
- 300E 1144 - 29th St. N.E.
- Calgary AB T2E7P1
- CA
-
-DC-E5-33 (hex) Private
-A00000-AFFFFF (base 16) Private
-
-A4-DA-22 (hex) Shen Zhen City YaKun Electronics Co., Ltd
-D00000-DFFFFF (base 16) Shen Zhen City YaKun Electronics Co., Ltd
- SOUTHERN BUILDING 5388 Shang Bu Industrial Zone Huaqiang North Road Futian District
- shen zhen city Guang Dong Province 518000
- CN
-
-A4-DA-22 (hex) Abetechs GmbH
-A00000-AFFFFF (base 16) Abetechs GmbH
- Niermannsweg 11
- Erkrath North Rhine-Westphalia 40699
- DE
-
-A4-DA-22 (hex) T2T System
-100000-1FFFFF (base 16) T2T System
- #316, HYUNDAI Knowledge Industry Center, 70, Dusan-ro
- Geumcheon-gu Seoul 08584
- KR
-
-A4-DA-22 (hex) Quuppa Oy
-E00000-EFFFFF (base 16) Quuppa Oy
- Keilaranta 1
- Espoo 02150
- FI
-
-88-A9-A7 (hex) AndroVideo Inc.
-C00000-CFFFFF (base 16) AndroVideo Inc.
- 2f-4, 17, Lane 91, Nei Hu Rd., Sec. 1
- Taipei 11441
- TW
-
-F0-41-C8 (hex) Shenzhen Nufilo Electronic Technology Co., Ltd.
-900000-9FFFFF (base 16) Shenzhen Nufilo Electronic Technology Co., Ltd.
- Tianliao Building West Unit F1315, (New Materials Industrial Park), Xueyuan Road, Nanshan District
- Shenzhen Guangdong 518055
- CN
-
-F0-41-C8 (hex) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
-300000-3FFFFF (base 16) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
- No.826,Zone 1,Block B,Famous industrial product display purchasing center,Baoyuan Road,Xixiang,Bao'an Dis., Shenzhen,P.R.China
- shenzhen China 518102
- CN
+3C-24-F0 (hex) Abrites Ltd.
+100000-1FFFFF (base 16) Abrites Ltd.
+ 147 Cherni Vrah Blvd.
+ Sofia Sofia 1407
+ BG
-F0-41-C8 (hex) Shanghai Think-Force Electronic Technology Co. Ltd
-C00000-CFFFFF (base 16) Shanghai Think-Force Electronic Technology Co. Ltd
- North ZhongShan Road, No. 3000, Room 2608
- Shanghai 200000
- CN
+3C-24-F0 (hex) Wisycom
+300000-3FFFFF (base 16) Wisycom
+ Via Spin 156
+ Romano D'Ezzelino Vicenza 36060
+ IT
1C-87-76 (hex) Zhuhai MYZR Technology Co.,Ltd
500000-5FFFFF (base 16) Zhuhai MYZR Technology Co.,Ltd
@@ -5213,12 +5390,6 @@ E00000-EFFFFF (base 16) BAYCOM OPTO-ELECTRONICS TECHNOLGY CO., LTD. HONG kONG 00852
HK
-50-FF-99 (hex) metraTec GmbH
-A00000-AFFFFF (base 16) metraTec GmbH
- Werner-Heisenberg-Str. 1
- Magdeburg Sachsen-Anh. 39106
- DE
-
50-FF-99 (hex) Informa LLC
E00000-EFFFFF (base 16) Informa LLC
215 N. College Ave
@@ -6218,6 +6389,66 @@ F8-B5-68 (hex) Combiwins Technology Co.,Limited Chennai Tamilnadu 600035
IN
+30-1F-9A (hex) CHISON Medical Technologies Co., Ltd.
+200000-2FFFFF (base 16) CHISON Medical Technologies Co., Ltd.
+ No.9, Xinhuihuan Road, Xinwu District, Wuxi, Jiangsu, China 214028
+ WUXI JIANGSU 214028
+ CN
+
+30-1F-9A (hex) Origami Group Limited
+C00000-CFFFFF (base 16) Origami Group Limited
+ Unit 913, 9/F.,Tower 2 Cheung Sha Wan Plaza, 833 Cheung Sha Wan Road, Kowloon
+ Hong Kong 000000
+ HK
+
+30-1F-9A (hex) Beijing Surestar Technology Co. Ltd,
+500000-5FFFFF (base 16) Beijing Surestar Technology Co. Ltd,
+ Room 502, building 1, No. 5 Yongfeng Road, Haidian District
+ Beijing 100089
+ CN
+
+30-1F-9A (hex) HUNAN CHANGSHA HENGJIAN TECHNOLDGY DEVELPMENT CO.,LTD.
+A00000-AFFFFF (base 16) HUNAN CHANGSHA HENGJIAN TECHNOLDGY DEVELPMENT CO.,LTD.
+ Jiayun Road 209
+ Changsha Hunan 410205
+ CN
+
+88-5F-E8 (hex) Shenzhen ORVIBO Technology Co., Ltd
+B00000-BFFFFF (base 16) Shenzhen ORVIBO Technology Co., Ltd
+ 7F, A7 Zhiyuan, No.1001, Xueyuan AV., Nanshan district, Shenzhen,518055,PRC
+ Shenzhen guangdong 518000
+ CN
+
+50-FF-99 (hex) metraTec GmbH
+A00000-AFFFFF (base 16) metraTec GmbH
+ Niels-Bohr-Str. 5
+ Magdeburg Sachsen-Anh. 39106
+ DE
+
+48-0B-B2 (hex) Beijing Dragon Resources Limited.
+700000-7FFFFF (base 16) Beijing Dragon Resources Limited.
+ Tongjunzhuangxinlukou (500meters east) Shilipu Town, MiyunCountry, Beijing101500, China
+ BeiJing 101500
+ CN
+
+0C-73-EB (hex) Tiinlab Acoustic Technology (Shenzhen) Co., Ltd.
+300000-3FFFFF (base 16) Tiinlab Acoustic Technology (Shenzhen) Co., Ltd.
+ Tianliao Building F14 East Block (New Materials Industrial Park), Xueyuan Road, Nanshan District,
+ Shenzhen Guangdong 518055
+ CN
+
+0C-73-EB (hex) Husty M.Styczen J.Hupert Sp.J.
+500000-5FFFFF (base 16) Husty M.Styczen J.Hupert Sp.J.
+ Rzepakowa 5e
+ Krakow malopolska 31-989
+ PL
+
+3C-24-F0 (hex) Travis Holding B.V.
+D00000-DFFFFF (base 16) Travis Holding B.V.
+ Stationsplein 45, A4.002 3013 AK
+ Rotterdam 3013AK
+ NL
+
28-2C-02 (hex) SHENZHEN DOMENOR TECHNOLOGY LLC
D00000-DFFFFF (base 16) SHENZHEN DOMENOR TECHNOLOGY LLC
F4, BUILDING A3, SILICON VALLEY POWER TECHNOLOGY PARK, SILI ROAD, KUKENG COMMUNITY, GUANLAN TOWN,LONGHUA DISTRICT
@@ -6368,6 +6599,54 @@ E00000-EFFFFF (base 16) Impact Distribution Herzelia 4673335
IL
+F0-41-C8 (hex) Candelic Limited
+400000-4FFFFF (base 16) Candelic Limited
+ Unit 312, 3/F Solo Workshop, 131-132 Cannaught Road West
+ Hong Kong 111111
+ HK
+
+F0-41-C8 (hex) POSTIUM KOREA CO., LTD.
+800000-8FFFFF (base 16) POSTIUM KOREA CO., LTD.
+ A208 Samsong Techno Valley, 140 Tongil-ro, Deogyang-gu
+ Koyang-si Kyeonggi-do 10594
+ KR
+
+88-5F-E8 (hex) Beijing laiwei Technology Co.,Ltd
+400000-4FFFFF (base 16) Beijing laiwei Technology Co.,Ltd
+ Room 205,2/F,No.1 Fazhan Road Beijing information international base Huilongguan town Changping district Beijing
+ Beijing Beijing 102206
+ CN
+
+88-5F-E8 (hex) Shenzhen Xin Kingbrand Enterprises Co.,Ltd
+600000-6FFFFF (base 16) Shenzhen Xin Kingbrand Enterprises Co.,Ltd
+ KingBrand Industrial Zone, Nanpu Road,Shang Liao Lin Pikeng,Shajing Town,Baoan District
+ Shenzhen 518000
+ CN
+
+48-0B-B2 (hex) annapurnalabs
+600000-6FFFFF (base 16) annapurnalabs
+ HACRMEL 2 st Brosh BLDG FLOOR3
+ YOKNEAM. POB 218 Israel 26814
+ IL
+
+48-0B-B2 (hex) BAJA ELECTRONICS TECHNOLOGY LIMITED
+100000-1FFFFF (base 16) BAJA ELECTRONICS TECHNOLOGY LIMITED
+ 403, Unit 3, Building 3, Zhongdian Hi-Tech Park, No.1 Kejiqi Rd.
+ Zhuhai Guangdong 519080
+ CN
+
+0C-73-EB (hex) Dinkle Enterprise Co., Ltd.
+700000-7FFFFF (base 16) Dinkle Enterprise Co., Ltd.
+ No.19, Wuquan 2nd Rd., Wugu Dist.
+ New Taipei City 24890
+ TW
+
+3C-24-F0 (hex) COMATIS
+B00000-BFFFFF (base 16) COMATIS
+ 8 rue Carnot
+ SAINT-CYR-L'ECOLE 78210
+ FR
+
1C-87-76 (hex) Hekatron Vertriebs GmbH
B00000-BFFFFF (base 16) Hekatron Vertriebs GmbH
Brühlmatten 9
@@ -8441,11 +8720,17 @@ C4-FF-BC (hex) VISATECH C0., LTD. Geumcheon-gu Seoul 08507
KR
-DC-E5-33 (hex) Tiertime Corporation
-900000-9FFFFF (base 16) Tiertime Corporation
- 2398 Walsh Avenue
- Santa Clara CA 95051
- US
+DC-E5-33 (hex) Ambi Labs Limited
+100000-1FFFFF (base 16) Ambi Labs Limited
+ 1903, 19/F, Loon Lee Building, 267-275 Des Voeux Road Central., Sheung Wan, Hong Kong
+ Hong Kong Hong Kong 00000
+ HK
+
+DC-E5-33 (hex) Remko GmbH & Co. KG
+200000-2FFFFF (base 16) Remko GmbH & Co. KG
+ Im Seelenkamp 12
+ Lage 32791
+ DE
A4-DA-22 (hex) Hydro Electronic Devices, Inc.
700000-7FFFFF (base 16) Hydro Electronic Devices, Inc.
@@ -8453,32 +8738,62 @@ A4-DA-22 (hex) Hydro Electronic Devices, Inc. Hartford WI 53027
US
-2C-26-5F (hex) Private
+A0-BB-3E (hex) Private
F00000-FFFFFF (base 16) Private
-28-FD-80 (hex) Private
-F00000-FFFFFF (base 16) Private
+88-A9-A7 (hex) Shenzhenshi kechuangzhixian technology Co.LTD
+000000-0FFFFF (base 16) Shenzhenshi kechuangzhixian technology Co.LTD
+ Room 14G,14th Floor, Langshi Building , keji South Road 12 , High-tech Industrial Park , Nanshan District
+ Shenzhen 518000
+ CN
-A0-BB-3E (hex) Private
-F00000-FFFFFF (base 16) Private
+88-A9-A7 (hex) TWK-ELEKTRONIK
+B00000-BFFFFF (base 16) TWK-ELEKTRONIK
+ Heinrichstr. 85
+ Duesseldorf 40239
+ DE
-F0-41-C8 (hex) ATN Media Group FZ LLC
-D00000-DFFFFF (base 16) ATN Media Group FZ LLC
- Business Bay-alabrj st Business Towar By Damac.office-807
- Dubai 25051
- AE
+88-A9-A7 (hex) psb intralogistics GmbH
+800000-8FFFFF (base 16) psb intralogistics GmbH
+ Blocksbergstrasse 145
+ Pirmasens 66955
+ DE
-F0-41-C8 (hex) XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd.
-500000-5FFFFF (base 16) XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd.
- Xi'an Beilin District Yanta Middle Road No. 17A XIN QING YA YUAN 2-5C
- XI'AN shanxi 710000
+F0-41-C8 (hex) Nanchang BlackShark Co.,Ltd.
+700000-7FFFFF (base 16) Nanchang BlackShark Co.,Ltd.
+ Room 319, Jiaoqiao Town Office Building, Economic and Technical development zone, Nanchang City, Jiangxi Province.
+ Nanchang 330013
CN
-F0-41-C8 (hex) AED Engineering GmbH
-600000-6FFFFF (base 16) AED Engineering GmbH
- Taunusstr. 51
- Munich Bavaria 80807
- DE
+88-5F-E8 (hex) Hauch & Bach ApS
+500000-5FFFFF (base 16) Hauch & Bach ApS
+ Femstykket 6
+ Lynge 3540
+ DK
+
+0C-73-EB (hex) Beijing Miiiw Technology Co., Ltd
+800000-8FFFFF (base 16) Beijing Miiiw Technology Co., Ltd
+ Room 3008, 3rd Floor, Qunfang Building, Bowangyuan, Yangfangdian Rd, Haidian District
+ Beijing 100010
+ CN
+
+0C-73-EB (hex) Deltapath, Inc.
+200000-2FFFFF (base 16) Deltapath, Inc.
+ 2107 N 1ST ST, STE 660
+ San Jose CA 95131
+ US
+
+0C-73-EB (hex) D-Link (Shanghai)Limited Corp.
+D00000-DFFFFF (base 16) D-Link (Shanghai)Limited Corp.
+ Registered Address: Part J1, Floor 1, Building 2, No.115, Fute West First Road, China(Shanghai) Pilot Free Trade Zone
+ Shanghai 200000
+ CN
+
+0C-73-EB (hex) U-PASS.CO.,LTD
+400000-4FFFFF (base 16) U-PASS.CO.,LTD
+ HANEULMAEUL-RO
+ GYEONGGI-DO GOYANG-SI,ILSANDONG-GU 410315
+ KR
34-D0-B8 (hex) Kongqiguanjia (Beijing)Technology co.,ltd
E00000-EFFFFF (base 16) Kongqiguanjia (Beijing)Technology co.,ltd
@@ -8564,17 +8879,11 @@ F8-B5-68 (hex) Beijing Wanji Techonology Co., Ltd. Hsinchu City Taiwan 300
TW
-DC-E5-33 (hex) Ambi Labs Limited
-100000-1FFFFF (base 16) Ambi Labs Limited
- 1903, 19/F, Loon Lee Building, 267-275 Des Voeux Road Central., Sheung Wan, Hong Kong
- Hong Kong Hong Kong 00000
- HK
-
-DC-E5-33 (hex) Remko GmbH & Co. KG
-200000-2FFFFF (base 16) Remko GmbH & Co. KG
- Im Seelenkamp 12
- Lage 32791
- DE
+DC-E5-33 (hex) Tiertime Corporation
+900000-9FFFFF (base 16) Tiertime Corporation
+ 2398 Walsh Avenue
+ Santa Clara CA 95051
+ US
A4-DA-22 (hex) SolidPro Technology Corporation
800000-8FFFFF (base 16) SolidPro Technology Corporation
@@ -8588,28 +8897,70 @@ A4-DA-22 (hex) Original Products Pvt. Ltd. New Delhi New Delhi 110062
IN
-88-A9-A7 (hex) Shenzhenshi kechuangzhixian technology Co.LTD
-000000-0FFFFF (base 16) Shenzhenshi kechuangzhixian technology Co.LTD
- Room 14G,14th Floor, Langshi Building , keji South Road 12 , High-tech Industrial Park , Nanshan District
- Shenzhen 518000
+2C-26-5F (hex) Private
+F00000-FFFFFF (base 16) Private
+
+28-FD-80 (hex) Private
+F00000-FFFFFF (base 16) Private
+
+F0-41-C8 (hex) ATN Media Group FZ LLC
+D00000-DFFFFF (base 16) ATN Media Group FZ LLC
+ Business Bay-alabrj st Business Towar By Damac.office-807
+ Dubai 25051
+ AE
+
+F0-41-C8 (hex) XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd.
+500000-5FFFFF (base 16) XI'AN MEI SHANG MEI WIRELESS TECHNOLOGY.Co., Ltd.
+ Xi'an Beilin District Yanta Middle Road No. 17A XIN QING YA YUAN 2-5C
+ XI'AN shanxi 710000
CN
-88-A9-A7 (hex) TWK-ELEKTRONIK
-B00000-BFFFFF (base 16) TWK-ELEKTRONIK
- Heinrichstr. 85
- Duesseldorf 40239
+F0-41-C8 (hex) AED Engineering GmbH
+600000-6FFFFF (base 16) AED Engineering GmbH
+ Taunusstr. 51
+ Munich Bavaria 80807
DE
-88-A9-A7 (hex) psb intralogistics GmbH
-800000-8FFFFF (base 16) psb intralogistics GmbH
- Blocksbergstrasse 145
- Pirmasens 66955
- DE
+30-1F-9A (hex) Dewesoft d.o.o.
+100000-1FFFFF (base 16) Dewesoft d.o.o.
+ Gabrsko 11a
+ Trbovlje 1420
+ SI
-F0-41-C8 (hex) Nanchang BlackShark Co.,Ltd.
-700000-7FFFFF (base 16) Nanchang BlackShark Co.,Ltd.
- Room 319, Jiaoqiao Town Office Building, Economic and Technical development zone, Nanchang City, Jiangxi Province.
- Nanchang 330013
+30-1F-9A (hex) OLIMEX Ltd
+D00000-DFFFFF (base 16) OLIMEX Ltd
+ 2 Pravda
+ Plovidv 4000
+ BG
+
+48-0B-B2 (hex) Popit Oy
+B00000-BFFFFF (base 16) Popit Oy
+ Metsänneidonkuja 6
+ Espoo 02130
+ FI
+
+48-0B-B2 (hex) BravoCom(xiamen)TechCo.Ltd
+800000-8FFFFF (base 16) BravoCom(xiamen)TechCo.Ltd
+ Room 506, Chengye Building lnnovation park Xiamen Torch Hi-Tech Zone Xiamen fujian P.R.China
+ Xiamen fujian 361000
+ CN
+
+48-0B-B2 (hex) Hangzhou Freely Communication Co., Ltd.
+400000-4FFFFF (base 16) Hangzhou Freely Communication Co., Ltd.
+ No. 90 Wensan, Hangzhou, Zhejiang
+ Hangzhou Zhejiang 310012
+ CN
+
+48-0B-B2 (hex) Microprogram Information Co., Ltd
+900000-9FFFFF (base 16) Microprogram Information Co., Ltd
+ 14F., No.262, Sec. 2, Henan Rd., Xitun Dist.
+ Taichung 407
+ TW
+
+3C-24-F0 (hex) SHENZHEN PINSIDA TECHNOLOGY CO.,LTD.
+000000-0FFFFF (base 16) SHENZHEN PINSIDA TECHNOLOGY CO.,LTD.
+ 411,4/F,Building A,Pengnian Science Park,Honghua IV Road,Xili,Nanshan District
+ Shenzhen Guangdong 518000
CN
1C-87-74 (hex) Philips Personal Health Solutions
@@ -9884,6 +10235,309 @@ D00000-DFFFFF (base 16) Hangzhou GANX Technology Co.,Ltd. Guangzhou Guangdong 510555
CN
+AC-1D-DF (hex) WESCO INTEGRATED SUPPLY
+A00000-AFFFFF (base 16) WESCO INTEGRATED SUPPLY
+ 36 HARBOR PARK DRIVE
+ PORT WASHINGTON NY 11050
+ US
+
+AC-1D-DF (hex) Solare Datensysteme GmbH
+900000-9FFFFF (base 16) Solare Datensysteme GmbH
+ Fuhrmannstraße 9
+ Geislingen-Binsdorf Baden-Wuerttemberg 72351
+ DE
+
+80-0A-80 (hex) Private
+F00000-FFFFFF (base 16) Private
+
+34-D0-B8 (hex) OROSOUND SAS
+B00000-BFFFFF (base 16) OROSOUND SAS
+ 48 RUE AMELOT
+ PARIS 75011
+ FR
+
+34-D0-B8 (hex) Glory Mark Electronic Ltd. Taiwan Branch (B.V.I.)
+C00000-CFFFFF (base 16) Glory Mark Electronic Ltd. Taiwan Branch (B.V.I.)
+ 3F, No. 6, Lane 148, Li De St., Chungho Dist.
+ New Taipei City Taiwan 235
+ TW
+
+34-D0-B8 (hex) Tascent, Inc.
+300000-3FFFFF (base 16) Tascent, Inc.
+ 475 Alberto Way, Suite #200
+ Los Gatos CA 95032
+ US
+
+34-D0-B8 (hex) NumberFour AG
+600000-6FFFFF (base 16) NumberFour AG
+ Schoenhauser Allee 8
+ Berlin 10119
+ DE
+
+EC-9F-0D (hex) WisIOE
+400000-4FFFFF (base 16) WisIOE
+ Room 601, Hongyuan Building, Baoyuan Road, Xixiang Street, Baoan District
+ Shenzhen Guangdong 518000
+ CN
+
+EC-9F-0D (hex) Sarcos Corp
+C00000-CFFFFF (base 16) Sarcos Corp
+ 360 S Wakara Way
+ Salt Lake City UT 84108
+ US
+
+EC-9F-0D (hex) Zhejiang HEJU Communication Technology Co., Ltd
+800000-8FFFFF (base 16) Zhejiang HEJU Communication Technology Co., Ltd
+ F4,Block B, Lotus Commercial Building,Lianhua Street 333#,XiHu District
+ HANGZHOU ZHEJIANG 310012
+ CN
+
+38-73-EA (hex) ISTCONTROL
+500000-5FFFFF (base 16) ISTCONTROL
+ #1203, 37 Maebongsan-ro, Mapo-gu
+ Seoul 03909
+ KR
+
+38-73-EA (hex) LG Electronics
+C00000-CFFFFF (base 16) LG Electronics
+ 51, Gasan Digital1-ro, Geumcheon-gu
+ Seoul 08592
+ KR
+
+38-73-EA (hex) KingWay Information Co.,Ltd.
+100000-1FFFFF (base 16) KingWay Information Co.,Ltd.
+ 3/F Rongxin business organization #56 Jinyan Road
+ Fuzhou Fujian 350000
+ CN
+
+38-73-EA (hex) Lightform, Inc.
+900000-9FFFFF (base 16) Lightform, Inc.
+ 123 Langton St.
+ San Francisco CA 94103
+ US
+
+40-48-FD (hex) RL Controls LLC.
+300000-3FFFFF (base 16) RL Controls LLC.
+ 2 G Gill St
+ Woburn MA 01801
+ US
+
+40-48-FD (hex) BEIJING C&W ELECTRONICS(GROUP)CO.,LTD
+000000-0FFFFF (base 16) BEIJING C&W ELECTRONICS(GROUP)CO.,LTD
+ No.14 Jiuxianqiao,chaoyang,Beijing,China
+ Beijing Beijing 100015
+ CN
+
+40-48-FD (hex) Shenzhen Yifang Digital Technology Co., LTD.
+A00000-AFFFFF (base 16) Shenzhen Yifang Digital Technology Co., LTD.
+ Building NO. 23, Fifth Region, Baiwangxin Industrial Park, Songbai Rd. Nanshan, Shenzhen
+ Shenzhen 518108
+ CN
+
+40-48-FD (hex) Plus One Global Ltd.
+900000-9FFFFF (base 16) Plus One Global Ltd.
+ 2-8-6,Nishishinbashi
+ Minato-ku Tokyo 105-0003
+ JP
+
+F8-B5-68 (hex) etectRx
+500000-5FFFFF (base 16) etectRx
+ 107 SW 140th Terr., Ste. 1
+ Newberry FL 32669
+ US
+
+40-48-FD (hex) SMART SENSOR DEVICES AB
+E00000-EFFFFF (base 16) SMART SENSOR DEVICES AB
+ Sollentunavägen 67A
+ Sollentuna Stockholm 19140
+ SE
+
+F8-B5-68 (hex) LifePrint Products, Inc.
+000000-0FFFFF (base 16) LifePrint Products, Inc.
+ 4667 Golden Foothill Parkway, Suite 102
+ El Dorado Hills CA 95762
+ US
+
+F8-B5-68 (hex) SinePulse GmbH
+A00000-AFFFFF (base 16) SinePulse GmbH
+ Kistlerhofstr. 170
+ Munich D-81379
+ DE
+
+28-2C-02 (hex) Shenzhen emb-star technology co. LTD
+200000-2FFFFF (base 16) Shenzhen emb-star technology co. LTD
+ 2/f,building C,qinghu science park,qingxiang road,qinghu,longhua new district
+ shenzhen Guangdong 518131
+ CN
+
+A4-4F-29 (hex) Private
+F00000-FFFFFF (base 16) Private
+
+0C-EF-AF (hex) Private
+F00000-FFFFFF (base 16) Private
+
+28-2C-02 (hex) EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA
+400000-4FFFFF (base 16) EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA
+ Dietla 93/6
+ Kraków 31-031
+ PL
+
+28-2C-02 (hex) Capintec, Inc.
+E00000-EFFFFF (base 16) Capintec, Inc.
+ 7 Vreeland Road
+ Florham Park NJ 07932
+ US
+
+9C-43-1E (hex) R-S-I Elektrotechnik GmbH CO KG
+600000-6FFFFF (base 16) R-S-I Elektrotechnik GmbH CO KG
+ Woelkestrasse 11
+ Schweitenkirchen 85276
+ DE
+
+9C-43-1E (hex) CONTINENT Co. Ltd
+900000-9FFFFF (base 16) CONTINENT Co. Ltd
+ Bumazhnaya st., 16/3 lit B, of. 414
+ Saint-Petersburg 190020
+ RU
+
+9C-43-1E (hex) SuZhou Jinruiyang Information Technology CO.,LTD
+C00000-CFFFFF (base 16) SuZhou Jinruiyang Information Technology CO.,LTD
+ NO.1003 Room A1 Buliding Tengfei Business Park in Suzhou Industrial Park.
+ Suzhou Jiangsu 215123
+ CN
+
+9C-43-1E (hex) JNL Technologies Inc
+B00000-BFFFFF (base 16) JNL Technologies Inc
+ W1205 Industrial Dr
+ Ixonia WI 53036
+ US
+
+9C-43-1E (hex) Midas Technology DBA Phoenix Audio Technologies
+E00000-EFFFFF (base 16) Midas Technology DBA Phoenix Audio Technologies
+ 16 Goodyear #120
+ Irvine CA 92618
+ US
+
+C4-FF-BC (hex) Advanced Navigation
+A00000-AFFFFF (base 16) Advanced Navigation
+ Level 8, 37 Pitt Street
+ Sydney NSW 2000
+ AU
+
+DC-E5-33 (hex) ShenZhen C&D Electronics CO.Ltd.
+300000-3FFFFF (base 16) ShenZhen C&D Electronics CO.Ltd.
+ 9th FIoor, Building 9, No.1 Qingxiang road, BaoNeng Science and TechnoIogy Industrial Park, Longhua New District
+ ShenZhen GuangDong 518000
+ CN
+
+DC-E5-33 (hex) WECAN Solution Inc.
+600000-6FFFFF (base 16) WECAN Solution Inc.
+ 71, Yulhadong-ro 8-gil, Dong-gu, Daegu, Republic of Korea
+ Daegu 41102
+ KR
+
+DC-E5-33 (hex) BRCK
+C00000-CFFFFF (base 16) BRCK
+ PO Box 58275-00200, 2nd Floor Bishop Magua Center, George Padmore Lane, 2nd Floor Bishop Magua Center, George Padmore Lane
+ Nairobi Nairobi 00200
+ KE
+
+A4-DA-22 (hex) Malldon Technology Limited
+900000-9FFFFF (base 16) Malldon Technology Limited
+ 607 Longsheng Technology Building, Longhua Dist
+ Shenzhen Guangdong 518000
+ CN
+
+88-A9-A7 (hex) AVLINK INDUSTRIAL CO., LTD
+D00000-DFFFFF (base 16) AVLINK INDUSTRIAL CO., LTD
+ 7/F, A1 Bldg, 1st Shuichanjingwan Industrial Park, Nanchang Village, Gushu, Bao'an Dist
+ Shenzhen Guangdong 518126
+ CN
+
+88-A9-A7 (hex) Volterman Inc.
+500000-5FFFFF (base 16) Volterman Inc.
+ Suite B2, Sunset Lake Road
+ Newark DE 19702
+ US
+
+F0-41-C8 (hex) Powervault Ltd
+B00000-BFFFFF (base 16) Powervault Ltd
+ 29 Shand Street, London Bridge
+ London SE1 2ES
+ GB
+
+F0-41-C8 (hex) Telstra
+A00000-AFFFFF (base 16) Telstra
+ 231 Elisabeth St
+ SYDNEY NSW 2000
+ AU
+
+30-1F-9A (hex) Smart Component Technologies LTD
+B00000-BFFFFF (base 16) Smart Component Technologies LTD
+ Cooper Buildings, Arundel Street
+ Sheffield South Yorkshire S1 2NS
+ GB
+
+30-1F-9A (hex) NCM Supplies, Inc.
+400000-4FFFFF (base 16) NCM Supplies, Inc.
+ 8125 NW 64th Street
+ Miami FL 33166
+ US
+
+30-1F-9A (hex) MICOMSOFT CO.,LTD.
+300000-3FFFFF (base 16) MICOMSOFT CO.,LTD.
+ 6F,KEIHAN-YODOYABASHI BLDG., 3-2-25,KITAHAMA,CHUO-KU
+ osaka 541-0041
+ JP
+
+30-1F-9A (hex) Triax A/S
+700000-7FFFFF (base 16) Triax A/S
+ Bjornkaervej 3
+ Hornsyld Denmark 8783
+ DK
+
+30-1F-9A (hex) FINE TRIUMPH TECHNOLOGY CORP.,LTD.
+800000-8FFFFF (base 16) FINE TRIUMPH TECHNOLOGY CORP.,LTD.
+ Xixiang
+ Shenzhen Guangdong 518126
+ CN
+
+88-5F-E8 (hex) Inor Process AB
+C00000-CFFFFF (base 16) Inor Process AB
+ Travbanegatan 10
+ Malmo Skane SE-213 77
+ SE
+
+88-5F-E8 (hex) Red Technologies, LLC.
+700000-7FFFFF (base 16) Red Technologies, LLC.
+ 34 Parker
+ Irvine CA 92618
+ US
+
+48-0B-B2 (hex) XIAMEN RONGTA TECHNOLOGY CO.,LTD.
+A00000-AFFFFF (base 16) XIAMEN RONGTA TECHNOLOGY CO.,LTD.
+ 3F, E Plant, Gaoqi Industrial Zones, No.195, Gaoqi Community, Gaodian Village, Huli
+ Xiamen 361000
+ CN
+
+88-5F-E8 (hex) Unicom Global, Inc.
+E00000-EFFFFF (base 16) Unicom Global, Inc.
+ 581, Ruiguang Road, Neihu Dist.
+ Taipei 11492
+ TW
+
+48-0B-B2 (hex) shanghai Rinlink Intelligent Technology Co., Ltd.
+300000-3FFFFF (base 16) shanghai Rinlink Intelligent Technology Co., Ltd.
+ Room1510,ROAD Xiuwen,Minhang District
+ shanghai 201100
+ CN
+
+48-0B-B2 (hex) Ridango AS
+000000-0FFFFF (base 16) Ridango AS
+ Pärnu maantee 139E/13
+ Tallinn Harjumaa 11317
+ EE
+
34-04-9E (hex) Eclipse Information Technologies
800000-8FFFFF (base 16) Eclipse Information Technologies
Gulsuyu Mah. Fevzi Cakmak Cad Lefke Sk 16/6
@@ -10475,233 +11129,32 @@ E00000-EFFFFF (base 16) MANUFACTURAS Y TRANSFORMADOS AB, S.L. Eindhoven 5656 AE
NL
-AC-1D-DF (hex) WESCO INTEGRATED SUPPLY
-A00000-AFFFFF (base 16) WESCO INTEGRATED SUPPLY
- 36 HARBOR PARK DRIVE
- PORT WASHINGTON NY 11050
- US
-
-AC-1D-DF (hex) Solare Datensysteme GmbH
-900000-9FFFFF (base 16) Solare Datensysteme GmbH
- Fuhrmannstraße 9
- Geislingen-Binsdorf Baden-Wuerttemberg 72351
- DE
-
-80-0A-80 (hex) Private
-F00000-FFFFFF (base 16) Private
-
-34-D0-B8 (hex) OROSOUND SAS
-B00000-BFFFFF (base 16) OROSOUND SAS
- 48 RUE AMELOT
- PARIS 75011
- FR
-
-34-D0-B8 (hex) Glory Mark Electronic Ltd. Taiwan Branch (B.V.I.)
-C00000-CFFFFF (base 16) Glory Mark Electronic Ltd. Taiwan Branch (B.V.I.)
- 3F, No. 6, Lane 148, Li De St., Chungho Dist.
- New Taipei City Taiwan 235
- TW
-
-34-D0-B8 (hex) Tascent, Inc.
-300000-3FFFFF (base 16) Tascent, Inc.
- 475 Alberto Way, Suite #200
- Los Gatos CA 95032
- US
-
-34-D0-B8 (hex) NumberFour AG
-600000-6FFFFF (base 16) NumberFour AG
- Schoenhauser Allee 8
- Berlin 10119
- DE
-
-EC-9F-0D (hex) WisIOE
-400000-4FFFFF (base 16) WisIOE
- Room 601, Hongyuan Building, Baoyuan Road, Xixiang Street, Baoan District
- Shenzhen Guangdong 518000
- CN
-
-EC-9F-0D (hex) Sarcos Corp
-C00000-CFFFFF (base 16) Sarcos Corp
- 360 S Wakara Way
- Salt Lake City UT 84108
- US
-
-EC-9F-0D (hex) Zhejiang HEJU Communication Technology Co., Ltd
-800000-8FFFFF (base 16) Zhejiang HEJU Communication Technology Co., Ltd
- F4,Block B, Lotus Commercial Building,Lianhua Street 333#,XiHu District
- HANGZHOU ZHEJIANG 310012
- CN
-
-38-73-EA (hex) ISTCONTROL
-500000-5FFFFF (base 16) ISTCONTROL
- #1203, 37 Maebongsan-ro, Mapo-gu
- Seoul 03909
- KR
-
-38-73-EA (hex) LG Electronics
-C00000-CFFFFF (base 16) LG Electronics
- 51, Gasan Digital1-ro, Geumcheon-gu
- Seoul 08592
- KR
-
-38-73-EA (hex) KingWay Information Co.,Ltd.
-100000-1FFFFF (base 16) KingWay Information Co.,Ltd.
- 3/F Rongxin business organization #56 Jinyan Road
- Fuzhou Fujian 350000
- CN
-
-38-73-EA (hex) Lightform, Inc.
-900000-9FFFFF (base 16) Lightform, Inc.
- 123 Langton St.
- San Francisco CA 94103
- US
+48-0B-B2 (hex) Solaredge LTD.
+500000-5FFFFF (base 16) Solaredge LTD.
+ Hamada 1
+ Herzelia 4673335
+ IL
-40-48-FD (hex) RL Controls LLC.
-300000-3FFFFF (base 16) RL Controls LLC.
- 2 G Gill St
- Woburn MA 01801
+0C-73-EB (hex) Synaccess Networks
+B00000-BFFFFF (base 16) Synaccess Networks
+ 14425 N 79th St., Suite C
+ Scottsdale AZ 85260
US
-40-48-FD (hex) BEIJING C&W ELECTRONICS(GROUP)CO.,LTD
-000000-0FFFFF (base 16) BEIJING C&W ELECTRONICS(GROUP)CO.,LTD
- No.14 Jiuxianqiao,chaoyang,Beijing,China
- Beijing Beijing 100015
- CN
-
-40-48-FD (hex) Shenzhen Yifang Digital Technology Co., LTD.
-A00000-AFFFFF (base 16) Shenzhen Yifang Digital Technology Co., LTD.
- Building NO. 23, Fifth Region, Baiwangxin Industrial Park, Songbai Rd. Nanshan, Shenzhen
- Shenzhen 518108
- CN
+0C-73-EB (hex) Taiwan Pulse Motion Co., Ltd.
+E00000-EFFFFF (base 16) Taiwan Pulse Motion Co., Ltd.
+ 5F.-11, No. 210, Gongyequ 38th Rd.
+ Taichung City 40768
+ TW
-40-48-FD (hex) Plus One Global Ltd.
-900000-9FFFFF (base 16) Plus One Global Ltd.
- 2-8-6,Nishishinbashi
- Minato-ku Tokyo 105-0003
+3C-24-F0 (hex) Inter Action Corporation
+600000-6FFFFF (base 16) Inter Action Corporation
+ 14F,Yokohama-Kanazawa High-Tech Center,1-1,
+ Yokohama Kanagawa 236-0004
JP
-F8-B5-68 (hex) etectRx
-500000-5FFFFF (base 16) etectRx
- 107 SW 140th Terr., Ste. 1
- Newberry FL 32669
- US
-
-40-48-FD (hex) SMART SENSOR DEVICES AB
-E00000-EFFFFF (base 16) SMART SENSOR DEVICES AB
- Sollentunavägen 67A
- Sollentuna Stockholm 19140
- SE
-
-F8-B5-68 (hex) LifePrint Products, Inc.
-000000-0FFFFF (base 16) LifePrint Products, Inc.
- 4667 Golden Foothill Parkway, Suite 102
- El Dorado Hills CA 95762
- US
-
-F8-B5-68 (hex) SinePulse GmbH
-A00000-AFFFFF (base 16) SinePulse GmbH
- Kistlerhofstr. 170
- Munich D-81379
- DE
-
-28-2C-02 (hex) Shenzhen emb-star technology co. LTD
-200000-2FFFFF (base 16) Shenzhen emb-star technology co. LTD
- 2/f,building C,qinghu science park,qingxiang road,qinghu,longhua new district
- shenzhen Guangdong 518131
- CN
-
-A4-4F-29 (hex) Private
-F00000-FFFFFF (base 16) Private
-
-0C-EF-AF (hex) Private
-F00000-FFFFFF (base 16) Private
-
-28-2C-02 (hex) EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA
-400000-4FFFFF (base 16) EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA
- Dietla 93/6
- Kraków 31-031
- PL
-
-28-2C-02 (hex) Capintec, Inc.
-E00000-EFFFFF (base 16) Capintec, Inc.
- 7 Vreeland Road
- Florham Park NJ 07932
- US
-
-9C-43-1E (hex) R-S-I Elektrotechnik GmbH CO KG
-600000-6FFFFF (base 16) R-S-I Elektrotechnik GmbH CO KG
- Woelkestrasse 11
- Schweitenkirchen 85276
- DE
-
-9C-43-1E (hex) CONTINENT Co. Ltd
-900000-9FFFFF (base 16) CONTINENT Co. Ltd
- Bumazhnaya st., 16/3 lit B, of. 414
- Saint-Petersburg 190020
- RU
-
-9C-43-1E (hex) SuZhou Jinruiyang Information Technology CO.,LTD
-C00000-CFFFFF (base 16) SuZhou Jinruiyang Information Technology CO.,LTD
- NO.1003 Room A1 Buliding Tengfei Business Park in Suzhou Industrial Park.
- Suzhou Jiangsu 215123
- CN
-
-9C-43-1E (hex) JNL Technologies Inc
-B00000-BFFFFF (base 16) JNL Technologies Inc
- W1205 Industrial Dr
- Ixonia WI 53036
- US
-
-9C-43-1E (hex) Midas Technology DBA Phoenix Audio Technologies
-E00000-EFFFFF (base 16) Midas Technology DBA Phoenix Audio Technologies
- 16 Goodyear #120
- Irvine CA 92618
- US
-
-C4-FF-BC (hex) Advanced Navigation
-A00000-AFFFFF (base 16) Advanced Navigation
- Level 8, 37 Pitt Street
- Sydney NSW 2000
- AU
-
-DC-E5-33 (hex) ShenZhen C&D Electronics CO.Ltd.
-300000-3FFFFF (base 16) ShenZhen C&D Electronics CO.Ltd.
- 9th FIoor, Building 9, No.1 Qingxiang road, BaoNeng Science and TechnoIogy Industrial Park, Longhua New District
- ShenZhen GuangDong 518000
- CN
-
-DC-E5-33 (hex) WECAN Solution Inc.
-600000-6FFFFF (base 16) WECAN Solution Inc.
- 71, Yulhadong-ro 8-gil, Dong-gu, Daegu, Republic of Korea
- Daegu 41102
- KR
-
-DC-E5-33 (hex) BRCK
-C00000-CFFFFF (base 16) BRCK
- PO Box 58275-00200, 2nd Floor Bishop Magua Center, George Padmore Lane, 2nd Floor Bishop Magua Center, George Padmore Lane
- Nairobi Nairobi 00200
- KE
-
-A4-DA-22 (hex) Malldon Technology Limited
-900000-9FFFFF (base 16) Malldon Technology Limited
- 607 Longsheng Technology Building, Longhua Dist
- Shenzhen Guangdong 518000
- CN
-
-88-A9-A7 (hex) AVLINK INDUSTRIAL CO., LTD
-D00000-DFFFFF (base 16) AVLINK INDUSTRIAL CO., LTD
- 7/F, A1 Bldg, 1st Shuichanjingwan Industrial Park, Nanchang Village, Gushu, Bao'an Dist
- Shenzhen Guangdong 518126
+3C-24-F0 (hex) Shenzhen Bestway Technology Co., Ltd
+A00000-AFFFFF (base 16) Shenzhen Bestway Technology Co., Ltd
+ 2nd Floor, Building 9, Jingxuan Industrial Park, East Ring Road, Longhua District,
+ Shenzhen GuangDong 518109
CN
-
-88-A9-A7 (hex) Volterman Inc.
-500000-5FFFFF (base 16) Volterman Inc.
- Suite B2, Sunset Lake Road
- Newark DE 19702
- US
-
-F0-41-C8 (hex) Powervault Ltd
-B00000-BFFFFF (base 16) Powervault Ltd
- 29 Shand Street, London Bridge
- London SE1 2ES
- GB
diff --git a/hwdb/ma-small.txt b/hwdb/ma-small.txt index 79b2cc672b..93d659d0bf 100644 --- a/hwdb/ma-small.txt +++ b/hwdb/ma-small.txt @@ -1187,12 +1187,6 @@ D86000-D86FFF (base 16) WPGSYS Pte Ltd Bridgewater NJ 08807
US
-00-1B-C5 (hex) Triax A/S
-08C000-08CFFF (base 16) Triax A/S
- Bjørnkærvej 3
- Hornsyld DK-8783
- DK
-
00-1B-C5 (hex) Seven Solutions S.L
090000-090FFF (base 16) Seven Solutions S.L
C/Baza, parcela 19,
@@ -2705,12 +2699,6 @@ EF7000-EF7FFF (base 16) DAVE SRL PORCIA PORDENONE 330850
IT
-70-B3-D5 (hex) Sierra Nevada Corporation
-252000-252FFF (base 16) Sierra Nevada Corporation
- 444 Salomon Circle
- Sparks NV 89434
- US
-
70-B3-D5 (hex) MANSION INDUSTRY CO., LTD.
734000-734FFF (base 16) MANSION INDUSTRY CO., LTD.
5F., No.6, Siwei Ln., Zhongzheng Rd., Xindian Dist.,
@@ -2771,72 +2759,6 @@ B6C000-B6CFFF (base 16) GHM-Messtechnik GmbH (Standort IMTRON) Kraków 31-031
PL
-70-B3-D5 (hex) KST technology
-351000-351FFF (base 16) KST technology
- KST B/D 4-5, Wiryeseong-daero 12-gil
- Songpa-gu Seoul 05636
- KR
-
-70-B3-D5 (hex) Vtron Pty Ltd
-15D000-15DFFF (base 16) Vtron Pty Ltd
- Unit 2, 62 Township Drive West
- West Burleigh Queensland 4219
- AU
-
-70-B3-D5 (hex) Vtron Pty Ltd
-341000-341FFF (base 16) Vtron Pty Ltd
- Unit 2, 62 Township Drive West
- West Burleigh Queensland 4219
- AU
-
-70-B3-D5 (hex) Kunshan excellent Intelligent Technology Co., Ltd.
-BE4000-BE4FFF (base 16) Kunshan excellent Intelligent Technology Co., Ltd.
- Room 2002 Site B Modern Square No 8 Wei yi Road
- kunshan Jiangsu Province 215301
- CN
-
-70-B3-D5 (hex) YUYAMA MFG Co.,Ltd
-E86000-E86FFF (base 16) YUYAMA MFG Co.,Ltd
- 3-3-1
- TOYONAKASHI OSAKA 561-0841
- JP
-
-70-B3-D5 (hex) QUANTAFLOW
-6EB000-6EBFFF (base 16) QUANTAFLOW
- AVENUE DU CANADA
- HONFLEUR 14600
- FR
-
-70-B3-D5 (hex) FLUDIA
-4A0000-4A0FFF (base 16) FLUDIA
- 4T rue honoré d'estienne d'orves
- Suresnes 92150
- FR
-
-70-B3-D5 (hex) OLEDCOMM
-A43000-A43FFF (base 16) OLEDCOMM
- 10-12 avenue de l'Europe
- Vélizy Villacoublay Ile de France 78140
- FR
-
-70-B3-D5 (hex) Peter Huber Kaeltemaschinenbau AG
-D7B000-D7BFFF (base 16) Peter Huber Kaeltemaschinenbau AG
- Werner-von-Siemens-Str. 1
- Offenburg Ba-Wue 77656
- DE
-
-70-B3-D5 (hex) TORGOVYY DOM TEHNOLOGIY LLC
-7C0000-7C0FFF (base 16) TORGOVYY DOM TEHNOLOGIY LLC
- The village of Rumyantsevo, Build.1
- Moscow Moscow 142784
- RU
-
-70-B3-D5 (hex) Cardinal Health
-75E000-75EFFF (base 16) Cardinal Health
- 444 McDonnell Blvd.
- Hazelwood MO 63042
- US
-
70-B3-D5 (hex) Matrix Orbital Corporation
2B7000-2B7FFF (base 16) Matrix Orbital Corporation
Suite 602, 4774 Westwinds Dr NE
@@ -2903,17 +2825,128 @@ DAA000-DAAFFF (base 16) AmTote Australasia Istanbul 34467
TR
+70-B3-D5 (hex) Zamir Recognition Systems Ltd.
+981000-981FFF (base 16) Zamir Recognition Systems Ltd.
+ Manachat Tech Park 1/22
+ Jerusalem 96951
+ IL
+
70-B3-D5 (hex) TRIDENT INFOSOL PVT LTD
C8F000-C8FFFF (base 16) TRIDENT INFOSOL PVT LTD
NO1A , KUSHAL GARDEN , PEENYA INDUSTRIAL AREA
BANGALORE 560058
IN
-70-B3-D5 (hex) Zamir Recognition Systems Ltd.
-981000-981FFF (base 16) Zamir Recognition Systems Ltd.
- Manachat Tech Park 1/22
- Jerusalem 96951
- IL
+70-B3-D5 (hex) Uplevel Systems Inc
+A13000-A13FFF (base 16) Uplevel Systems Inc
+ 6950 SW Hampton Street, Suite 308
+ Tigard OR 97223
+ US
+
+00-1B-C5 (hex) Triax A/S
+08C000-08CFFF (base 16) Triax A/S
+ Bjornkaervej 3
+ Hornsyld Denmark 8783
+ DK
+
+70-B3-D5 (hex) Sierra Nevada Corporation
+252000-252FFF (base 16) Sierra Nevada Corporation
+ 444 Salomon Circle
+ Sparks NV 89434
+ US
+
+70-B3-D5 (hex) X-SPEX GmbH
+D6F000-D6FFFF (base 16) X-SPEX GmbH
+ Albert-Einstein-Str. 14
+ Berlin Berlin 12489
+ DE
+
+70-B3-D5 (hex) KST technology
+351000-351FFF (base 16) KST technology
+ KST B/D 4-5, Wiryeseong-daero 12-gil
+ Songpa-gu Seoul 05636
+ KR
+
+70-B3-D5 (hex) Vtron Pty Ltd
+15D000-15DFFF (base 16) Vtron Pty Ltd
+ Unit 2, 62 Township Drive West
+ West Burleigh Queensland 4219
+ AU
+
+70-B3-D5 (hex) Vtron Pty Ltd
+341000-341FFF (base 16) Vtron Pty Ltd
+ Unit 2, 62 Township Drive West
+ West Burleigh Queensland 4219
+ AU
+
+70-B3-D5 (hex) Kunshan excellent Intelligent Technology Co., Ltd.
+BE4000-BE4FFF (base 16) Kunshan excellent Intelligent Technology Co., Ltd.
+ Room 2002 Site B Modern Square No 8 Wei yi Road
+ kunshan Jiangsu Province 215301
+ CN
+
+70-B3-D5 (hex) YUYAMA MFG Co.,Ltd
+E86000-E86FFF (base 16) YUYAMA MFG Co.,Ltd
+ 3-3-1
+ TOYONAKASHI OSAKA 561-0841
+ JP
+
+70-B3-D5 (hex) QUANTAFLOW
+6EB000-6EBFFF (base 16) QUANTAFLOW
+ AVENUE DU CANADA
+ HONFLEUR 14600
+ FR
+
+70-B3-D5 (hex) FLUDIA
+4A0000-4A0FFF (base 16) FLUDIA
+ 4T rue honoré d'estienne d'orves
+ Suresnes 92150
+ FR
+
+70-B3-D5 (hex) OLEDCOMM
+A43000-A43FFF (base 16) OLEDCOMM
+ 10-12 avenue de l'Europe
+ Vélizy Villacoublay Ile de France 78140
+ FR
+
+70-B3-D5 (hex) Peter Huber Kaeltemaschinenbau AG
+D7B000-D7BFFF (base 16) Peter Huber Kaeltemaschinenbau AG
+ Werner-von-Siemens-Str. 1
+ Offenburg Ba-Wue 77656
+ DE
+
+70-B3-D5 (hex) TORGOVYY DOM TEHNOLOGIY LLC
+7C0000-7C0FFF (base 16) TORGOVYY DOM TEHNOLOGIY LLC
+ The village of Rumyantsevo, Build.1
+ Moscow Moscow 142784
+ RU
+
+70-B3-D5 (hex) Cardinal Health
+75E000-75EFFF (base 16) Cardinal Health
+ 444 McDonnell Blvd.
+ Hazelwood MO 63042
+ US
+
+70-B3-D5 (hex) Private
+90E000-90EFFF (base 16) Private
+
+70-B3-D5 (hex) CoXlab Inc.
+DF1000-DF1FFF (base 16) CoXlab Inc.
+ 312 Hannuri-daero, 309
+ Sejong 30128
+ KR
+
+70-B3-D5 (hex) Verity Studios AG
+7AC000-7ACFFF (base 16) Verity Studios AG
+ Zürcherstrasse 39
+ Schlieren 8952
+ CH
+
+70-B3-D5 (hex) GSP Sprachtechnologie GmbH
+2A4000-2A4FFF (base 16) GSP Sprachtechnologie GmbH
+ Teltowkanalstraße 1
+ Berlin 12247
+ DE
70-B3-D5 (hex) Flintab AB
D60000-D60FFF (base 16) Flintab AB
@@ -4850,6 +4883,456 @@ D32000-D32FFF (base 16) Euklis by GSG International Trezzano sul Naviglio MI 20090
IT
+70-B3-D5 (hex) SHENZHEN GAONA ELECTRONIC CO.LTD
+031000-031FFF (base 16) SHENZHEN GAONA ELECTRONIC CO.LTD
+ F3.East block. Xinwu Industrial Building, Longzhu Road.Nanshan District
+ Shenzhen Guangdong China 518000
+ CN
+
+70-B3-D5 (hex) DIGIVERV INC
+548000-548FFF (base 16) DIGIVERV INC
+ 1515 Evanvale Dr
+ Allen TX 75013
+ US
+
+70-B3-D5 (hex) Globalcom Engineering SPA
+284000-284FFF (base 16) Globalcom Engineering SPA
+ Via Volta 39
+ CARDANO AL CAMPO VA 21010
+ IT
+
+70-B3-D5 (hex) Array Technologies Inc.
+A4E000-A4EFFF (base 16) Array Technologies Inc.
+ 21 Sequin Drive
+ Glastonbury 06033
+ US
+
+70-B3-D5 (hex) Private
+580000-580FFF (base 16) Private
+
+70-B3-D5 (hex) Alma
+BA9000-BA9FFF (base 16) Alma
+ 4A, Bd de la Gare, Porte 1
+ Boissy St Léger PACA 94470
+ FR
+
+70-B3-D5 (hex) Health Care Originals, Inc.
+2F2000-2F2FFF (base 16) Health Care Originals, Inc.
+ 1 Pleasant St., Ste. 442
+ Rochester NY 14604
+ US
+
+70-B3-D5 (hex) GSF Corporation Pte Ltd
+B98000-B98FFF (base 16) GSF Corporation Pte Ltd
+ 60 Paya Lebar Road
+ # 12-05 Paya Lebar Square 409051
+ SG
+
+70-B3-D5 (hex) Grossenbacher Systeme AG
+0DE000-0DEFFF (base 16) Grossenbacher Systeme AG
+ Spinnereistrasse 10
+ St. Gallen 9008
+ CH
+
+70-B3-D5 (hex) International Roll-Call Corporation
+4B8000-4B8FFF (base 16) International Roll-Call Corporation
+ 8346 Old Richfood Road
+ Mechanicsville VA 23116
+ US
+
+70-B3-D5 (hex) Javasparrow Inc.
+991000-991FFF (base 16) Javasparrow Inc.
+ 303,1-31-17,Koudou
+ Adachi Tokyo 120013
+ JP
+
+70-B3-D5 (hex) RCATSONE
+3AA000-3AAFFF (base 16) RCATSONE
+ 5925 Airport Road - Suite 905
+ Mississauga Ontario L4V 1W1
+ CA
+
+70-B3-D5 (hex) UnI Systech Co.,Ltd
+894000-894FFF (base 16) UnI Systech Co.,Ltd
+ A-511 Sigma2 164,Tancheongsang-ro,Bundang-gu
+ Seongnam-si Gyeonggi-do 13631
+ KR
+
+70-B3-D5 (hex) IOT Engineering
+16B000-16BFFF (base 16) IOT Engineering
+ 3 Eglington Ave
+ Epson Auckland 1024
+ NZ
+
+70-B3-D5 (hex) DEUTA-WERKE GmbH
+432000-432FFF (base 16) DEUTA-WERKE GmbH
+ Paffrather Str. 140
+ Bergisch Gladbach North Rhine-Westphalia 51465
+ DE
+
+70-B3-D5 (hex) Husty M.Styczen J.Hupert Sp.J.
+086000-086FFF (base 16) Husty M.Styczen J.Hupert Sp.J.
+ Rzepakowa 5e
+ Krakow malopolska 31-989
+ PL
+
+70-B3-D5 (hex) Private
+E17000-E17FFF (base 16) Private
+
+70-B3-D5 (hex) megatec electronic GmbH
+8A8000-8A8FFF (base 16) megatec electronic GmbH
+ Lehenhammer 14
+ Etzelwang Bayern 92268
+ DE
+
+70-B3-D5 (hex) EFG CZ spol. s r.o.
+897000-897FFF (base 16) EFG CZ spol. s r.o.
+ Na Jarově 4
+ Praha 3 Czech republic 13000
+ CZ
+
+70-B3-D5 (hex) Certus Operations Ltd
+4B2000-4B2FFF (base 16) Certus Operations Ltd
+ Dragonara Business Centre, 5th Floor, Dragonara Road c/w Ball Street
+ St Julians STJ 3141
+ MT
+
+70-B3-D5 (hex) Service Plus LLC
+169000-169FFF (base 16) Service Plus LLC
+ Kotlyakovskaya str. 5
+ Moscow 115201
+ RU
+
+70-B3-D5 (hex) Spectrum Techniques, LLC
+953000-953FFF (base 16) Spectrum Techniques, LLC
+ 106 Union Valley Rd
+ Oak Ridge TN 37930
+ US
+
+70-B3-D5 (hex) Private
+A03000-A03FFF (base 16) Private
+
+70-B3-D5 (hex) Xacti Corporation
+828000-828FFF (base 16) Xacti Corporation
+ Tower East 28F, Umeda Sky bldg, 1-1-88, Oyodonaka, Kita-ku,
+ Osaka Osaka 5316028
+ JP
+
+70-B3-D5 (hex) Shangdong Bosure Automation Technology Ltd
+A88000-A88FFF (base 16) Shangdong Bosure Automation Technology Ltd
+ No.1 Shunhua Road, Gaoxin District
+ Jinan Shangdong 250101
+ CN
+
+70-B3-D5 (hex) HumanEyes Technologies Ltd.
+9DD000-9DDFFF (base 16) HumanEyes Technologies Ltd.
+ Neve Ilan
+ Neve Ilan 90850
+ IL
+
+70-B3-D5 (hex) Ideetron b.v.
+9B5000-9B5FFF (base 16) Ideetron b.v.
+ Dorpsstraat 81
+ Doorn Utrecht 3941JL
+ NL
+
+70-B3-D5 (hex) APG Cash Drawer, LLC
+BB3000-BB3FFF (base 16) APG Cash Drawer, LLC
+ 5250 Industrial Blvd NE
+ Minneapolis MN 55421
+ US
+
+70-B3-D5 (hex) Asystems Corporation
+255000-255FFF (base 16) Asystems Corporation
+ 10F., No.70, Sec.1, Keelung Rd
+ Taipei Taiwan 11070
+ TW
+
+70-B3-D5 (hex) Mettler Toledo Hi Speed
+74A000-74AFFF (base 16) Mettler Toledo Hi Speed
+ 5 Barr Road
+ Ithaca NY 14850
+ US
+
+70-B3-D5 (hex) Polynet Telecommunications Consulting and Contractor Ltd.
+877000-877FFF (base 16) Polynet Telecommunications Consulting and Contractor Ltd.
+ Montevideo street 3/b
+ Budapest 1037
+ HU
+
+70-B3-D5 (hex) Movicom LLC
+5DB000-5DBFFF (base 16) Movicom LLC
+ Nauchny proezd, 20
+ Moscow 117246
+ RU
+
+70-B3-D5 (hex) PAMIR Inc
+D93000-D93FFF (base 16) PAMIR Inc
+ B-222, 606, Seobusaet-gil, Geumcheon-gu
+ Seoul 08504
+ KR
+
+70-B3-D5 (hex) RIKEN OPTECH CORPORATION
+63E000-63EFFF (base 16) RIKEN OPTECH CORPORATION
+ 5615-1 Taguchi
+ Saku-city Nagano 384-0412
+ JP
+
+70-B3-D5 (hex) LOGICUBE INC
+999000-999FFF (base 16) LOGICUBE INC
+ 19755 Nordhoff Place
+ Chatsworth CA 91311
+ US
+
+70-B3-D5 (hex) Electrolux
+7A6000-7A6FFF (base 16) Electrolux
+ Corso Lino Zanussi 24
+ Porcia PORDENONE 33080
+ IT
+
+70-B3-D5 (hex) Autocom Diagnostic Partner AB
+98E000-98EFFF (base 16) Autocom Diagnostic Partner AB
+ Grafitvägen 23B
+ TROLLHÄTTAN 46138
+ SE
+
+70-B3-D5 (hex) Breas Medical AB
+E88000-E88FFF (base 16) Breas Medical AB
+ Företagsvägen 1
+ Mölnlycke SE-435 33
+ SE
+
+70-B3-D5 (hex) LG Electronics
+723000-723FFF (base 16) LG Electronics
+ 189, LG Gasan Digital Center, Gasan digital 1-ro, Geumcheon-gu
+ Seoul 153-803
+ KR
+
+70-B3-D5 (hex) InOut Communication Systems
+FF9000-FF9FFF (base 16) InOut Communication Systems
+ via Nobel, 10
+ Noventa di Piave Venezia 30020
+ IT
+
+70-B3-D5 (hex) Jiangsu Jinheng Information Technology Co.,Ltd.
+492000-492FFF (base 16) Jiangsu Jinheng Information Technology Co.,Ltd.
+ LuHe District,XieJiaDian,Ninggang Road No.81
+ Nanjing Jiangsu 210035
+ CN
+
+70-B3-D5 (hex) BLOCKSI LLC
+95E000-95EFFF (base 16) BLOCKSI LLC
+ 228 Hamilton avenue 3rd floor
+ Palo Alto 94301
+ US
+
+70-B3-D5 (hex) VAGLER International Sdn Bhd
+582000-582FFF (base 16) VAGLER International Sdn Bhd
+ 2006 Jalan Jelawat, Seberang Jaya Industrial Estate
+ Prai Penang 13700
+ MY
+
+70-B3-D5 (hex) TechSigno srl
+0A2000-0A2FFF (base 16) TechSigno srl
+ Via Giovanni Paolo II, 3
+ Udiner UD 33100
+ IT
+
+70-B3-D5 (hex) Neuron GmbH
+E1B000-E1BFFF (base 16) Neuron GmbH
+ Badenerstrasse 9
+ Brugg 5200
+ CH
+
+70-B3-D5 (hex) HAVELSAN A.Ş.
+096000-096FFF (base 16) HAVELSAN A.Ş.
+ Mustafa Kemal Mah. 2120.Cad. No.39
+ ANKARA 06510
+ TR
+
+70-B3-D5 (hex) Selex ES Inc.
+F5E000-F5EFFF (base 16) Selex ES Inc.
+ 4221 Tudor Lane
+ Greensboro NC 27410
+ US
+
+70-B3-D5 (hex) YG COMPANY CO., LTD
+63F000-63FFFF (base 16) YG COMPANY CO., LTD
+ 65, Techno 3-ro
+ Daejeon Yuseong-gu 34016
+ KR
+
+70-B3-D5 (hex) QIAGEN Instruments AG
+A29000-A29FFF (base 16) QIAGEN Instruments AG
+ Garstligweg 8
+ Hombrechtikon Zurich 8634
+ CH
+
+70-B3-D5 (hex) DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME
+F8F000-F8FFFF (base 16) DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME
+ Praça Rotary Club, 355
+ Ribeirão Preto São Paulo 14021-355
+ BR
+
+70-B3-D5 (hex) Savari Inc
+207000-207FFF (base 16) Savari Inc
+ 2005 De la cruz blvd, st 111,
+ santa clara CA 95050
+ US
+
+70-B3-D5 (hex) Emergency Lighting Products Limited
+480000-480FFF (base 16) Emergency Lighting Products Limited
+ Gillmans Industrial Estate, Natts Lane
+ Billingshurst RH14 9EZ
+ GB
+
+70-B3-D5 (hex) ONDEMAND LABORATORY Co., Ltd.
+069000-069FFF (base 16) ONDEMAND LABORATORY Co., Ltd.
+ Daiba 449 Space 369 Building 2F
+ Mishima Shizuoka 411-0803
+ JP
+
+70-B3-D5 (hex) EPSOFT Co., Ltd
+A3A000-A3AFFF (base 16) EPSOFT Co., Ltd
+ 301, Bupyeong-daero, Bupyeong-gu
+ Incheon 21315
+ KR
+
+70-B3-D5 (hex) CSM MACHINERY srl
+FE3000-FE3FFF (base 16) CSM MACHINERY srl
+ Via Cadore Mare, 25
+ Cimetta di Codognè Treviso 31013
+ IT
+
+70-B3-D5 (hex) X-Laser LLC
+711000-711FFF (base 16) X-Laser LLC
+ 9125 Whiskey Bottom Rd Ste A
+ Laurel MD 20723
+ US
+
+70-B3-D5 (hex) GS Elektromedizinsiche Geräte G. Stemple GmbH
+144000-144FFF (base 16) GS Elektromedizinsiche Geräte G. Stemple GmbH
+ Hauswiesenstr. 26
+ Kaufering Bayern 86916
+ DE
+
+70-B3-D5 (hex) NESA SRL
+BFA000-BFAFFF (base 16) NESA SRL
+ Via Sartori, 6/8
+ Vidor Treviso 31020
+ IT
+
+70-B3-D5 (hex) Renesas Electronics
+340000-340FFF (base 16) Renesas Electronics
+ 2801 Scott Blvd
+ Santa Clara CA 95050
+ US
+
+70-B3-D5 (hex) AEM Singapore Pte. Ltd.
+AC1000-AC1FFF (base 16) AEM Singapore Pte. Ltd.
+ 52 Serangoon North Ave 4
+ Singapore Singapore 555853
+ SG
+
+70-B3-D5 (hex) Planewave Instruments
+CB4000-CB4FFF (base 16) Planewave Instruments
+ 1819 Kona Dr.
+ Compton CA 90220
+ US
+
+70-B3-D5 (hex) Avionica
+611000-611FFF (base 16) Avionica
+ 9941 West Jessamine St
+ Miami FL 33157
+ US
+
+70-B3-D5 (hex) ELDES
+9A0000-9A0FFF (base 16) ELDES
+ Ukmerges 283B
+ Vilnius 06313
+ LT
+
+70-B3-D5 (hex) Intesens
+B17000-B17FFF (base 16) Intesens
+ 425 rue Jean Rostand
+ labege 31670
+ FR
+
+70-B3-D5 (hex) Avant Technologies, Inc
+410000-410FFF (base 16) Avant Technologies, Inc
+ Road 156 Caguas West Ind. Park bldg 39
+ Caguas PR 00726
+ US
+
+70-B3-D5 (hex) Lab241 Co.,Ltd.
+21B000-21BFFF (base 16) Lab241 Co.,Ltd.
+ 25Dong 241Ho, 97, Siheung-daero, Geumcheon-gu
+ Seoul Seoul 08639
+ KR
+
+70-B3-D5 (hex) HEITEC AG
+228000-228FFF (base 16) HEITEC AG
+ Dr.-Otto-Leich-Str. 16
+ Eckental Bavaria 90542
+ DE
+
+70-B3-D5 (hex) Insitu, Inc
+B3B000-B3BFFF (base 16) Insitu, Inc
+ 118 E Columbia River Way
+ Bingen WA 98605
+ US
+
+70-B3-D5 (hex) Alere Technologies AS
+2AE000-2AEFFF (base 16) Alere Technologies AS
+ Kjelsaasveien 161
+ Oslo Oslo 0382
+ NO
+
+70-B3-D5 (hex) MatchX GmbH
+1CB000-1CBFFF (base 16) MatchX GmbH
+ Adalbert Str.8
+ Berlin 10999
+ DE
+
+70-B3-D5 (hex) Metrum Sweden AB
+F98000-F98FFF (base 16) Metrum Sweden AB
+ Anders Personsgatan 16
+ Goteborg 41664
+ SE
+
+70-B3-D5 (hex) Private
+DE9000-DE9FFF (base 16) Private
+
+70-B3-D5 (hex) FOSHAN VOHOM
+2BF000-2BFFFF (base 16) FOSHAN VOHOM
+ Unit 402, 4/F ENT A3 Bldg, Hantian Science and Technology City, No. 17 Shenhai RD.
+ Foshan Guangdong 528200
+ CN
+
+70-B3-D5 (hex) Hills Health Solutions
+78A000-78AFFF (base 16) Hills Health Solutions
+ Unit 1, Builing F, 3-29 Birnie Ave
+ Lidcombe New South Wales 2141
+ AU
+
+70-B3-D5 (hex) Cambridge Pixel
+023000-023FFF (base 16) Cambridge Pixel
+ New Cambridge House, Litlington
+ Royston Herts SG8 0SS
+ GB
+
+70-B3-D5 (hex) Triax A/S
+C2E000-C2EFFF (base 16) Triax A/S
+ Bjornkaervej 3
+ Hornsyld Denmark 8783
+ DK
+
+70-B3-D5 (hex) D.E.M. SPA
+C1C000-C1CFFF (base 16) D.E.M. SPA
+ Z.I. VILLANOVA 20
+ Longarone (BL) 32013
+ IT
+
70-B3-D5 (hex) PTYPE Co., LTD.
6B0000-6B0FFF (base 16) PTYPE Co., LTD.
B121, B-dong, Keumkang Penterium IT Tower, 810, Gwanyand 2-dong, Dongan-gu
@@ -5030,12 +5513,6 @@ E9C000-E9CFFF (base 16) ATG UV Technology Sissach 4450
CH
-70-B3-D5 (hex) Triax A/S
-C2E000-C2EFFF (base 16) Triax A/S
- Bjornkaervej 3
- Hornsyld Denmark 8783
- DK
-
70-B3-D5 (hex) Dextera Labs
0EF000-0EFFFF (base 16) Dextera Labs
3175 Quatre-Bourgeois #104
@@ -5465,426 +5942,84 @@ EB9000-EB9FFF (base 16) Thiel Audio Products Company, LLC Nashville TN 37228
US
-70-B3-D5 (hex) SHENZHEN GAONA ELECTRONIC CO.LTD
-031000-031FFF (base 16) SHENZHEN GAONA ELECTRONIC CO.LTD
- F3.East block. Xinwu Industrial Building, Longzhu Road.Nanshan District
- Shenzhen Guangdong China 518000
- CN
-
-70-B3-D5 (hex) DIGIVERV INC
-548000-548FFF (base 16) DIGIVERV INC
- 1515 Evanvale Dr
- Allen TX 75013
- US
-
-70-B3-D5 (hex) Globalcom Engineering SPA
-284000-284FFF (base 16) Globalcom Engineering SPA
- Via Volta 39
- CARDANO AL CAMPO VA 21010
+70-B3-D5 (hex) TATTILE SRL
+2CA000-2CAFFF (base 16) TATTILE SRL
+ VIA DONIZETTI, 1/3/5
+ MAIRANO BRESCIA 25030
IT
-70-B3-D5 (hex) Array Technologies Inc.
-A4E000-A4EFFF (base 16) Array Technologies Inc.
- 21 Sequin Drive
- Glastonbury 06033
- US
-
-70-B3-D5 (hex) Private
-580000-580FFF (base 16) Private
-
-70-B3-D5 (hex) Alma
-BA9000-BA9FFF (base 16) Alma
- 4A, Bd de la Gare, Porte 1
- Boissy St Léger PACA 94470
- FR
-
-70-B3-D5 (hex) Health Care Originals, Inc.
-2F2000-2F2FFF (base 16) Health Care Originals, Inc.
- 1 Pleasant St., Ste. 442
- Rochester NY 14604
- US
-
-70-B3-D5 (hex) GSF Corporation Pte Ltd
-B98000-B98FFF (base 16) GSF Corporation Pte Ltd
- 60 Paya Lebar Road
- # 12-05 Paya Lebar Square 409051
- SG
-
-70-B3-D5 (hex) Grossenbacher Systeme AG
-0DE000-0DEFFF (base 16) Grossenbacher Systeme AG
- Spinnereistrasse 10
- St. Gallen 9008
- CH
-
-70-B3-D5 (hex) International Roll-Call Corporation
-4B8000-4B8FFF (base 16) International Roll-Call Corporation
- 8346 Old Richfood Road
- Mechanicsville VA 23116
- US
-
-70-B3-D5 (hex) Javasparrow Inc.
-991000-991FFF (base 16) Javasparrow Inc.
- 303,1-31-17,Koudou
- Adachi Tokyo 120013
- JP
-
-70-B3-D5 (hex) RCATSONE
-3AA000-3AAFFF (base 16) RCATSONE
- 5925 Airport Road - Suite 905
- Mississauga Ontario L4V 1W1
- CA
-
-70-B3-D5 (hex) UnI Systech Co.,Ltd
-894000-894FFF (base 16) UnI Systech Co.,Ltd
- A-511 Sigma2 164,Tancheongsang-ro,Bundang-gu
- Seongnam-si Gyeonggi-do 13631
- KR
-
-70-B3-D5 (hex) IOT Engineering
-16B000-16BFFF (base 16) IOT Engineering
- 3 Eglington Ave
- Epson Auckland 1024
- NZ
-
-70-B3-D5 (hex) DEUTA-WERKE GmbH
-432000-432FFF (base 16) DEUTA-WERKE GmbH
- Paffrather Str. 140
- Bergisch Gladbach North Rhine-Westphalia 51465
- DE
-
-70-B3-D5 (hex) Husty M.Styczen J.Hupert Sp.J.
-086000-086FFF (base 16) Husty M.Styczen J.Hupert Sp.J.
- Rzepakowa 5e
- Krakow malopolska 31-989
- PL
-
-70-B3-D5 (hex) Private
-E17000-E17FFF (base 16) Private
-
-70-B3-D5 (hex) megatec electronic GmbH
-8A8000-8A8FFF (base 16) megatec electronic GmbH
- Lehenhammer 14
- Etzelwang Bayern 92268
- DE
-
-70-B3-D5 (hex) EFG CZ spol. s r.o.
-897000-897FFF (base 16) EFG CZ spol. s r.o.
- Na Jarově 4
- Praha 3 Czech republic 13000
- CZ
-
-70-B3-D5 (hex) Certus Operations Ltd
-4B2000-4B2FFF (base 16) Certus Operations Ltd
- Dragonara Business Centre, 5th Floor, Dragonara Road c/w Ball Street
- St Julians STJ 3141
- MT
-
-70-B3-D5 (hex) Service Plus LLC
-169000-169FFF (base 16) Service Plus LLC
- Kotlyakovskaya str. 5
- Moscow 115201
- RU
-
-70-B3-D5 (hex) Spectrum Techniques, LLC
-953000-953FFF (base 16) Spectrum Techniques, LLC
- 106 Union Valley Rd
- Oak Ridge TN 37930
- US
-
-70-B3-D5 (hex) Private
-A03000-A03FFF (base 16) Private
-
-70-B3-D5 (hex) Xacti Corporation
-828000-828FFF (base 16) Xacti Corporation
- Tower East 28F, Umeda Sky bldg, 1-1-88, Oyodonaka, Kita-ku,
- Osaka Osaka 5316028
- JP
-
-70-B3-D5 (hex) Shangdong Bosure Automation Technology Ltd
-A88000-A88FFF (base 16) Shangdong Bosure Automation Technology Ltd
- No.1 Shunhua Road, Gaoxin District
- Jinan Shangdong 250101
- CN
-
-70-B3-D5 (hex) HumanEyes Technologies Ltd.
-9DD000-9DDFFF (base 16) HumanEyes Technologies Ltd.
- Neve Ilan
- Neve Ilan 90850
- IL
-
-70-B3-D5 (hex) Ideetron b.v.
-9B5000-9B5FFF (base 16) Ideetron b.v.
- Dorpsstraat 81
- Doorn Utrecht 3941JL
- NL
-
-70-B3-D5 (hex) APG Cash Drawer, LLC
-BB3000-BB3FFF (base 16) APG Cash Drawer, LLC
- 5250 Industrial Blvd NE
- Minneapolis MN 55421
- US
+70-B3-D5 (hex) DORLET SAU
+8E3000-8E3FFF (base 16) DORLET SAU
+ Albert Eistein 34
+ Alava SPAIN 01510
+ ES
-70-B3-D5 (hex) Asystems Corporation
-255000-255FFF (base 16) Asystems Corporation
- 10F., No.70, Sec.1, Keelung Rd
- Taipei Taiwan 11070
+70-B3-D5 (hex) Gentec Systems Co.
+469000-469FFF (base 16) Gentec Systems Co.
+ 5F., No.51-3, Fuxing Rd., Xindian Dist.,
+ New Taipei City 23150
TW
-70-B3-D5 (hex) Mettler Toledo Hi Speed
-74A000-74AFFF (base 16) Mettler Toledo Hi Speed
- 5 Barr Road
- Ithaca NY 14850
- US
-
-70-B3-D5 (hex) Polynet Telecommunications Consulting and Contractor Ltd.
-877000-877FFF (base 16) Polynet Telecommunications Consulting and Contractor Ltd.
- Montevideo street 3/b
- Budapest 1037
- HU
-
-70-B3-D5 (hex) Movicom LLC
-5DB000-5DBFFF (base 16) Movicom LLC
- Nauchny proezd, 20
- Moscow 117246
- RU
-
-70-B3-D5 (hex) PAMIR Inc
-D93000-D93FFF (base 16) PAMIR Inc
- B-222, 606, Seobusaet-gil, Geumcheon-gu
- Seoul 08504
- KR
-
-70-B3-D5 (hex) RIKEN OPTECH CORPORATION
-63E000-63EFFF (base 16) RIKEN OPTECH CORPORATION
- 5615-1 Taguchi
- Saku-city Nagano 384-0412
- JP
-
-70-B3-D5 (hex) LOGICUBE INC
-999000-999FFF (base 16) LOGICUBE INC
- 19755 Nordhoff Place
- Chatsworth CA 91311
- US
-
-70-B3-D5 (hex) Electrolux
-7A6000-7A6FFF (base 16) Electrolux
- Corso Lino Zanussi 24
- Porcia PORDENONE 33080
- IT
-
-70-B3-D5 (hex) Autocom Diagnostic Partner AB
-98E000-98EFFF (base 16) Autocom Diagnostic Partner AB
- Grafitvägen 23B
- TROLLHÄTTAN 46138
- SE
-
-70-B3-D5 (hex) Breas Medical AB
-E88000-E88FFF (base 16) Breas Medical AB
- Företagsvägen 1
- Mölnlycke SE-435 33
- SE
-
-70-B3-D5 (hex) LG Electronics
-723000-723FFF (base 16) LG Electronics
- 189, LG Gasan Digital Center, Gasan digital 1-ro, Geumcheon-gu
- Seoul 153-803
- KR
-
-70-B3-D5 (hex) InOut Communication Systems
-FF9000-FF9FFF (base 16) InOut Communication Systems
- via Nobel, 10
- Noventa di Piave Venezia 30020
- IT
-
-70-B3-D5 (hex) Jiangsu Jinheng Information Technology Co.,Ltd.
-492000-492FFF (base 16) Jiangsu Jinheng Information Technology Co.,Ltd.
- LuHe District,XieJiaDian,Ninggang Road No.81
- Nanjing Jiangsu 210035
- CN
-
-70-B3-D5 (hex) BLOCKSI LLC
-95E000-95EFFF (base 16) BLOCKSI LLC
- 228 Hamilton avenue 3rd floor
- Palo Alto 94301
- US
+70-B3-D5 (hex) Exi Flow Measurement Ltd
+AAF000-AAFFFF (base 16) Exi Flow Measurement Ltd
+ Unit 22 Ford Lane business Park
+ Ford, ARUNDEL West Sussex BN164HP
+ GB
-70-B3-D5 (hex) VAGLER International Sdn Bhd
-582000-582FFF (base 16) VAGLER International Sdn Bhd
- 2006 Jalan Jelawat, Seberang Jaya Industrial Estate
- Prai Penang 13700
- MY
+70-B3-D5 (hex) OÜ ELIKO Tehnoloogia Arenduskeskus
+D4A000-D4AFFF (base 16) OÜ ELIKO Tehnoloogia Arenduskeskus
+ Mäealuse 2/1
+ Tallinn Harju 12618
+ EE
-70-B3-D5 (hex) TechSigno srl
-0A2000-0A2FFF (base 16) TechSigno srl
- Via Giovanni Paolo II, 3
- Udiner UD 33100
- IT
+70-B3-D5 (hex) SEASON DESIGN TECHNOLOGY
+2C9000-2C9FFF (base 16) SEASON DESIGN TECHNOLOGY
+ FLOOR 4, WARDS EXCHANGE, 199 ECCLESALL ROAD
+ SHEFFIELD SOUTH YORKSHIRE S11 8HW
+ GB
-70-B3-D5 (hex) Neuron GmbH
-E1B000-E1BFFF (base 16) Neuron GmbH
- Badenerstrasse 9
- Brugg 5200
- CH
+70-B3-D5 (hex) BCD Audio
+728000-728FFF (base 16) BCD Audio
+ 5 Bristol Way, Stoke Gardens
+ Slough Berkshire SL1 3QE
+ GB
-70-B3-D5 (hex) HAVELSAN A.Ş.
-096000-096FFF (base 16) HAVELSAN A.Ş.
- Mustafa Kemal Mah. 2120.Cad. No.39
- ANKARA 06510
- TR
+70-B3-D5 (hex) Resolution Systems
+D89000-D89FFF (base 16) Resolution Systems
+ 1/214 Greenhill Rd
+ Eastwood South Australia 6063
+ AU
-70-B3-D5 (hex) YG COMPANY CO., LTD
-63F000-63FFFF (base 16) YG COMPANY CO., LTD
- 65, Techno 3-ro
- Daejeon Yuseong-gu 34016
+70-B3-D5 (hex) WARECUBE,INC
+F06000-F06FFF (base 16) WARECUBE,INC
+ #A-811, 142-10, Saneop-ro, 156beon-gil, Gwonseon-gu
+ Suwon-si 16648
KR
-70-B3-D5 (hex) Selex ES Inc.
-F5E000-F5EFFF (base 16) Selex ES Inc.
- 4221 Tudor Lane
- Greensboro NC 27410
+70-B3-D5 (hex) Roxford
+651000-651FFF (base 16) Roxford
+ PO Box 231851
+ Encinitas CA 92023-1851
US
-70-B3-D5 (hex) DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME
-F8F000-F8FFFF (base 16) DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME
- Praça Rotary Club, 355
- Ribeirão Preto São Paulo 14021-355
+70-B3-D5 (hex) Scenario Automation
+8B4000-8B4FFF (base 16) Scenario Automation
+ Rua Paulo Elias, 216
+ São Carlos São Paulo 13564400
BR
-70-B3-D5 (hex) Savari Inc
-207000-207FFF (base 16) Savari Inc
- 2005 De la cruz blvd, st 111,
- santa clara CA 95050
- US
-
-70-B3-D5 (hex) QIAGEN Instruments AG
-A29000-A29FFF (base 16) QIAGEN Instruments AG
- Garstligweg 8
- Hombrechtikon Zurich 8634
- CH
-
-70-B3-D5 (hex) ONDEMAND LABORATORY Co., Ltd.
-069000-069FFF (base 16) ONDEMAND LABORATORY Co., Ltd.
- Daiba 449 Space 369 Building 2F
- Mishima Shizuoka 411-0803
- JP
-
-70-B3-D5 (hex) EPSOFT Co., Ltd
-A3A000-A3AFFF (base 16) EPSOFT Co., Ltd
- 301, Bupyeong-daero, Bupyeong-gu
- Incheon 21315
- KR
-
-70-B3-D5 (hex) Emergency Lighting Products Limited
-480000-480FFF (base 16) Emergency Lighting Products Limited
- Gillmans Industrial Estate, Natts Lane
- Billingshurst RH14 9EZ
- GB
-
-70-B3-D5 (hex) CSM MACHINERY srl
-FE3000-FE3FFF (base 16) CSM MACHINERY srl
- Via Cadore Mare, 25
- Cimetta di Codognè Treviso 31013
- IT
-
-70-B3-D5 (hex) X-Laser LLC
-711000-711FFF (base 16) X-Laser LLC
- 9125 Whiskey Bottom Rd Ste A
- Laurel MD 20723
- US
-
-70-B3-D5 (hex) GS Elektromedizinsiche Geräte G. Stemple GmbH
-144000-144FFF (base 16) GS Elektromedizinsiche Geräte G. Stemple GmbH
- Hauswiesenstr. 26
- Kaufering Bayern 86916
- DE
-
-70-B3-D5 (hex) NESA SRL
-BFA000-BFAFFF (base 16) NESA SRL
- Via Sartori, 6/8
- Vidor Treviso 31020
- IT
-
-70-B3-D5 (hex) Renesas Electronics
-340000-340FFF (base 16) Renesas Electronics
- 2801 Scott Blvd
- Santa Clara CA 95050
- US
-
-70-B3-D5 (hex) AEM Singapore Pte. Ltd.
-AC1000-AC1FFF (base 16) AEM Singapore Pte. Ltd.
- 52 Serangoon North Ave 4
- Singapore Singapore 555853
- SG
-
-70-B3-D5 (hex) Planewave Instruments
-CB4000-CB4FFF (base 16) Planewave Instruments
- 1819 Kona Dr.
- Compton CA 90220
- US
-
-70-B3-D5 (hex) Avionica
-611000-611FFF (base 16) Avionica
- 9941 West Jessamine St
- Miami FL 33157
- US
-
-70-B3-D5 (hex) ELDES
-9A0000-9A0FFF (base 16) ELDES
- Ukmerges 283B
- Vilnius 06313
- LT
-
-70-B3-D5 (hex) Intesens
-B17000-B17FFF (base 16) Intesens
- 425 rue Jean Rostand
- labege 31670
- FR
-
-70-B3-D5 (hex) Avant Technologies, Inc
-410000-410FFF (base 16) Avant Technologies, Inc
- Road 156 Caguas West Ind. Park bldg 39
- Caguas PR 00726
- US
-
-70-B3-D5 (hex) Lab241 Co.,Ltd.
-21B000-21BFFF (base 16) Lab241 Co.,Ltd.
- 25Dong 241Ho, 97, Siheung-daero, Geumcheon-gu
- Seoul Seoul 08639
- KR
-
-70-B3-D5 (hex) HEITEC AG
-228000-228FFF (base 16) HEITEC AG
- Dr.-Otto-Leich-Str. 16
- Eckental Bavaria 90542
- DE
-
-70-B3-D5 (hex) Alere Technologies AS
-2AE000-2AEFFF (base 16) Alere Technologies AS
- Kjelsaasveien 161
- Oslo Oslo 0382
- NO
-
-70-B3-D5 (hex) Insitu, Inc
-B3B000-B3BFFF (base 16) Insitu, Inc
- 118 E Columbia River Way
- Bingen WA 98605
- US
+70-B3-D5 (hex) Talleres de Escoriaza SA
+532000-532FFF (base 16) Talleres de Escoriaza SA
+ Barrio Ventas, 35
+ Irun Gipuzkoa 20305
+ ES
-70-B3-D5 (hex) MatchX GmbH
-1CB000-1CBFFF (base 16) MatchX GmbH
- Adalbert Str.8
- Berlin 10999
+70-B3-D5 (hex) MB connect line GmbH Fernwartungssysteme
+8D9000-8D9FFF (base 16) MB connect line GmbH Fernwartungssysteme
+ Winnettener Straße 6
+ Dinkelsbuehl Bavaria 91550
DE
-70-B3-D5 (hex) Metrum Sweden AB
-F98000-F98FFF (base 16) Metrum Sweden AB
- Anders Personsgatan 16
- Goteborg 41664
- SE
-
-70-B3-D5 (hex) Private
-DE9000-DE9FFF (base 16) Private
-
70-B3-D5 (hex) Schildknecht AG
494000-494FFF (base 16) Schildknecht AG
Haugweg 26
@@ -6011,12 +6146,6 @@ FCF000-FCFFFF (base 16) Acc+Ess Ltd Centurion Gauteng 0157
ZA
-70-B3-D5 (hex) Triax A/S
-D7E000-D7EFFF (base 16) Triax A/S
- Bjornkaervej 3
- Hornsyld Denmark 8783
- DK
-
70-B3-D5 (hex) IntelliDesign Pty Ltd
061000-061FFF (base 16) IntelliDesign Pty Ltd
99 Bluestone Circuit
@@ -6161,12 +6290,6 @@ E3B000-E3BFFF (base 16) ComNav Technology Ltd. Shanghai Shanghai 201103
CN
-70-B3-D5 (hex) Sierra Nevada Corporation
-339000-339FFF (base 16) Sierra Nevada Corporation
- 444 Salomon Circle
- Sparks NV 89434
- US
-
70-B3-D5 (hex) StromIdee GmbH
703000-703FFF (base 16) StromIdee GmbH
Walzmühlestrasse 51
@@ -6650,12 +6773,6 @@ F2B000-F2BFFF (base 16) SENSYS GmbH Halmstad Halland 30241
SE
-70-B3-D5 (hex) Triax A/S
-941000-941FFF (base 16) Triax A/S
- Bjørnkærvej 3
- Hornsyld 8783
- DK
-
70-B3-D5 (hex) Cyberteam Sp z o o
36D000-36DFFF (base 16) Cyberteam Sp z o o
Kalinowice 157
@@ -6908,12 +7025,6 @@ B3D000-B3DFFF (base 16) Inras GmbH Linz Oberösterreich A-4040
AT
-00-1B-C5 (hex) Triax A/S
-0BB000-0BBFFF (base 16) Triax A/S
- Bjornskærvej 3
- Hornsyld Denmark 8783
- US
-
00-1B-C5 (hex) Roslen Eco-Networking Products
0B1000-0B1FFF (base 16) Roslen Eco-Networking Products
2010 Vada Ranch Road
@@ -8573,6 +8684,96 @@ CFE000-CFEFFF (base 16) Secturion Systems Centerville UT 84014
US
+70-B3-D5 (hex) PHB Eletronica Ltda.
+904000-904FFF (base 16) PHB Eletronica Ltda.
+ Aroaba St., 129
+ São Paulo 05315-020
+ BR
+
+70-B3-D5 (hex) SoftLab-NSK
+555000-555FFF (base 16) SoftLab-NSK
+ Pr.Koptjuga 1
+ Novosibirsk 630090
+ RU
+
+70-B3-D5 (hex) TIAMA
+BA3000-BA3FFF (base 16) TIAMA
+ ZA des Plattes - 1 Chemin des Plattes
+ VOURLES 69390
+ FR
+
+70-B3-D5 (hex) SAICE
+FB7000-FB7FFF (base 16) SAICE
+ 5-23-1
+ Shinagawa Higashi-Gotanda Tokyo 141-0022
+ JP
+
+70-B3-D5 (hex) Core Balance Co., Ltd.
+D5F000-D5FFFF (base 16) Core Balance Co., Ltd.
+ #1807, #1808, 308-4, Seongsu-dong 2-ga, Seongdong-gu
+ Seoul 04781
+ KR
+
+70-B3-D5 (hex) Triax A/S
+D7E000-D7EFFF (base 16) Triax A/S
+ Bjornkaervej 3
+ Hornsyld Denmark 8783
+ DK
+
+00-1B-C5 (hex) Triax A/S
+0BB000-0BBFFF (base 16) Triax A/S
+ Bjornkaervej 3
+ Hornsyld Denmark 8783
+ DK
+
+70-B3-D5 (hex) Triax A/S
+941000-941FFF (base 16) Triax A/S
+ Bjornkaervej 3
+ Hornsyld Denmark 8783
+ DK
+
+70-B3-D5 (hex) Agramkow Fluid Systems A/S
+4AF000-4AFFFF (base 16) Agramkow Fluid Systems A/S
+ Augustenborg Landevej 19
+ Soenderborg DK 6400
+ DK
+
+70-B3-D5 (hex) PULLNET TECHNOLOGY, SA DE CV SSC1012302S73
+70A000-70AFFF (base 16) PULLNET TECHNOLOGY, SA DE CV SSC1012302S73
+ LUZ SAVIÑON 2007
+ BENITO JUAREZ CIUDAD DE MEXICO 03020
+ MX
+
+70-B3-D5 (hex) Systems With Intelligence Inc.
+93E000-93EFFF (base 16) Systems With Intelligence Inc.
+ 6889 Rexwood Road, Unit 9
+ Mississauga Ontario L4V 1R2
+ CA
+
+70-B3-D5 (hex) ENTEC Electric & Electronic Co., LTD.
+E0B000-E0BFFF (base 16) ENTEC Electric & Electronic Co., LTD.
+ 78-2 Buncheon-ri, Bongdam-eup
+ Hwaseong-city Gyungki-do 445-894
+ KR
+
+70-B3-D5 (hex) Labtronik s.r.l.
+6C1000-6C1FFF (base 16) Labtronik s.r.l.
+ Via di Cervara 49
+ Rome Italy 00155
+ IT
+
+70-B3-D5 (hex) Nautel Limited
+87C000-87CFFF (base 16) Nautel Limited
+ 10089 Peggy's Cove Road
+ Hackett's Cove Nova Scotia B3Z3J4
+ CA
+
+70-B3-D5 (hex) Biovigil Hygiene Technologies
+DB1000-DB1FFF (base 16) Biovigil Hygiene Technologies
+ 924 N. Main st., Suite 2
+ Ann Arbor MI 48104
+ US
+
70-B3-D5 (hex) Shenzhen INVT Electric Co.,Ltd
1D0000-1D0FFF (base 16) Shenzhen INVT Electric Co.,Ltd
INVT Bldg., GaoFa Scientific Park, Longjing, Nanshan, Shenzhen.
@@ -8687,6 +8888,102 @@ BB9000-BB9FFF (base 16) KOSMEK.Ltd Plymouth MI 48170
US
+70-B3-D5 (hex) Shanghai YuanAn Environmental Protection Technology Co.,Ltd
+6D8000-6D8FFF (base 16) Shanghai YuanAn Environmental Protection Technology Co.,Ltd
+ Rm213/225,Oriental Pearl European City,No 285 East luochuan Road
+ Shanghai Shanghai 200072
+ CN
+
+70-B3-D5 (hex) ST Aerospace Systems
+27F000-27FFFF (base 16) ST Aerospace Systems
+ 505A Airport Road Paya Lebar
+ Singapore Singapore 539934
+ SG
+
+70-B3-D5 (hex) Sierra Nevada Corporation
+339000-339FFF (base 16) Sierra Nevada Corporation
+ 444 Salomon Circle
+ Sparks NV 89434
+ US
+
+70-B3-D5 (hex) Hi Tech Systems Ltd
+4B4000-4B4FFF (base 16) Hi Tech Systems Ltd
+ Holbrook House, Oakley Lane
+ Basingstoke Hampshire RG23 7JY
+ GB
+
+70-B3-D5 (hex) Hermann Lümmen GmbH
+D4B000-D4BFFF (base 16) Hermann Lümmen GmbH
+ Biberweg 32
+ Troisdorf 53842
+ DE
+
+70-B3-D5 (hex) DEUTA-WERKE GmbH
+EF5000-EF5FFF (base 16) DEUTA-WERKE GmbH
+ Paffrather Str. 140
+ Bergisch Gladbach North Rhine-Westphalia 51465
+ DE
+
+70-B3-D5 (hex) BigStuff3, Inc.
+64E000-64EFFF (base 16) BigStuff3, Inc.
+ 4352 Fenton Rd
+ Hartland MI 48353
+ US
+
+70-B3-D5 (hex) Teko Telecom Srl
+29C000-29CFFF (base 16) Teko Telecom Srl
+ via Meucci 24/a
+ Castel San Pietro Terme Bologna 40024
+ IT
+
+70-B3-D5 (hex) Henrich Electronics Corporation
+436000-436FFF (base 16) Henrich Electronics Corporation
+ 225 Deming Place
+ Westmont IL 60559
+ US
+
+70-B3-D5 (hex) Cubitech
+7D0000-7D0FFF (base 16) Cubitech
+ Likourgou 9
+ Athens 17676
+ GR
+
+70-B3-D5 (hex) Euklis by GSG International
+AD8000-AD8FFF (base 16) Euklis by GSG International
+ via Colombo 23
+ Trezzano sul Naviglio MI 20090
+ IT
+
+70-B3-D5 (hex) Chengdu Cove Technology CO.,LTD
+24E000-24EFFF (base 16) Chengdu Cove Technology CO.,LTD
+ 6-419, Hi-tech Incubation Park, No.1480 Tianfu Ave
+ Chengdu Sichuan 610000
+ CN
+
+70-B3-D5 (hex) Star Systems International
+5EF000-5EFFFF (base 16) Star Systems International
+ Unit 04, 12/F Vanta Industrial Centre, 21-33 Tai Lin Pai Road
+ Kwai Chung 852
+ HK
+
+70-B3-D5 (hex) ZAO ZEO
+B43000-B43FFF (base 16) ZAO ZEO
+ Khachaturiana 14a
+ Moscow 127562
+ RU
+
+70-B3-D5 (hex) Robotelf Technologies (Chengdu) Co., Ltd.
+1A6000-1A6FFF (base 16) Robotelf Technologies (Chengdu) Co., Ltd.
+ N3-4-1-1914, Global Center, No. 1700, Tianfu Road North, High-rech Zone
+ Chengdu City Sichuan 610041
+ CN
+
+70-B3-D5 (hex) LG Electronics
+257000-257FFF (base 16) LG Electronics
+ 10, Magokjungang 10-ro, Gangseo-gu
+ Seoul 07796
+ KR
+
70-B3-D5 (hex) Innitive B.V.
66B000-66BFFF (base 16) Innitive B.V.
Brouwerijstraat 20
@@ -10085,18 +10382,6 @@ A66000-A66FFF (base 16) Trapeze Software Group Inc Sankt-Peterburg 197348
RU
-70-B3-D5 (hex) Sicon srl
-36C000-36CFFF (base 16) Sicon srl
- Via Sila 1/3
- Isola Vicentina Vicenza 36033
- IT
-
-70-B3-D5 (hex) Sicon srl
-04D000-04DFFF (base 16) Sicon srl
- Via Sila 1/3
- Isola Vicentina Vicenza 36033
- IT
-
70-B3-D5 (hex) Bionics co.,ltd.
A78000-A78FFF (base 16) Bionics co.,ltd.
Honmachi 1chome 2-1 Honmachi-riverside-bill 2F
@@ -10145,12 +10430,6 @@ D63000-D63FFF (base 16) CRDE Dresden Saxony 01069
DE
-70-B3-D5 (hex) Triax A/S
-C9F000-C9FFFF (base 16) Triax A/S
- Bjornkaervej 3
- Hornsyld Denmark 8783
- DK
-
70-B3-D5 (hex) Aplex Technology Inc.
8E4000-8E4FFF (base 16) Aplex Technology Inc.
2nd Floor,Tower3,District5,HongHuaLing industrial park, Nanshan District
@@ -10772,12 +11051,6 @@ FBF000-FBFFFF (base 16) SenSys (Design Electronics Ltd) MAIRANO BRESCIA 25030
IT
-70-B3-D5 (hex) Sicon srl
-D37000-D37FFF (base 16) Sicon srl
- Via Sila 1/3
- Isola Vicentina Vicenza 36033
- IT
-
70-B3-D5 (hex) DoWoo Digitech
039000-039FFF (base 16) DoWoo Digitech
A-706ho,Ssangyong IT Twintower, dunchondaero, JungWon-Gu
@@ -11318,11 +11591,11 @@ BA2000-BA2FFF (base 16) MAMAC Systems, Inc. West Burleigh Queensland 4219
AU
-70-B3-D5 (hex) ELVA-1 MICROWAVE HANDELSBOLAG
-FA3000-FA3FFF (base 16) ELVA-1 MICROWAVE HANDELSBOLAG
- c/o Hornlund, Kungsgatan 54
- Furulund 244 62
- SE
+70-B3-D5 (hex) Preston Industries dba PolyScience
+3B5000-3B5FFF (base 16) Preston Industries dba PolyScience
+ 6600 W. Touhy Ave
+ Niles IL 60714-4588
+ US
70-B3-D5 (hex) Collini Dienstleistungs GmbH
C67000-C67FFF (base 16) Collini Dienstleistungs GmbH
@@ -11330,6 +11603,12 @@ C67000-C67FFF (base 16) Collini Dienstleistungs GmbH Hohenems A 6845
AT
+70-B3-D5 (hex) Fire4 Systems UK Ltd
+E69000-E69FFF (base 16) Fire4 Systems UK Ltd
+ 8 Regent Street
+ Leeds West Yorkshire LS7 4PE
+ GB
+
70-B3-D5 (hex) Richard Paul Russell Ltd
98B000-98BFFF (base 16) Richard Paul Russell Ltd
The Lodge, Unit 1 Barnes Farm Business Park
@@ -11342,24 +11621,132 @@ AEB000-AEBFFF (base 16) Association Romandix Lausanne Vaud 1004
CH
-70-B3-D5 (hex) Special Services Group, LLC
-0F8000-0F8FFF (base 16) Special Services Group, LLC
- PO Box 825
- Denair CA 95316
- US
-
70-B3-D5 (hex) Divigraph (Pty) LTD
A86000-A86FFF (base 16) Divigraph (Pty) LTD
Postnet Suite 72, Private Bag X7
Chempet 7442
ZA
-70-B3-D5 (hex) Tunstall A/S
-A17000-A17FFF (base 16) Tunstall A/S
- Niels Bohrs vej 42
- Stilling Skanderborg 8660
+70-B3-D5 (hex) RealD
+CCB000-CCBFFF (base 16) RealD
+ 5700 Flatiron Parkway
+ Boulder CO 80301
+ US
+
+70-B3-D5 (hex) Melecs EWS GmbH
+704000-704FFF (base 16) Melecs EWS GmbH
+ GZO-Technologiestrasse 1
+ Siegendorf 7011
+ AT
+
+70-B3-D5 (hex) Raft Technologies
+8D0000-8D0FFF (base 16) Raft Technologies
+ Habarzel 25
+ Tel aviv 6971035
+ IL
+
+70-B3-D5 (hex) Jacarta Ltd
+09B000-09BFFF (base 16) Jacarta Ltd
+ Wagon Yard, London Road
+ Marlborough SN8 1LH
+ GB
+
+70-B3-D5 (hex) APP Engineering, Inc.
+049000-049FFF (base 16) APP Engineering, Inc.
+ 5234 Elmwood Avenue
+ Indianapolis IN 46203
+ US
+
+70-B3-D5 (hex) Hangzhou AwareTec Technology Co., Ltd
+5DE000-5DEFFF (base 16) Hangzhou AwareTec Technology Co., Ltd
+ 6th Floor,Building 2,No.307 Liuhe Road,Binjiang District,Hangzhou 城市: Hangzhou
+ Hangzhou Zhejiang 310000
+ CN
+
+70-B3-D5 (hex) ELEUSI GmbH
+1CD000-1CDFFF (base 16) ELEUSI GmbH
+ Rottendorferstrasse 1
+ Feldkirchen Kaernten 9560
+ AT
+
+70-B3-D5 (hex) Sicon srl
+04D000-04DFFF (base 16) Sicon srl
+ Via Sila 1/3
+ Isola Vicentina Vicenza 36033
+ IT
+
+70-B3-D5 (hex) Sicon srl
+36C000-36CFFF (base 16) Sicon srl
+ Via Sila 1/3
+ Isola Vicentina Vicenza 36033
+ IT
+
+70-B3-D5 (hex) ERA a.s.
+A90000-A90FFF (base 16) ERA a.s.
+ Prumyslova 462
+ Pardubice 53003
+ CZ
+
+70-B3-D5 (hex) Wimate Technology Solutions Private Limited
+253000-253FFF (base 16) Wimate Technology Solutions Private Limited
+ 96, 34th B cross, 16th Main, Jayanagar 4th T block
+ Bangalore Karnataka 560041
+ IN
+
+70-B3-D5 (hex) ioThings
+993000-993FFF (base 16) ioThings
+ Past. Debijestraat 42
+ Hegelsom Limburg 5963AG
+ NL
+
+70-B3-D5 (hex) Guangzhou Male Industrial Animation Technology Co.,Ltd.
+0D4000-0D4FFF (base 16) Guangzhou Male Industrial Animation Technology Co.,Ltd.
+ 4/F,Block A, 23 Huancun Road,Dalong Street, Panyu District,Guangzhou City
+ Guangzhou City Guangdong Province 514000
+ CN
+
+70-B3-D5 (hex) Zigencorp, Inc
+739000-739FFF (base 16) Zigencorp, Inc
+ 6934 Canby Avenue 107
+ Reseda CA 91335
+ US
+
+70-B3-D5 (hex) FlowNet LLC
+526000-526FFF (base 16) FlowNet LLC
+ 580 Lake Ave
+ Lancaster NY 14086
+ US
+
+70-B3-D5 (hex) Urbana Smart Solutions Pte Ltd
+224000-224FFF (base 16) Urbana Smart Solutions Pte Ltd
+ 6 Eu Tong Sen Street #06-20 The Central
+ Singapore 059817
+ SG
+
+70-B3-D5 (hex) OnYield Inc Ltd
+B74000-B74FFF (base 16) OnYield Inc Ltd
+ 814 Houston Centre, 63 Mody Road
+ Kowloon TST East
+ HK
+
+70-B3-D5 (hex) SonoSound ApS
+656000-656FFF (base 16) SonoSound ApS
+ Malov Byvej 229
+ Malov Hovedstaden 2760
DK
+70-B3-D5 (hex) Granite River Labs Inc
+749000-749FFF (base 16) Granite River Labs Inc
+ 3500 Thomas Rd # A,
+ Santa Clara 95054
+ US
+
+70-B3-D5 (hex) CT Company
+3AD000-3ADFFF (base 16) CT Company
+ Godovikova , 9, Moscow
+ Moscow RUSSIA 129085
+ RU
+
70-B3-D5 (hex) Saline Lectronics, Inc.
246000-246FFF (base 16) Saline Lectronics, Inc.
710 N Maple Rd
@@ -11462,23 +11849,23 @@ AF2000-AF2FFF (base 16) True Networks Ltd. Baltimore MD 21230
US
-70-B3-D5 (hex) HGH SYSTEMES INFRAROUGES
-853000-853FFF (base 16) HGH SYSTEMES INFRAROUGES
- 10 Rue Maryse Bastié
- Igny IDF 91430
- FR
-
70-B3-D5 (hex) Shenzhen bayue software co. LTD
784000-784FFF (base 16) Shenzhen bayue software co. LTD
B301, second phase of China merchants street technology building, nanshan district
ShenZhen 518000
CN
-70-B3-D5 (hex) Preston Industries dba PolyScience
-3B5000-3B5FFF (base 16) Preston Industries dba PolyScience
- 6600 W. Touhy Ave
- Niles IL 60714-4588
- US
+70-B3-D5 (hex) ELVA-1 MICROWAVE HANDELSBOLAG
+FA3000-FA3FFF (base 16) ELVA-1 MICROWAVE HANDELSBOLAG
+ c/o Hornlund, Kungsgatan 54
+ Furulund 244 62
+ SE
+
+70-B3-D5 (hex) HGH SYSTEMES INFRAROUGES
+853000-853FFF (base 16) HGH SYSTEMES INFRAROUGES
+ 10 Rue Maryse Bastié
+ Igny IDF 91430
+ FR
70-B3-D5 (hex) KMtronic ltd
0AF000-0AFFFF (base 16) KMtronic ltd
@@ -11492,35 +11879,65 @@ AF2000-AF2FFF (base 16) True Networks Ltd. Palo Alto 94301
US
-70-B3-D5 (hex) Fire4 Systems UK Ltd
-E69000-E69FFF (base 16) Fire4 Systems UK Ltd
- 8 Regent Street
- Leeds West Yorkshire LS7 4PE
- GB
-
-70-B3-D5 (hex) RealD
-CCB000-CCBFFF (base 16) RealD
- 5700 Flatiron Parkway
- Boulder CO 80301
+70-B3-D5 (hex) Special Services Group, LLC
+0F8000-0F8FFF (base 16) Special Services Group, LLC
+ PO Box 825
+ Denair CA 95316
US
-70-B3-D5 (hex) Melecs EWS GmbH
-704000-704FFF (base 16) Melecs EWS GmbH
- GZO-Technologiestrasse 1
- Siegendorf 7011
+70-B3-D5 (hex) Tunstall A/S
+A17000-A17FFF (base 16) Tunstall A/S
+ Niels Bohrs vej 42
+ Stilling Skanderborg 8660
+ DK
+
+70-B3-D5 (hex) Triax A/S
+C9F000-C9FFFF (base 16) Triax A/S
+ Bjornkaervej 3
+ Hornsyld Denmark 8783
+ DK
+
+70-B3-D5 (hex) Gedomo GmbH
+7D7000-7D7FFF (base 16) Gedomo GmbH
+ Erlacker 483
+ Poellau bei Hartberg Steiermark 8225
AT
-70-B3-D5 (hex) Raft Technologies
-8D0000-8D0FFF (base 16) Raft Technologies
- Habarzel 25
- Tel aviv 6971035
- IL
+70-B3-D5 (hex) Sicon srl
+D37000-D37FFF (base 16) Sicon srl
+ Via Sila 1/3
+ Isola Vicentina Vicenza 36033
+ IT
-70-B3-D5 (hex) Jacarta Ltd
-09B000-09BFFF (base 16) Jacarta Ltd
- Wagon Yard, London Road
- Marlborough SN8 1LH
- GB
+70-B3-D5 (hex) Contec DTx
+8B7000-8B7FFF (base 16) Contec DTx
+ 1800 Penn St Suite 1
+ Melbourne FL 32901
+ US
+
+70-B3-D5 (hex) HZHY TECHNOLOGY
+4A6000-4A6FFF (base 16) HZHY TECHNOLOGY
+ The 2th floor,Longzeyuan Multi-use
+ beijing 102208
+ CN
+
+70-B3-D5 (hex) Mesa Labs, Inc.
+23A000-23AFFF (base 16) Mesa Labs, Inc.
+ 12100 West 6th Ave.
+ Lakewood CO 80228
+ US
+
+70-B3-D5 (hex) De Haardt bv
+CA2000-CA2FFF (base 16) De Haardt bv
+ Marithaime 6
+ Elst 6662 WD
+ NL
+
+70-B3-D5 (hex) Colorimetry Research, Inc
+10E000-10EFFF (base 16) Colorimetry Research, Inc
+ 26612 Heirloom Place
+ Santa Clarita CA 91350
+ US
70-B3-D5 (hex) EMAC, Inc.
8AB000-8ABFFF (base 16) EMAC, Inc.
@@ -12065,12 +12482,6 @@ C97000-C97FFF (base 16) CSINFOTEL Daejeon Republic of Korea 305-340
KR
-70-B3-D5 (hex) Riegl Laser Measurement Systems GmbH
-F10000-F10FFF (base 16) Riegl Laser Measurement Systems GmbH
- Riedenburgstrasse 48
- Horn Lower Austria 3580
- AT
-
70-B3-D5 (hex) Twoway Communications, Inc.
4AA000-4AAFFF (base 16) Twoway Communications, Inc.
41 Wu Kung 6 Rd., New Taipei Industrial Park, New Taipei City,24891,Taiwan,R.O.C.
@@ -12917,12 +13328,6 @@ AE1000-AE1FFF (base 16) DimoCore Corporation Dachau 85221
DE
-70-B3-D5 (hex) Sicon srl
-30C000-30CFFF (base 16) Sicon srl
- Via Sila 1/3
- Isola Vicentina Vicenza 36033
- IT
-
70-B3-D5 (hex) ANTEK GmbH
90C000-90CFFF (base 16) ANTEK GmbH
Im Koechersgrund 3
@@ -13205,12 +13610,6 @@ CCC000-CCCFFF (base 16) AEC s.r.l. Creazzo Vicenza 36051
IT
-70-B3-D5 (hex) Sicon srl
-3B2000-3B2FFF (base 16) Sicon srl
- Via Sila 1/3
- Isola Vicentina Vicenza 36033
- IT
-
70-B3-D5 (hex) GWF MessSysteme AG
387000-387FFF (base 16) GWF MessSysteme AG
Obergrundstrasse 119
@@ -13403,6 +13802,393 @@ F95000-F95FFF (base 16) Get SAT Casazza Lombardia 24060
IT
+70-B3-D5 (hex) SureFlap Ltd
+F9C000-F9CFFF (base 16) SureFlap Ltd
+ 7 The Irwin Centre, Scotland Road, Dry Drayton
+ Cambridge Cambridgeshire CB23 8AR
+ GB
+
+70-B3-D5 (hex) Private
+279000-279FFF (base 16) Private
+
+70-B3-D5 (hex) NETWAYS GmbH
+73D000-73DFFF (base 16) NETWAYS GmbH
+ Deutschherrnstraße 15
+ Nürnberg 90429
+ DE
+
+70-B3-D5 (hex) The Dini Group, La Jolla inc.
+678000-678FFF (base 16) The Dini Group, La Jolla inc.
+ 7469 Draper Ave.
+ La Jolla CA 92037
+ US
+
+70-B3-D5 (hex) Uwinloc
+D6B000-D6BFFF (base 16) Uwinloc
+ 57 Avenue Jean Monnet
+ Colomiers 31770
+ FR
+
+70-B3-D5 (hex) PHPower Srl
+A3F000-A3FFFF (base 16) PHPower Srl
+ Via Borgonuovo 27
+ Milano MI 20121
+ IT
+
+70-B3-D5 (hex) Rtone
+5F3000-5F3FFF (base 16) Rtone
+ 120 rue de Saint cyr
+ Lyon 69009
+ FR
+
+70-B3-D5 (hex) FreeFlight Systems
+5F6000-5F6FFF (base 16) FreeFlight Systems
+ 8150 Springwood Drive, Suite 100
+ Irving TX 75063
+ US
+
+70-B3-D5 (hex) MI Inc.
+D26000-D26FFF (base 16) MI Inc.
+ 6F, Toto building, 5-1-4, Toranomon, Minato-ku
+ Tokyo 1050001
+ JP
+
+70-B3-D5 (hex) TOSEI ENGINEERING CORP.
+24B000-24BFFF (base 16) TOSEI ENGINEERING CORP.
+ 4-6, Higashi-Nakanuki-machi
+ Tsuchiura-city Ibaraki 300-0006
+ JP
+
+70-B3-D5 (hex) Maharsystem
+72E000-72EFFF (base 16) Maharsystem
+ No 1, 5th Alley ,Ozgol , Artesh Blvd
+ Tehran Tehran 1694937141
+ IR
+
+70-B3-D5 (hex) Cannex Technology Inc.
+CD1000-CD1FFF (base 16) Cannex Technology Inc.
+ No.182, Sec.2, Yuanlu Rd.
+ Sihu Changhua 51449
+ TW
+
+70-B3-D5 (hex) Mettler Toledo
+4FC000-4FCFFF (base 16) Mettler Toledo
+ 6005 Benjamin Road
+ Tampa FL 33634
+ US
+
+70-B3-D5 (hex) NAS Australia P/L
+E91000-E91FFF (base 16) NAS Australia P/L
+ 28 Newstead Terrace
+ Newstead QLD 4006
+ AU
+
+70-B3-D5 (hex) Toughdog Security Systems
+A32000-A32FFF (base 16) Toughdog Security Systems
+ 1317 E Hackberry Ave
+ McAllen TX 78501
+ US
+
+70-B3-D5 (hex) Lode BV
+716000-716FFF (base 16) Lode BV
+ Zernikepark 16
+ Groningen 9747 AN
+ NL
+
+70-B3-D5 (hex) Fater Rasa Noor
+5F1000-5F1FFF (base 16) Fater Rasa Noor
+ Damavand St. , Between Khaghani and Ayat station, Hadi Building, no.499, second floor
+ Tehran Tehran 0098
+ IR
+
+70-B3-D5 (hex) Schneider Electric Motion USA
+153000-153FFF (base 16) Schneider Electric Motion USA
+ 370 N. Main St.
+ Marlborough CT 06447
+ US
+
+70-B3-D5 (hex) BioBusiness
+A08000-A08FFF (base 16) BioBusiness
+ 4 Elsafwa Towers, Ellebiny st, Mariutia Haram
+ Giza Cairo 12111
+ EG
+
+70-B3-D5 (hex) nyantec GmbH
+C6F000-C6FFFF (base 16) nyantec GmbH
+ Europaplatz 2
+ Berlin 10557
+ DE
+
+70-B3-D5 (hex) CE LINK LIMITED
+547000-547FFF (base 16) CE LINK LIMITED
+ 2/F, Building G, Licheng Tech. Ind. Zone
+ Shenzhen Guangdong 518104
+ CN
+
+70-B3-D5 (hex) Embedded Arts Co., Ltd.
+0C6000-0C6FFF (base 16) Embedded Arts Co., Ltd.
+ 1-1-6 Ryousoutuuun Bldg. 2F
+ Kisarazu-shi Chiba 292-0067
+ JP
+
+70-B3-D5 (hex) IDEM INC.
+DC6000-DC6FFF (base 16) IDEM INC.
+ 17302 Daimler St. STE A
+ Irvine CA 92614
+ US
+
+70-B3-D5 (hex) JL World Corporation Limited
+D54000-D54FFF (base 16) JL World Corporation Limited
+ Unit 20, 5/F., Block B, Proficient Industrial Centre
+ Kowloon Bay 0000
+ HK
+
+70-B3-D5 (hex) Landis Gyr
+0B6000-0B6FFF (base 16) Landis Gyr
+ Hasdrubal Bellegard, 400, CIC
+ Curitiba Paraná 81460120
+ BR
+
+70-B3-D5 (hex) Ofil USA
+9E2000-9E2FFF (base 16) Ofil USA
+ 5415 Sugarloaf Parkway Suite 1102 A&B
+ Lawrenceville GA 30043
+ US
+
+70-B3-D5 (hex) WeWork Companies, Inc.
+2CC000-2CCFFF (base 16) WeWork Companies, Inc.
+ 115 W 18th St
+ New York NY 10011
+ US
+
+70-B3-D5 (hex) Hagenuk KMT Kabelmesstechnik GmbH
+132000-132FFF (base 16) Hagenuk KMT Kabelmesstechnik GmbH
+ Röderaue 41
+ Radeburg Sachsen 01471
+ DE
+
+70-B3-D5 (hex) Critical Link LLC
+D5C000-D5CFFF (base 16) Critical Link LLC
+ 6712 Brooklawn Parkway
+ Syracuse 13211
+ US
+
+70-B3-D5 (hex) Critical Link LLC
+EF9000-EF9FFF (base 16) Critical Link LLC
+ 6712 Brooklawn Pkwy
+ Syracuse NY 13211
+ US
+
+70-B3-D5 (hex) QUERCUS TECHNOLOGIES, S.L.
+777000-777FFF (base 16) QUERCUS TECHNOLOGIES, S.L.
+ Av. Onze de Setembre 19
+ Reus Tarragona 43203
+ ES
+
+70-B3-D5 (hex) White Matter LLC
+368000-368FFF (base 16) White Matter LLC
+ 999 3rd Ave 700
+ Seattle 98104
+ US
+
+70-B3-D5 (hex) iFreecomm Technology Co., Ltd
+032000-032FFF (base 16) iFreecomm Technology Co., Ltd
+ D401, NO.16 Langshan Road, Nanshan District
+ Shenzhen Guangdong 518057
+ CN
+
+70-B3-D5 (hex) RELISTE Ges.m.b.H.
+1B9000-1B9FFF (base 16) RELISTE Ges.m.b.H.
+ Enzersdorfer Strasse 8-10
+ Brunn am Gebirge 2345
+ AT
+
+70-B3-D5 (hex) JUSTEK INC
+EB5000-EB5FFF (base 16) JUSTEK INC
+ 613-9, DONGCHUN-RI, JINWI-MYEON
+ PYEONGTAEK-SI GYEONGGI-DO 17711
+ KR
+
+70-B3-D5 (hex) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+94A000-94AFFF (base 16) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
+ No.826,Zone 1,Block B,Famous industrial product display purchasing center,Baoyuan Road,Xixiang,Bao'an Dis., Shenzhen,P.R.China
+ shenzhen China 518102
+ CN
+
+70-B3-D5 (hex) Mo-Sys Engineering Ltd
+075000-075FFF (base 16) Mo-Sys Engineering Ltd
+ Thames Bank House, Tunnel Avenue
+ London SE100PA
+ GB
+
+70-B3-D5 (hex) Abbas, a.s.
+B18000-B18FFF (base 16) Abbas, a.s.
+ Edisonova 5
+ Brno CZ 61200
+ CZ
+
+70-B3-D5 (hex) Shanghai Holystar Information Technology Co.,Ltd
+6E1000-6E1FFF (base 16) Shanghai Holystar Information Technology Co.,Ltd
+ 8F Building A3 NO.1528 Gumei Rd Shanghai China PR
+ shanghai 200233
+ CN
+
+70-B3-D5 (hex) Mimo Networks
+25D000-25DFFF (base 16) Mimo Networks
+ 701 E Middlefield Road Mountain View,
+ Mountain View CA 94043
+ US
+
+70-B3-D5 (hex) ATBiS Co.,Ltd
+C2F000-C2FFFF (base 16) ATBiS Co.,Ltd
+ #1603 5th. Ace High-end Tower, 226 Gasan Digital 1-ro, Geumcheon-gu
+ Seoul 08502
+ KR
+
+70-B3-D5 (hex) Cyanview
+E3A000-E3AFFF (base 16) Cyanview
+ 26, Rue de la Foire
+ Papignies 7861
+ BE
+
+70-B3-D5 (hex) Valk Welding B.V.
+5DA000-5DAFFF (base 16) Valk Welding B.V.
+ Staalindustrieweg 15
+ Alblasserdam Zuid Holland 2952 AT
+ NL
+
+70-B3-D5 (hex) AdInte, inc.
+BAC000-BACFFF (base 16) AdInte, inc.
+ 347-1, Shijo-cho, Shimogyo-ku, 7F CUBE Nishikarasuma BLDG.
+ Kyoto-shi Kyoto 6008441
+ JP
+
+70-B3-D5 (hex) VITEC
+CDA000-CDAFFF (base 16) VITEC
+ 99 rue pierre sémard
+ Chatillon France 92320
+ FR
+
+70-B3-D5 (hex) Nortek Global HVAC
+4D4000-4D4FFF (base 16) Nortek Global HVAC
+ Fens Pool Ave
+ Brierley Hill West Midlands DY5 1QA
+ GB
+
+70-B3-D5 (hex) Insitu, Inc
+7AD000-7ADFFF (base 16) Insitu, Inc
+ 118 E Columbia River Way
+ Bingen WA 98605
+ US
+
+70-B3-D5 (hex) KWS-Electronic GmbH
+EB3000-EB3FFF (base 16) KWS-Electronic GmbH
+ Sportplatzstrasse 1
+ Grosskarolinenfeld D-83109
+ DE
+
+70-B3-D5 (hex) University Of Groningen
+700000-700FFF (base 16) University Of Groningen
+ Broerstraat 5
+ Groningen Groningen 9712 CP
+ NL
+
+70-B3-D5 (hex) Triton Electronics Ltd
+7A5000-7A5FFF (base 16) Triton Electronics Ltd
+ Bigods Hall, Bigods Lane
+ DUNMOW Essex CM63BE
+ GB
+
+70-B3-D5 (hex) ETON Deutschland Electro Acoustic GmbH
+213000-213FFF (base 16) ETON Deutschland Electro Acoustic GmbH
+ Pfaffenweg 21
+ Neu-Ulm Bavaria 89231
+ DE
+
+70-B3-D5 (hex) Globalcom Engineering SPA
+A0D000-A0DFFF (base 16) Globalcom Engineering SPA
+ Via Volta 39
+ CARDANO AL CAMPO VA 21010
+ IT
+
+70-B3-D5 (hex) Monnit Corporation
+236000-236FFF (base 16) Monnit Corporation
+ 3400 S West Temple
+ Salt Lake City 84115
+ US
+
+70-B3-D5 (hex) Advice
+810000-810FFF (base 16) Advice
+ 16 Atir Yeda St
+ Kfar Saba Not applicable 4464321
+ IL
+
+70-B3-D5 (hex) Triax A/S
+963000-963FFF (base 16) Triax A/S
+ Bjornkaervej 3
+ Hornsyld Denmark 8783
+ DK
+
+70-B3-D5 (hex) Sicon srl
+30C000-30CFFF (base 16) Sicon srl
+ Via Sila 1/3
+ Isola Vicentina Vicenza 36033
+ IT
+
+70-B3-D5 (hex) Sicon srl
+3B2000-3B2FFF (base 16) Sicon srl
+ Via Sila 1/3
+ Isola Vicentina Vicenza 36033
+ IT
+
+70-B3-D5 (hex) Sicon srl
+A35000-A35FFF (base 16) Sicon srl
+ Via Sila 1/3
+ Isola Vicentina Vicenza 36033
+ IT
+
+70-B3-D5 (hex) G+D Mobile Security
+024000-024FFF (base 16) G+D Mobile Security
+ C/ 114 nº 27, Polígon Pratenc
+ El Prat de Llobregat Barcelona E-08820
+ ES
+
+70-B3-D5 (hex) Sicon srl
+145000-145FFF (base 16) Sicon srl
+ Via Sila 1/3
+ Isola Vicentina Vicenza 36033
+ IT
+
+70-B3-D5 (hex) E-MetroTel
+FF0000-FF0FFF (base 16) E-MetroTel
+ 2828 West Parker Unit B201
+ Plano TX 75075
+ US
+
+70-B3-D5 (hex) Silex Inside
+3BA000-3BAFFF (base 16) Silex Inside
+ rue du bosquet 7
+ LouvainlaNeuve Brabant 1348
+ BE
+
+70-B3-D5 (hex) Yaham Optoelectronics Co., Ltd
+2FE000-2FEFFF (base 16) Yaham Optoelectronics Co., Ltd
+ Bldg A & Bldg D, Yongwei Industrial Park,#118 Yongfu Rd, Qiaotou Community, Fuyong,Bao'an District,Shenzhen
+ Shenzhen Bao'an District/GuangDong 518103
+ CN
+
+70-B3-D5 (hex) Shandong Hospot IOT Technology Co.,Ltd.
+576000-576FFF (base 16) Shandong Hospot IOT Technology Co.,Ltd.
+ No.96 Road Fuyang
+ Rizhao Shandong 276800
+ CN
+
+70-B3-D5 (hex) Brakels IT
+54B000-54BFFF (base 16) Brakels IT
+ Veldboersweg 10a
+ Langeveen Overijssel 7679TL
+ NL
+
70-B3-D5 (hex) Apantac LLC
CD5000-CD5FFF (base 16) Apantac LLC
7556 SW Bridgeport Road
@@ -13964,12 +14750,6 @@ D43000-D43FFF (base 16) EZSYS Co., Ltd. Gwangmyeong-si Gyeonggi-do 14322
KR
-70-B3-D5 (hex) Sicon srl
-A35000-A35FFF (base 16) Sicon srl
- Via Sila 1/3
- Isola Vicentina Vicenza 36033
- IT
-
70-B3-D5 (hex) Boutronic
359000-359FFF (base 16) Boutronic
Edisonstraat 24
@@ -14024,305 +14804,32 @@ EC7000-EC7FFF (base 16) Neoptix Inc. Kosice-Krasna 04018
SK
-70-B3-D5 (hex) SureFlap Ltd
-F9C000-F9CFFF (base 16) SureFlap Ltd
- 7 The Irwin Centre, Scotland Road, Dry Drayton
- Cambridge Cambridgeshire CB23 8AR
- GB
-
-70-B3-D5 (hex) Private
-279000-279FFF (base 16) Private
-
-70-B3-D5 (hex) NETWAYS GmbH
-73D000-73DFFF (base 16) NETWAYS GmbH
- Deutschherrnstraße 15
- Nürnberg 90429
- DE
-
-70-B3-D5 (hex) The Dini Group, La Jolla inc.
-678000-678FFF (base 16) The Dini Group, La Jolla inc.
- 7469 Draper Ave.
- La Jolla CA 92037
- US
-
-70-B3-D5 (hex) Uwinloc
-D6B000-D6BFFF (base 16) Uwinloc
- 57 Avenue Jean Monnet
- Colomiers 31770
- FR
-
-70-B3-D5 (hex) PHPower Srl
-A3F000-A3FFFF (base 16) PHPower Srl
- Via Borgonuovo 27
- Milano MI 20121
- IT
-
-70-B3-D5 (hex) Rtone
-5F3000-5F3FFF (base 16) Rtone
- 120 rue de Saint cyr
- Lyon 69009
- FR
-
-70-B3-D5 (hex) FreeFlight Systems
-5F6000-5F6FFF (base 16) FreeFlight Systems
- 8150 Springwood Drive, Suite 100
- Irving TX 75063
- US
-
-70-B3-D5 (hex) MI Inc.
-D26000-D26FFF (base 16) MI Inc.
- 6F, Toto building, 5-1-4, Toranomon, Minato-ku
- Tokyo 1050001
- JP
-
-70-B3-D5 (hex) TOSEI ENGINEERING CORP.
-24B000-24BFFF (base 16) TOSEI ENGINEERING CORP.
- 4-6, Higashi-Nakanuki-machi
- Tsuchiura-city Ibaraki 300-0006
- JP
-
-70-B3-D5 (hex) Maharsystem
-72E000-72EFFF (base 16) Maharsystem
- No 1, 5th Alley ,Ozgol , Artesh Blvd
- Tehran Tehran 1694937141
- IR
-
-70-B3-D5 (hex) Cannex Technology Inc.
-CD1000-CD1FFF (base 16) Cannex Technology Inc.
- No.182, Sec.2, Yuanlu Rd.
- Sihu Changhua 51449
- TW
-
-70-B3-D5 (hex) Mettler Toledo
-4FC000-4FCFFF (base 16) Mettler Toledo
- 6005 Benjamin Road
- Tampa FL 33634
- US
-
-70-B3-D5 (hex) NAS Australia P/L
-E91000-E91FFF (base 16) NAS Australia P/L
- 28 Newstead Terrace
- Newstead QLD 4006
- AU
-
-70-B3-D5 (hex) Toughdog Security Systems
-A32000-A32FFF (base 16) Toughdog Security Systems
- 1317 E Hackberry Ave
- McAllen TX 78501
- US
-
-70-B3-D5 (hex) Lode BV
-716000-716FFF (base 16) Lode BV
- Zernikepark 16
- Groningen 9747 AN
- NL
-
-70-B3-D5 (hex) Fater Rasa Noor
-5F1000-5F1FFF (base 16) Fater Rasa Noor
- Damavand St. , Between Khaghani and Ayat station, Hadi Building, no.499, second floor
- Tehran Tehran 0098
- IR
-
-70-B3-D5 (hex) Schneider Electric Motion USA
-153000-153FFF (base 16) Schneider Electric Motion USA
- 370 N. Main St.
- Marlborough CT 06447
- US
-
-70-B3-D5 (hex) BioBusiness
-A08000-A08FFF (base 16) BioBusiness
- 4 Elsafwa Towers, Ellebiny st, Mariutia Haram
- Giza Cairo 12111
- EG
-
-70-B3-D5 (hex) nyantec GmbH
-C6F000-C6FFFF (base 16) nyantec GmbH
- Europaplatz 2
- Berlin 10557
- DE
-
-70-B3-D5 (hex) CE LINK LIMITED
-547000-547FFF (base 16) CE LINK LIMITED
- 2/F, Building G, Licheng Tech. Ind. Zone
- Shenzhen Guangdong 518104
- CN
-
-70-B3-D5 (hex) Embedded Arts Co., Ltd.
-0C6000-0C6FFF (base 16) Embedded Arts Co., Ltd.
- 1-1-6 Ryousoutuuun Bldg. 2F
- Kisarazu-shi Chiba 292-0067
- JP
-
-70-B3-D5 (hex) IDEM INC.
-DC6000-DC6FFF (base 16) IDEM INC.
- 17302 Daimler St. STE A
- Irvine CA 92614
- US
-
-70-B3-D5 (hex) JL World Corporation Limited
-D54000-D54FFF (base 16) JL World Corporation Limited
- Unit 20, 5/F., Block B, Proficient Industrial Centre
- Kowloon Bay 0000
- HK
-
-70-B3-D5 (hex) Landis Gyr
-0B6000-0B6FFF (base 16) Landis Gyr
- Hasdrubal Bellegard, 400, CIC
- Curitiba Paraná 81460120
- BR
-
-70-B3-D5 (hex) Ofil USA
-9E2000-9E2FFF (base 16) Ofil USA
- 5415 Sugarloaf Parkway Suite 1102 A&B
- Lawrenceville GA 30043
- US
-
-70-B3-D5 (hex) WeWork Companies, Inc.
-2CC000-2CCFFF (base 16) WeWork Companies, Inc.
- 115 W 18th St
- New York NY 10011
- US
-
-70-B3-D5 (hex) Hagenuk KMT Kabelmesstechnik GmbH
-132000-132FFF (base 16) Hagenuk KMT Kabelmesstechnik GmbH
- Röderaue 41
- Radeburg Sachsen 01471
- DE
-
-70-B3-D5 (hex) Critical Link LLC
-D5C000-D5CFFF (base 16) Critical Link LLC
- 6712 Brooklawn Parkway
- Syracuse 13211
- US
-
-70-B3-D5 (hex) Critical Link LLC
-EF9000-EF9FFF (base 16) Critical Link LLC
- 6712 Brooklawn Pkwy
- Syracuse NY 13211
- US
-
-70-B3-D5 (hex) QUERCUS TECHNOLOGIES, S.L.
-777000-777FFF (base 16) QUERCUS TECHNOLOGIES, S.L.
- Av. Onze de Setembre 19
- Reus Tarragona 43203
- ES
-
-70-B3-D5 (hex) Triax A/S
-963000-963FFF (base 16) Triax A/S
- Bjornkaervej 3
- Hornsyld Denmark 8783
- DK
-
-70-B3-D5 (hex) White Matter LLC
-368000-368FFF (base 16) White Matter LLC
- 999 3rd Ave 700
- Seattle 98104
+70-B3-D5 (hex) Vitro Technology Corporation
+F19000-F19FFF (base 16) Vitro Technology Corporation
+ Box 91232
+ Austin TX 78709-1232
US
-70-B3-D5 (hex) iFreecomm Technology Co., Ltd
-032000-032FFF (base 16) iFreecomm Technology Co., Ltd
- D401, NO.16 Langshan Road, Nanshan District
- Shenzhen Guangdong 518057
- CN
-
-70-B3-D5 (hex) RELISTE Ges.m.b.H.
-1B9000-1B9FFF (base 16) RELISTE Ges.m.b.H.
- Enzersdorfer Strasse 8-10
- Brunn am Gebirge 2345
+70-B3-D5 (hex) Riegl Laser Measurement Systems GmbH
+F10000-F10FFF (base 16) Riegl Laser Measurement Systems GmbH
+ Riedenburgstrasse 48
+ Horn Lower Austria 3580
AT
-70-B3-D5 (hex) JUSTEK INC
-EB5000-EB5FFF (base 16) JUSTEK INC
- 613-9, DONGCHUN-RI, JINWI-MYEON
- PYEONGTAEK-SI GYEONGGI-DO 17711
- KR
-
-70-B3-D5 (hex) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
-94A000-94AFFF (base 16) SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD
- No.826,Zone 1,Block B,Famous industrial product display purchasing center,Baoyuan Road,Xixiang,Bao'an Dis., Shenzhen,P.R.China
- shenzhen China 518102
- CN
-
-70-B3-D5 (hex) Mo-Sys Engineering Ltd
-075000-075FFF (base 16) Mo-Sys Engineering Ltd
- Thames Bank House, Tunnel Avenue
- London SE100PA
- GB
+70-B3-D5 (hex) M.T. S.R.L.
+141000-141FFF (base 16) M.T. S.R.L.
+ VIA MONZA 83
+ GESSATE 20060
+ IT
-70-B3-D5 (hex) Abbas, a.s.
-B18000-B18FFF (base 16) Abbas, a.s.
- Edisonova 5
- Brno CZ 61200
- CZ
+70-B3-D5 (hex) Ariston Thermo s.p.a.
+C11000-C11FFF (base 16) Ariston Thermo s.p.a.
+ Via Aristide Merloni 45
+ Fabriano Ancona 60044
+ IT
-70-B3-D5 (hex) Shanghai Holystar Information Technology Co.,Ltd
-6E1000-6E1FFF (base 16) Shanghai Holystar Information Technology Co.,Ltd
- 8F Building A3 NO.1528 Gumei Rd Shanghai China PR
- shanghai 200233
+70-B3-D5 (hex) Walk Horizon Technology (Beijing) Co., Ltd.
+154000-154FFF (base 16) Walk Horizon Technology (Beijing) Co., Ltd.
+ Rm121 B1 Shouxindasha Building, 5 Jiangtailu Rd., Chaoyang District
+ Beijing 100015
CN
-
-70-B3-D5 (hex) Mimo Networks
-25D000-25DFFF (base 16) Mimo Networks
- 701 E Middlefield Road Mountain View,
- Mountain View CA 94043
- US
-
-70-B3-D5 (hex) ATBiS Co.,Ltd
-C2F000-C2FFFF (base 16) ATBiS Co.,Ltd
- #1603 5th. Ace High-end Tower, 226 Gasan Digital 1-ro, Geumcheon-gu
- Seoul 08502
- KR
-
-70-B3-D5 (hex) Cyanview
-E3A000-E3AFFF (base 16) Cyanview
- 26, Rue de la Foire
- Papignies 7861
- BE
-
-70-B3-D5 (hex) AdInte, inc.
-BAC000-BACFFF (base 16) AdInte, inc.
- 347-1, Shijo-cho, Shimogyo-ku, 7F CUBE Nishikarasuma BLDG.
- Kyoto-shi Kyoto 6008441
- JP
-
-70-B3-D5 (hex) Valk Welding B.V.
-5DA000-5DAFFF (base 16) Valk Welding B.V.
- Staalindustrieweg 15
- Alblasserdam Zuid Holland 2952 AT
- NL
-
-70-B3-D5 (hex) VITEC
-CDA000-CDAFFF (base 16) VITEC
- 99 rue pierre sémard
- Chatillon France 92320
- FR
-
-70-B3-D5 (hex) Nortek Global HVAC
-4D4000-4D4FFF (base 16) Nortek Global HVAC
- Fens Pool Ave
- Brierley Hill West Midlands DY5 1QA
- GB
-
-70-B3-D5 (hex) Insitu, Inc
-7AD000-7ADFFF (base 16) Insitu, Inc
- 118 E Columbia River Way
- Bingen WA 98605
- US
-
-70-B3-D5 (hex) KWS-Electronic GmbH
-EB3000-EB3FFF (base 16) KWS-Electronic GmbH
- Sportplatzstrasse 1
- Grosskarolinenfeld D-83109
- DE
-
-70-B3-D5 (hex) University Of Groningen
-700000-700FFF (base 16) University Of Groningen
- Broerstraat 5
- Groningen Groningen 9712 CP
- NL
-
-70-B3-D5 (hex) Globalcom Engineering SPA
-A0D000-A0DFFF (base 16) Globalcom Engineering SPA
- Via Volta 39
- CARDANO AL CAMPO VA 21010
- IT
diff --git a/hwdb/pci.ids b/hwdb/pci.ids index f749ba4010..d6f8b1cf2f 100644 --- a/hwdb/pci.ids +++ b/hwdb/pci.ids @@ -1,8 +1,8 @@ # # List of PCI ID's # -# Version: 2017.12.06 -# Date: 2017-12-06 03:15:02 +# Version: 2018.01.14 +# Date: 2018-01-14 03:15:02 # # Maintained by Albert Pool, Martin Mares, and other volunteers from # the PCI ID Project at http://pci-ids.ucw.cz/. @@ -42,6 +42,7 @@ # nee nCipher 0100 Thales e-Security 0123 General Dynamics +0128 Dell (wrong ID) # 018a is not LevelOne but there is a board misprogrammed 018a LevelOne 0106 FPC-0106TX misprogrammed [RTL81xx] @@ -584,6 +585,7 @@ 0096 SAS3004 PCI-Express Fusion-MPT SAS-3 0097 SAS3008 PCI-Express Fusion-MPT SAS-3 1000 3090 SAS9311-8i + 1000 30a0 SAS9300-8e 1000 30e0 SAS9300-8i 1000 3130 SAS 9300-16i 1028 1f45 HBA330 Adapter @@ -749,7 +751,8 @@ 131b Kaveri [Radeon R4 Graphics] 131c Kaveri [Radeon R7 Graphics] 131d Kaveri [Radeon R6 Graphics] - 15dd Radeon Vega 8 Mobile + 15dd Vega [Radeon Vega 8 Mobile] + 15ff Vega [Radeon Vega 28 Mobile] 1714 BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series] 103c 168b ProBook 4535s 3150 RV380/M24 [Mobility Radeon X600] @@ -2267,6 +2270,7 @@ 67b9 Vesuvius [Radeon R9 295X2] 67be Hawaii LE 67c0 Ellesmere [Radeon Pro WX 7100] + 67c2 Ellesmere [Radeon Pro V7300X / V7350x2] 67c4 Ellesmere [Radeon Pro WX 7100] 1002 0336 Radeon Pro Duo 1002 1336 Radeon Pro Duo @@ -2274,6 +2278,7 @@ 67ca Ellesmere [Polaris10] 67cc Ellesmere [Polaris10] 67cf Ellesmere [Polaris10] + 67d0 Ellesmere [Radeon Pro V7300X / V7350x2] 67df Ellesmere [Radeon RX 470/480/570/580] 1002 0b37 Radeon RX 480 1043 04a8 Radeon RX 480 @@ -2293,13 +2298,13 @@ 1787 a470 Radeon RX 470 1787 a480 Radeon RX 480 1da2 e353 Sapphire Radeon RX 580 Pulse 8GB - 1da2 e366 Radeon RX 570 + 1da2 e366 Nitro+ Radeon RX 580 4GB 67e0 Baffin [Polaris11] 67e1 Baffin [Polaris11] 67e3 Baffin [Radeon Pro WX 4100] 67e8 Baffin [Polaris11] 67e9 Baffin [Polaris11] - 67eb Baffin [Polaris11] + 67eb Baffin [Radeon Pro V5300X] 67ef Baffin [Radeon RX 460/560D / Pro 450/455/460/560] 106b 0160 Radeon Pro 460 106b 0166 Radeon Pro 455 @@ -2343,6 +2348,7 @@ 1002 0b05 Radeon HD 8870 OEM 174b 8b04 Radeon HD 8860 6819 Pitcairn PRO [Radeon HD 7850 / R7 265 / R9 270 1024SP] + 1043 042c Radeon HD 7850 1682 7269 Radeon R9 270 1024SP 1682 9278 Radeon R9 270 1024SP 174b a008 Radeon R9 270 1024SP @@ -2505,8 +2511,14 @@ 144d c0c7 Radeon HD 7550M 6842 Thames LE [Radeon HD 7000M Series] 6843 Thames [Radeon HD 7670M] + 6860 Vega 10 [Radeon Instinct MI25] 6861 Vega 10 XT [Radeon PRO WX 9100] + 6862 Vega 10 XT [Radeon PRO SSG] 6863 Vega 10 XTX [Radeon Vega Frontier Edition] + 6864 Vega + 6867 Vega + 6868 Vega + 686c Vega 10 [Radeon Instinct MI25 MxGPU] 687f Vega 10 XT [Radeon RX Vega 64] 6888 Cypress XT [FirePro V8800] 6889 Cypress PRO [FirePro V7800] @@ -3015,11 +3027,12 @@ 148c 9380 Radeon R9 380 # Make naming scheme consistent 174b e308 Radeon R9 380 Nitro 4G D5 + 694c Vega [Radeon RX Vega M] 6980 Polaris12 6981 Polaris12 6985 Lexa XT [Radeon PRO WX 3100] 6986 Polaris12 - 6987 Polaris12 + 6987 Lexa [Radeon E9171 MCM] 6995 Lexa XT [Radeon PRO WX 2100] 699f Lexa PRO [Radeon RX 550] 148c 2380 Lexa XL [Radeon RX 550] @@ -4041,6 +4054,11 @@ 1423 Family 15h (Models 30h-3fh) I/O Memory Management Unit 1424 Family 15h (Models 30h-3fh) Processor Root Port 1426 Family 15h (Models 30h-3fh) Processor Root Port + 142e Liverpool Processor Function 0 + 142f Liverpool Processor Function 1 + 1430 Liverpool Processor Function 2 + 1431 Liverpool Processor Function 3 + 1432 Liverpool Processor Function 4 1436 Liverpool Processor Root Complex 1437 Liverpool I/O Memory Management Unit 1438 Liverpool Processor Root Port @@ -5439,10 +5457,11 @@ 1028 014e PCI7410,7510,7610 OHCI-Lynx Controller (Latitude D800) 802e PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller 1028 018d Inspiron 700m/710m - 8031 PCIxx21/x515 Cardbus Controller + 8031 PCIxx21/PCIxx11/PCIx515 PC Card Controller 1025 0064 Extensa 3000 series laptop 1025 0080 Aspire 5024WLMi 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 103c 308b MX6125 8032 OHCI Compliant IEEE 1394 Host Controller @@ -5451,19 +5470,22 @@ 103c 0934 Compaq nw8240/nx8220 103c 099c NX6110/NC6120 103c 308b MX6125 - 8033 PCIxx21 Integrated FlashMedia Controller + 8033 PCIxx21/PCIxx11 Flash Media Controller 1025 0064 Extensa 3000 series laptop 1025 0080 Aspire 5024WLMi 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 103c 308b MX6125 - 8034 PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller + 8034 PCIxx21/PCIxx11 SD Host Controller 1025 0080 Aspire 5024WLMi 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 103c 308b MX6125 - 8035 PCI6411/6421/6611/6621/7411/7421/7611/7621 Smart Card Controller + 8035 PCIxx21/PCIxx11 Smart Card Controller 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 8036 PCI6515 Cardbus Controller 8038 PCI6515 SmartCard Controller @@ -5477,7 +5499,7 @@ 103c 30a1 NC2400 103c 30a3 Compaq nw8440 104d 902d VAIO VGN-NR120E - 803b 5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) + 803b PCIxx12 Flash Media Controller 103c 309f nx9420 103c 30a3 Compaq nw8440 104d 8212 VAIO VGN-N21E @@ -5650,6 +5672,22 @@ 90a3 Aeolia Memory (DDR3/SPM) 90a4 Aeolia USB 3.0 xHCI Host Controller 90bc SxS Pro+ memory card + 90c8 Belize ACPI + 90c9 Belize Ethernet Controller + 90ca Belize SATA AHCI Controller + 90cb Belize SD/MMC Host Controller + 90cc Belize PCI Express Glue and Miscellaneous Devices + 90cd Belize DMA Controller + 90ce Belize Memory (DDR3/SPM) + 90cf Belize USB 3.0 xHCI Host Controller + 90d7 Baikal ACPI + 90d8 Baikal Ethernet Controller + 90d9 Baikal SATA AHCI Controller + 90da Baikal SD/MMC Host Controller + 90db Baikal PCI Express Glue and Miscellaneous Devices + 90dc Baikal DMA Controller + 90dd Baikal Memory (DDR3/SPM) + 90de Baikal USB 3.0 xHCI Host Controller 104e Oak Technology, Inc 0017 OTI-64017 0107 OTI-107 [Spitfire] @@ -6230,6 +6268,10 @@ 8070 FastLinQ QL41000 Series 10/25/40/50GbE Controller 1077 0001 10GE 2P QL41162HxRJ-DE Adapter 1077 0002 10GE 2P QL41112HxCU-DE Adapter + 1077 0005 QLogic 4x10GE QL41164HMRJ CNA + 1077 0006 QLogic 4x10GE QL41164HMCU CNA + 1077 0007 QLogic 2x1GE+2x10GE QL41264HMCU CNA + 1077 0009 QLogic 2x1GE+2x10GE QL41162HMRJ CNA 1077 000b 25GE 2P QL41262HxCU-DE Adapter 1077 0011 FastLinQ QL41212H 25GbE Adapter 1077 0012 FastLinQ QL41112H 10GbE Adapter @@ -6240,19 +6282,34 @@ 8080 FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) 1077 0001 10GE 2P QL41162HxRJ-DE Adapter 1077 0002 10GE 2P QL41112HxCU-DE Adapter + 1077 0005 QLogic 4x10GE QL41164HMRJ CNA + 1077 0006 QLogic 4x10GE QL41164HMCU CNA + 1077 0007 QLogic 2x1GE+2x10GE QL41264HMCU CNA + 1077 0009 QLogic 2x1GE+2x10GE QL41162HMRJ CNA 1077 000b 25GE 2P QL41262HxCU-DE Adapter + 1077 000c QLogic 2x25GE QL41262HMCU CNA 1077 000d FastLinQ QL41262H 25GbE FCoE Adapter 1077 000e FastLinQ QL41162H 10GbE FCoE Adapter 8084 FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) 1077 0001 10GE 2P QL41162HxRJ-DE Adapter 1077 0002 10GE 2P QL41112HxCU-DE Adapter + 1077 0005 QLogic 4x10GE QL41164HMRJ CNA + 1077 0006 QLogic 4x10GE QL41164HMCU CNA + 1077 0007 QLogic 2x25GE QL41262HMCU CNA + 1077 0009 QLogic 2x1GE+2x10GE QL41162HMRJ CNA 1077 000b 25GE 2P QL41262HxCU-DE Adapter + 1077 000c QLogic 2x25GE QL41262HMCU CNA 1077 000d FastLinQ QL41262H 25GbE iSCSI Adapter 1077 000e FastLinQ QL41162H 10GbE iSCSI Adapter 8090 FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) 1077 0001 25GE 2P QL41262HxCU-DE Adapter 1077 0002 10GE 2P QL41112HxCU-DE Adapter + 1077 0005 QLogic 4x10GE QL41164HMRJ CNA + 1077 0006 QLogic 4x10GE QL41164HMCU CNA + 1077 0007 QLogic 2x1GE+2x10GE QL41264HMCU CNA + 1077 0009 QLogic 2x1GE+2x10GE QL41162HMRJ CNA 1077 000b 25GE 2P QL41262HxCU-DE Adapter + 1077 000c QLogic 2x25GE QL41262HMCU CNA 1077 000d FastLinQ QL41262H 25GbE FCoE Adapter (SR-IOV VF) 1077 000e FastLinQ QL41162H 10GbE iSCSI Adapter (SR-IOV VF) 1077 0011 FastLinQ QL41212H 25GbE Adapter (SR-IOV VF) @@ -10834,11 +10891,12 @@ 13d8 GM204M [GeForce GTX 970M] 13d9 GM204M [GeForce GTX 965M] 13da GM204M [GeForce GTX 980 Mobile] - 13e7 GM204 [GeForce GTX 980 Engineering Sample] + 13e7 GM204GL [GeForce GTX 980 Engineering Sample] 13f0 GM204GL [Quadro M5000] 13f1 GM204GL [Quadro M4000] 13f2 GM204GL [Tesla M60] 13f3 GM204GL [Tesla M6] + 10de 1184 GRID M6-8Q 13f8 GM204GLM [Quadro M5000M / M5000 SE] 13f9 GM204GLM [Quadro M4000M] 13fa GM204GLM [Quadro M3000M] @@ -10902,6 +10960,7 @@ 1bb7 GP104GLM [Quadro P4000 Mobile] 1462 11e9 Quadro P4000 Max-Q 1bb8 GP104GLM [Quadro P3000 Mobile] + 1bc7 GP104 [P104-101] 1be0 GP104M [GeForce GTX 1080 Mobile] 1028 07c0 GeForce GTX 1080 Max-Q 1458 355b GeForce GTX 1080 Max-Q @@ -10910,6 +10969,8 @@ 1c01 GP106 1c02 GP106 [GeForce GTX 1060 3GB] 1c03 GP106 [GeForce GTX 1060 6GB] + 1c04 GP106 [GeForce GTX 1060 5GB] + 1c06 GP106 [GeForce GTX 1060 6GB Rev. 2] 1c07 GP106 [P106-100] 1c09 GP106 [P106-090] 1c20 GP106M [GeForce GTX 1060 Mobile] @@ -10937,7 +10998,8 @@ 1cb3 GP107GL [Quadro P400] 1d01 GP108 [GeForce GT 1030] 1d10 GP108M [GeForce MX150] - 1d81 GV100 + 1d33 GP108GL [Quadro P500] + 1d81 GV100 [TITAN V] 1db1 GV100 [Tesla V100 SXM2] 1db4 GV100 [Tesla V100 PCIe] 10df Emulex Corporation @@ -10965,6 +11027,7 @@ e180 Proteus-X: LightPulse IOV Fibre Channel Host Adapter e200 LightPulse LPe16002 1014 03f1 PCIe2 16 Gb 2-port Fibre Channel Adapter (FC EL5B; CCIN 577F) + 10df e282 Flex System FC5054 4-port 16Gb FC Adapter e208 LightPulse 16Gb Fibre Channel Host Adapter (Lancer-VF) e220 OneConnect NIC (Lancer) 17aa 1054 ThinkServer LPm16002B-M6-L AnyFabric @@ -11139,13 +11202,14 @@ 8129 RTL-8129 10ec 8129 RT8129 Fast Ethernet Adapter 11ec 8129 RTL8111/8168 PCIe Gigabit Ethernet (misconfigured) - 8136 RTL8101/2/6E PCI Express Fast Ethernet controller + 8136 RTL810xE PCI Express Fast Ethernet controller 103c 1985 RTL8106E on Pavilion 17-e163sg Notebook PC 103c 2a8c Compaq 500B Microtower 103c 2ab1 Pavilion p6774 103c 30cc Pavilion dv6700 1179 ff64 RTL8102E PCI-E Fast Ethernet NIC 17c0 1053 RTL8101e Medion WIM 2210 Notebook PC [MD96850] + 8137 RTL8104E PCIe Fast Ethernet Controller 8138 RT8139 (B/C) Cardbus Fast Ethernet Adapter 10ec 8138 RT8139 (B/C) Fast Ethernet Adapter 8139 RTL-8100/8101L/8139 PCI Fast Ethernet Adapter @@ -14066,20 +14130,49 @@ 0043 RocketPort Infinity 16port, External Interface 0044 RocketPort Infinity Quad, 4port, DB 0045 RocketPort Infinity Octa, 8port, DB + 0046 RocketPort INFINITY 4-port w/external I/F 0047 RocketPort Infinity 4port, RJ45 + 0048 RocketPort INFINITY 4J (4-port) w/RJ45 connectors + 004a RocketPort INFINITY Plus 4-port + 004b RocketPort INFINITY Plus 8-port + 004c RocketModem INFINITY III 8-port + 004d RocketModem INFINITY III 4-port + 004e RocketPort INFINITY Plus 2-port 004f RocketPort Infinity 2port, SMPTE + 0050 RocketPort INFINITY Plus 4-port RJ45 + 0051 RocketPort INFINITY Plus 8-port RJ11 0052 RocketPort Infinity Octa, 8port, SMPTE - 0801 RocketPort UPCI 32 port w/external I/F - 0802 RocketPort UPCI 8 port w/external I/F - 0803 RocketPort UPCI 16 port w/external I/F - 0805 RocketPort UPCI 8 port w/octa cable - 080c RocketModem III 8 port - 080d RocketModem III 4 port - 0810 RocketPort UPCI Plus 4 port RS232 - 0811 RocketPort UPCI Plus 8 port RS232 - 0812 RocketPort UPCI Plus 8 port RS422 + 0060 RocketPort EXPRESS 8-port w/Octa Cable + 0061 RocketPort EXPRESS 32-port w/external I/F + 0062 RocketPort EXPRESS 8-Port w/external I/F + 0063 RocketPort EXPRESS 16-port w/external I/F + 0064 RocketPort EXPRESS 4-port w/Quad Cable + 0065 RocketPort EXPRESS 8-port w/Octa Cable + 0066 RocketPort EXPRESS 4-port w/external I/F + 0067 RocketPort EXPRESS 4J (4-port) w/RJ45 connectors + 0068 RocketPort EXPRESS 8J (8-port) w/RJ11 connectors + 006f RocketPort EXPRESS SMPTE 2-port + 0072 RocketPort EXPRESS SMPTE 8-port w/external I/F + 0801 RocketPort uPCI 32-port w/external I/F + 0802 RocketPort uPCI 8-port w/external I/F + 0803 RocketPort uPCI 16-port w/external I/F + 0805 RocketPort uPCI 8-port w/Octa Cable + 080b RocketPort Plus uPCI 8-port w/Octa Cable + 080c RocketModem III 8-port + 080d RcoketModem III 4-port + 080e RocketPort uPCI 2-port RS232 w/DB9 connectors + 080f RocketPort uPCI SMPTE 2-port + 0810 RocketPort Plus uPCI 4J (4-port) w/RJ45 connectors + 0811 RocketPort Plus uPCI 8J (8-port) w/RJ11 connectors + 0812 RocketPort Plus uPCI 422 8-port + 0813 RocketModem IV uPCI 8-port + 0814 RocketModem IV uPCI 4-port 0903 RocketPort Compact PCI 16 port w/external I/F - 8015 RocketPort 4-port UART 16954 +# 16954 UART + 8015 RocketPort 550 4-port + 8805 RocketPort uPCI 4-port w/Quad Cable + 880b RocketPort Plus uPCI 4-port w/Quad Cable + 8812 RocketPort Plus uPCI 4-port RS422 w/Quad Cable 11ff Scion Corporation 0003 AG-5 1200 CSS Corporation @@ -15642,6 +15735,7 @@ 0252 XR17V252 Dual UART PCI controller 0254 XR17V254 Quad UART PCI controller 0258 XR17V258 Octal UART PCI controller + 0352 XR17V3521 Dual PCIe UART 13a9 Siemens Medical Systems, Ultrasound Group 13aa Broadband Networks Inc 13ab Arcom Control Systems Ltd @@ -16302,6 +16396,7 @@ 50a9 T580-50A9 Unified Wire Ethernet Controller 50aa T580-50AA Unified Wire Ethernet Controller 50ab T520-50AB Unified Wire Ethernet Controller + 50ac T540-50AC Unified Wire Ethernet Controller 5401 T520-CR Unified Wire Ethernet Controller 5402 T522-CR Unified Wire Ethernet Controller 5403 T540-CR Unified Wire Ethernet Controller @@ -16364,6 +16459,7 @@ 54a9 T580-50A9 Unified Wire Ethernet Controller 54aa T580-50AA Unified Wire Ethernet Controller 54ab T520-50AB Unified Wire Ethernet Controller + 54ac T540-50AC Unified Wire Ethernet Controller 5501 T520-CR Unified Wire Storage Controller 5502 T522-CR Unified Wire Storage Controller 5503 T540-CR Unified Wire Storage Controller @@ -16424,6 +16520,9 @@ 55a7 T580-50A7 Unified Wire Storage Controller 55a8 T580-50A8 Unified Wire Storage Controller 55a9 T580-50A9 Unified Wire Storage Controller + 55aa T580-50AA Unified Wire Storage Controller + 55ab T520-50AB Unified Wire Storage Controller + 55ac T540-50AC Unified Wire Storage Controller 5601 T520-CR Unified Wire Storage Controller 5602 T522-CR Unified Wire Storage Controller 5603 T540-CR Unified Wire Storage Controller @@ -16486,6 +16585,7 @@ 56a9 T580-50A9 Unified Wire Storage Controller 56aa T580-50AA Unified Wire Storage Controller 56ab T520-50AB Unified Wire Storage Controller + 56ac T540-50AC Unified Wire Storage Controller 5701 T520-CR Unified Wire Ethernet Controller 5702 T522-CR Unified Wire Ethernet Controller 5703 T540-CR Unified Wire Ethernet Controller @@ -16587,6 +16687,7 @@ 58a9 T580-50A9 Unified Wire Ethernet Controller [VF] 58aa T580-50AA Unified Wire Ethernet Controller [VF] 58ab T520-50AB Unified Wire Ethernet Controller [VF] + 58ac T540-50AC Unified Wire Ethernet Controller [VF] 6001 T6225-CR Unified Wire Ethernet Controller 6002 T6225-SO-CR Unified Wire Ethernet Controller 6003 T6425-CR Unified Wire Ethernet Controller @@ -16607,6 +16708,7 @@ 6084 T64100-6084 Unified Wire Ethernet Controller 6085 T6240-6085 Unified Wire Ethernet Controller 6086 T6225-6086 Unified Wire Ethernet Controller + 6087 T6225-6087 Unified Wire Ethernet Controller 6401 T6225-CR Unified Wire Ethernet Controller 6402 T6225-SO-CR Unified Wire Ethernet Controller 6403 T6425-CR Unified Wire Ethernet Controller @@ -16627,6 +16729,7 @@ 6484 T64100-6084 Unified Wire Ethernet Controller 6485 T6240-6085 Unified Wire Ethernet Controller 6486 T6225-6086 Unified Wire Ethernet Controller + 6487 T6225-6087 Unified Wire Ethernet Controller 6501 T6225-CR Unified Wire Storage Controller 6502 T6225-SO-CR Unified Wire Storage Controller 6503 T6425-CR Unified Wire Storage Controller @@ -16647,6 +16750,7 @@ 6584 T64100-6084 Unified Wire Storage Controller 6585 T6240-6085 Unified Wire Storage Controller 6586 T6225-6086 Unified Wire Storage Controller + 6587 T6225-6087 Unified Wire Storage Controller 6601 T6225-CR Unified Wire Storage Controller 6602 T6225-SO-CR Unified Wire Storage Controller 6603 T6425-CR Unified Wire Storage Controller @@ -16667,6 +16771,7 @@ 6684 T64100-6084 Unified Wire Storage Controller 6685 T6240-6085 Unified Wire Storage Controller 6686 T6225-6086 Unified Wire Storage Controller + 6687 T6225-6087 Unified Wire Storage Controller 6801 T6225-CR Unified Wire Ethernet Controller [VF] 6802 T6225-SO-CR Unified Wire Ethernet Controller [VF] 6803 T6425-CR Unified Wire Ethernet Controller [VF] @@ -16687,6 +16792,7 @@ 6884 T64100-6084 Unified Wire Ethernet Controller [VF] 6885 T6240-6085 Unified Wire Ethernet Controller [VF] 6886 T6225-6086 Unified Wire Ethernet Controller [VF] + 6887 T6225-6087 Unified Wire Ethernet Controller [VF] a000 PE10K Unified Wire Ethernet Controller 1426 Storage Technology Corp. 1427 Better On-Line Solutions @@ -17198,6 +17304,7 @@ 103c 169d Ethernet 1Gb 4-port 331FLR Adapter 103c 22be Ethernet 1Gb 4-port 331i Adapter 103c 3383 Ethernet 1Gb 4-port 331T Adapter + 14e4 1904 4-port 1Gb Ethernet Adapter 1659 NetXtreme BCM5721 Gigabit Ethernet PCI Express 1014 02c6 eServer xSeries server mainboard 1028 01e6 PowerEdge 860 @@ -17269,6 +17376,7 @@ 1014 0577 ThinkPad X41 / Z60t 103c 0934 nx8220 103c 0940 Compaq nw8240 Mobile Workstation + 103c 0944 Compaq nc6220 Notebook PC 17aa 2081 ThinkPad R60e 167e NetXtreme BCM5751F Fast Ethernet PCI Express 167f NetLink BCM5787F Fast Ethernet PCI Express @@ -18253,6 +18361,8 @@ 1556 PLDA 1100 PCI Express Core Reference Design 110f PCI Express Core Reference Design Virtual Function + 1110 XpressRich Reference Design + 1113 XpressSwitch 1557 MEDIASTAR Co Ltd 1558 CLEVO/KAPOK Computer 1559 SI LOGIC Ltd @@ -18408,6 +18518,7 @@ 020b MT27710 Family [ConnectX-4 Lx Flash Recovery] 020d MT28800 Family [ConnectX-5 Flash Recovery] 020f MT28908A0 Family [ConnectX-6 Flash Recovery] + 0210 MT28908A0 Family [ConnectX-6 Secure Flash Recovery] 0211 MT416842 Family [BlueField SoC Flash Recovery] # reserved for RM#105916 024e MT53100 [Spectrum-2, Flash recovery mode] @@ -18415,9 +18526,11 @@ 024f MT53100 [Spectrum-2, Flash recovery mode] 0262 MT27710 [ConnectX-4 Lx Programmable] EN 0263 MT27710 [ConnectX-4 Lx Programmable Virtual Function] EN + 0264 Innova-2 Flex Burn image 0281 NPS-600 Flash Recovery 1002 MT25400 Family [ConnectX-2 Virtual Function] 1003 MT27500 Family [ConnectX-3] + 1014 04b5 PCIe3 40GbE RoCE Converged Host Bus Adapter for Power 103c 1777 InfiniBand FDR/EN 10/40Gb Dual Port 544FLR-QSFP Adapter (Rev Cx) 103c 17c9 Infiniband QDR/Ethernet 10Gb 2-port 544i Adapter 103c 18ce InfiniBand QDR/EN 10Gb Dual Port 544M Adapter @@ -18463,6 +18576,7 @@ 1011 MT27600 [Connect-IB] 1012 MT27600 Family [Connect-IB Virtual Function] 1013 MT27700 Family [ConnectX-4] + 1014 04f7 PCIe3 2-port 100 GbE (NIC and RoCE) QSFP28 Adapter for Power 15b3 0003 Mellanox Technologies ConnectX-4 Stand-up single-port 40GbE MCX413A-BCAT 15b3 0005 Mellanox Technologies ConnectX-4 Stand-up single-port 40GbE MCX415A-BCAT 15b3 0006 MCX416A-BCAT, ConnectX-4 EN, 40/56GbE 2P, PCIe3.0 x16 @@ -18472,6 +18586,7 @@ 15b3 0050 ConnectX-4 100 GbE Dual Port QSFP28 Adapter 1014 MT27700 Family [ConnectX-4 Virtual Function] 1015 MT27710 Family [ConnectX-4 Lx] + 15b3 0004 ConnectX-4 Lx Stand-up dual-port 10GbE MCX4121A-XCAT 15b3 0005 Mellanox Technologies ConnectX-4 Lx Stand-up single-port 40GbE MCX4131A-BCAT 15b3 0016 ConnectX-4 Lx 25 GbE Dual Port SFP28 Adapter 15b3 0020 MCX4411A-ACQN, ConnectX-4 Lx EN OCP, 1x25Gb @@ -18507,6 +18622,7 @@ 6372 MT25408 [ConnectX EN 10GigE 10GBaseT, PCIe 2.0 2.5GT/s] 6732 MT26418 [ConnectX VPI PCIe 2.0 5GT/s - IB DDR / 10GigE] 673c MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE] + 1014 0415 PCIe2 2-port 4X InfiniBand QDR Adapter for Power 1014 0487 GX++ 1-port 4X IB QDR Adapter for Power 795 103c 1782 4X QDR InfiniBand Mezzanine HCA for c-Class BladeSystem 15b3 0021 HP InfiniBand 4X QDR CX-2 PCI-e G2 Dual Port HCA @@ -18529,6 +18645,7 @@ 7121 NPS-600 configuration and management interface 7122 NPS-600 network interface PF 7123 NPS-600 network interface VF + 8200 Innova-2 Flex Shell Logic a2d0 MT416842 BlueField SoC Crypto enabled a2d1 MT416842 BlueField SoC Crypto disabled a2d2 MT416842 BlueField integrated ConnectX-5 network controller @@ -18565,6 +18682,7 @@ 0015 ZBox 15b7 Sandisk Corp 2001 Skyhawk Series NVME SSD + 5001 WD Black NVMe SSD 15b8 ADDI-DATA GmbH 1001 APCI1516 SP controller (16 digi outputs) 1003 APCI1032 SP controller (32 digi inputs w/ opto coupler) @@ -18713,6 +18831,11 @@ 1006 Format synchronizer, model 10500 1007 Format synchronizer, model 21000 2002 Fast Universal Data Output + 3100 IO31000 Frame Synchronizer and I/O + 3200 IO32000 Frame Synchronizer and I/O + 4002 High Rate Demodulator + 5001 High Rate FEC + 6001 High Rate Demodulator and FEC 1631 Packard Bell B.V. 1638 Standard Microsystems Corp [SMC] 1100 SMC2602W EZConnect / Addtron AWA-100 / Eumitcom PCI WL11000 @@ -19019,6 +19142,7 @@ 0777 4005 SR71-15 802.11an Mini PCI Adapter 1186 3a7a DWA-552 802.11n Xtreme N Desktop Adapter (rev A2) 1186 3a7d DWA-552 802.11n Xtreme N Desktop Adapter (rev A3) + 168c 0029 AR922X Wireless Network Adapter 168c 2096 Compex WLM200NX / Wistron DNMA-92 002a AR928X Wireless Network Adapter (PCI-Express) 0777 4f05 SR71-X 802.11abgn Wireless ExpressCard Adapter [AR9280] @@ -19203,17 +19327,23 @@ 7012 AP440-2: 32-Channel Isolated Digital Input Module 7013 AP440-3: 32-Channel Isolated Digital Input Module 7014 AP445: 32-Channel Isolated Digital Output Module + 7015 AP471 48-Channel TTL Level Digital Input/Output Module 7016 AP470 48-Channel TTL Level Digital Input/Output Module 7017 AP323 16-bit, 20 or 40 Channel Analog Input Module 7018 AP408: 32-Channel Digital I/O Module 7019 AP341 14-bit, 16-Channel Simultaneous Conversion Analog Input Module 701a AP220-16 12-Bit, 16-Channel Analog Output Module 701b AP231-16 16-Bit, 16-Channel Analog Output Module + 701c AP225 12-Bit, 16-Channel Analog Output Module with Waveform Memory + 701d AP235 16-Bit, 16-Channel Analog Output Module with Waveform Memory 7021 APA7-201 Reconfigurable Artix-7 FPGA module 48 TTL channels 7022 APA7-202 Reconfigurable Artix-7 FPGA module 24 RS485 channels 7023 APA7-203 Reconfigurable Artix-7 FPGA module 24 TTL & 12 RS485 channels 7024 APA7-204 Reconfigurable Artix-7 FPGA module 24 LVDS channels 7027 AP418 16-Channel High Voltage Digital Input/Output Module + 7029 AP342 14-bit, 12-Channel Isolated Simultaneous Conversion Analog Input Module + 702a AP226 12-Bit, 8-Channel Isolated Analog Output Module + 702b AP236 16-Bit, 8-Channel Isolated Analog Output Module 7042 AP482 Counter Timer Module with TTL Level Input/Output 7043 AP483 Counter Timer Module with TTL Level and RS422 Input/Output 7044 AP484 Counter Timer Module with RS422 Input/Output @@ -20070,11 +20200,15 @@ 1924 8019 SFN8542-R2 8000 Series 10/40G Adapter 1924 801a SFN8722-R1 8000 Series OCP 10G Adapter 1924 801b SFN8522-R3 8000 Series 10G Adapter + 0b03 SFC9250 10/25/40/50/100G Ethernet Controller + 1924 801d x2522-R1 2000 Series 10/25G Adapter + 1924 801e x2542-R1 2000 Series 40/100G Adapter 1803 SFC9020 10G Ethernet Controller (Virtual Function) 1813 SFL9021 10GBASE-T Ethernet Controller (Virtual Function) 1903 SFC9120 10G Ethernet Controller (Virtual Function) 1923 SFC9140 10/40G Ethernet Controller (Virtual Function) 1a03 SFC9220 10/40G Ethernet Controller (Virtual Function) + 1b03 SFC9250 10/25/40/50/100G Ethernet Controller (Virtual Function) 6703 SFC4000 rev A iSCSI/Onload [Solarstorm] 10b8 0102 SMC10GPCIe-10BT (A2) [TigerCard] 10b8 0103 SMC10GPCIe-10BT (A3) [TigerCard] @@ -20095,6 +20229,7 @@ 000c Qualcomm MSM6275 UMTS chip 1932 DiBcom 193c MAXIM Integrated Products +193d Hangzhou H3C Technologies Co., Ltd. 193f AHA Products Group 0001 AHA36x-PCIX 0360 AHA360-PCIe @@ -20737,6 +20872,8 @@ 1bbf Maxeler Technologies Ltd. 0003 MAX3 0004 MAX4 +1bcf NEC Corporation + 001c Vector Engine 1.0 1bd0 Astronics Corporation 1001 Mx5 PMC/XMC Databus Interface Card 1002 PM1553-5 (PC/104+ MIL-STD-1553 Interface Card) @@ -20920,7 +21057,13 @@ 1d65 Imagine Communications Corp. 04de Taurus/McKinley 1d6a Aquantia Corp. + 07b1 AQC107 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + 08b1 AQC108 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + 11b1 AQC111 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + 12b1 AQC112 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + 87b1 AQC107 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] d107 AQC107 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + d108 AQC108 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] 1d6c Atomic Rules LLC 1001 A5PL-E1 1002 A5PL-E7 @@ -20943,6 +21086,36 @@ 1d7c Aerotech, Inc. 1d87 Fuzhou Rockchip Electronics Co., Ltd 1d8f Enyx +1d94 Chengdu Higon IC Design Co.Ltd + 1450 Root Complex + 1451 I/O Memory Management Unit + 1452 PCIe Dummy Host Bridge + 1453 PCIE GPP Bridge + 1454 Internal PCIe GPP Bridge 0 to Bus B + 1455 PCIe Dummy Function + 1456 PSPCCP Command DMA Processor + 1458 10 Gb Ethernet Controller Port 0/Port1 + 1459 10 Gb Ethernet Controller Port 2/Port3 + 145a PCIe Dummy Function + 145b PCIE Non-Transparent Bridge + 145c USB3 XHCI + 145d Switch upstream in PCIe + 145e Switch downstream in PCIe + 145f USB 3.0 Host controller + 1460 Data Fabric: Device 18h; Function 0 + 1461 Data Fabric: Device 18h; Function 1 + 1462 Data Fabric: Device 18h; Function 2 + 1463 Data Fabric: Device 18h; Function 3 + 1464 Data Fabric: Device 18h; Function 4 + 1465 Data Fabric: Device 18h; Function 5 + 1466 Data Fabric: Device 18h; Function 6 + 1467 Data Fabric: Device 18h; Function 7 + 1468 NTBCCP + 7901 FCH SATA Controller [AHCI mode] + 7904 FCH SATA Controller [AHCI mode] + 7906 FCH SD Flash Controller + 790b FCH SMBus Controller + 790e FCH LPC Bridge 1d95 Graphcore Ltd 1da1 Teko Telecom S.r.l. 1da2 Sapphire Technology Limited @@ -20954,6 +21127,16 @@ 1de5 Eideticom, Inc 1000 IO Memory Controller 2000 NoLoad Hardware Development Kit +1def Ampere Computing, LLC + e005 Skylark PCI Express Root Port 0 [X-Gene 3] + e006 Skylark PCI Express Root Port 1 [X-Gene 3] + e007 Skylark PCI Express Root Port 2 [X-Gene 3] + e008 Skylark PCI Express Root Port 3 [X-Gene 3] + e009 Skylark PCI Express Root Port 4 [X-Gene 3] + e00a Skylark PCI Express Root Port 5 [X-Gene 3] + e00b Skylark PCI Express Root Port 6 [X-Gene 3] + e00c Skylark PCI Express Root Port 7 [X-Gene 3] +1df7 opencpi.org # nee Tumsan Oy 1fc0 Ascom (Finland) Oy 0300 E2200 Dual E1/Rawpipe Card @@ -21668,6 +21851,8 @@ 3000 HD-3000 5500 HD5500 HDTV 7284 HT OMEGA Inc. +7357 IOxOS Technologies SA + 7910 7910 [Althea] 7401 EndRun Technologies e100 PTP3100 PCIe PTP Slave Clock 7470 TP-LINK Technologies Co., Ltd. @@ -23659,8 +23844,9 @@ 15c7 Ethernet Connection X553 1GbE 15c8 Ethernet Connection X553/X557-AT 10GBASE-T 15ce Ethernet Connection X553 10 GbE SFP+ - 15d0 Ethernet SDI Adapter FM10420-100GbE-QDA2 + 15d0 Ethernet SDI Adapter 8086 0001 Ethernet SDI Adapter FM10420-100GbE-QDA2 + 8086 0002 Ethernet SDI Adapter FM10840-MTP2 15d1 Ethernet Controller 10G X550T 8086 0002 Ethernet Converged Network Adapter X550-T1 8086 001b Ethernet Server Adapter X550-T1 for OCP @@ -23685,6 +23871,14 @@ 15e3 Ethernet Connection (5) I219-LM 15e4 Ethernet Connection X553 1GbE 15e5 Ethernet Connection X553 1GbE + 15e7 JHL7540 Thunderbolt 3 Bridge [Titan Ridge 2C 2018] + 15e8 JHL7540 Thunderbolt 3 NHI [Titan Ridge 2C 2018] + 15e9 JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 2C 2018] + 15ea JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] + 15eb JHL7540 Thunderbolt 3 NHI [Titan Ridge 4C 2018] + 15ec JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 4C 2018] + 15ef JHL7540 Thunderbolt 3 Bridge [Titan Ridge DD 2018] + 15f0 JHL7540 Thunderbolt 3 USB Controller [Titan Ridge DD 2018] 1600 Broadwell-U Host Bridge -OPI 1601 Broadwell-U PCI Express x16 Controller 1602 Broadwell-U Integrated Graphics @@ -24111,6 +24305,7 @@ 144d c652 NP300E5C series laptop 1849 1e2d Motherboard 1e31 7 Series/C210 Series Chipset Family USB xHCI Host Controller + 103c 179b Elitebook 8470p 103c 17ab ProBook 6570b 1043 108d VivoBook X202EV 1043 1477 N56VZ @@ -24420,6 +24615,7 @@ 1028 040a Latitude E6410 1028 040b Latitude E6510 103c 0934 Compaq nw8240 Mobile Workstation + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 103c 309f Compaq nx9420 Notebook 103c 30a3 Compaq nw8440 @@ -25087,6 +25283,7 @@ 1014 0575 ThinkPad X41 / Z60t 1028 0182 Latitude C610 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 104d 81b7 Vaio VGN-S3XP a304 81b7 Vaio VGN-S3XP @@ -25271,6 +25468,7 @@ 2641 82801FBM (ICH6M) LPC Interface Bridge 1014 0568 ThinkPad X41 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 2642 82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge 2651 82801FB/FW (ICH6/ICH6W) SATA Controller @@ -25291,6 +25489,7 @@ 1028 0177 Dimension 8400 1028 0179 Optiplex GX280 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 1043 80a6 P5GD1-VW Mainboard 1458 2558 GA-8I915ME-G Mainboard @@ -25304,6 +25503,7 @@ 1028 0177 Dimension 8400 1028 0179 Optiplex GX280 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 1043 80a6 P5GD1-VW Mainboard 1458 2659 GA-8I915ME-G Mainboard @@ -25317,6 +25517,7 @@ 1028 0177 Dimension 8400 1028 0179 Optiplex GX280 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 1043 80a6 P5GD1-VW Mainboard 1458 265a GA-8I915ME-G Mainboard @@ -25342,6 +25543,7 @@ 1028 0177 Dimension 8400 1028 0179 Optiplex GX280 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 1043 80a6 P5GD1-VW Mainboard 1458 5006 GA-8I915ME-G Mainboard @@ -25353,12 +25555,14 @@ e4bf 58b1 XB1 2660 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 103c 0934 Compaq nw8240 Mobile Workstation + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 e4bf 0ccd CCD-CALYPSO e4bf 0cd3 CD3-JIVE e4bf 58b1 XB1 2662 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 103c 0934 Compaq nw8240 Mobile Workstation + 103c 0944 Compaq nc6220 Notebook PC e4bf 0ccd CCD-CALYPSO e4bf 0cd3 CD3-JIVE e4bf 58b1 XB1 @@ -25412,6 +25616,7 @@ 266f 82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller 1028 0177 Dimension 8400 103c 0934 Compaq nw8240/nx8220 + 103c 0944 Compaq nc6220 Notebook PC 103c 099c NX6110/NC6120 1043 80a6 P5GD1-VW Mainboard 1458 266f GA-8I915ME-G Mainboard @@ -25484,6 +25689,12 @@ 103c 31fe ProLiant DL140 G3 15d9 8680 X7DVL-E-O motherboard 15d9 9680 X7DBN Motherboard + 2700 Optane SSD 900P Series + 8086 3900 900P Series [Add-in Card] + 8086 3901 900P Series [2.5" SFF] + 2701 Optane DC P4800X Series SSD + 8086 3904 DC P4800X Series [Add-in Card] + 8086 3905 DC P4800X Series [2.5" SFF] 2770 82945G/GZ/P/PL Memory Controller Hub 1028 01ad OptiPlex GX620 103c 2a3b Pavilion A1512X @@ -25514,6 +25725,7 @@ 2792 Mobile 915GM/GMS/910GML Express Graphics Controller 1014 0582 ThinkPad X41 103c 099c NX6110/NC6120 + 103c 308a Compaq nc6220 Notebook PC 1043 1881 GMA 900 915GM Integrated Graphics e4bf 0ccd CCD-CALYPSO e4bf 0cd3 CD3-JIVE @@ -27544,7 +27756,7 @@ 4117 Atom Processor E6xx PCI Host Bridge #4 4220 PRO/Wireless 2200BG [Calexico2] Network Connection 103c 0934 Compaq nw8240/nx8220 - 103c 12f6 nc6120/nx8220/nw8240 + 103c 12f6 nc6120/nc6220/nw8240/nx8220 8086 2701 WM3B2200BG Mini-PCI Card 8086 2712 IBM ThinkPad R50e 8086 2721 Dell B130 laptop integrated WLAN @@ -27692,9 +27904,11 @@ 590f Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers 5910 Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers 5912 HD Graphics 630 + 5914 Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers 5916 HD Graphics 620 17aa 2248 ThinkPad T570 17aa 224f ThinkPad X1 Carbon 5th Gen + 5917 UHD Graphics 620 591d HD Graphics P630 591f Intel Kaby Lake Host Bridge 5a84 Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller @@ -28111,6 +28325,8 @@ 8c26 8 Series/C220 Series Chipset Family USB EHCI #1 103c 1909 ZBook 15 17aa 220e ThinkPad T440p + 17aa 2210 ThinkPad T540p + 2210 17aa ThinkPad T540p 8c2d 8 Series/C220 Series Chipset Family USB EHCI #2 103c 1909 ZBook 15 17aa 220e ThinkPad T440p @@ -29018,6 +29234,11 @@ 103c 0701 Smart Array P204i-b SR Gen10 103c 1100 Smart Array P816i-a SR Gen10 103c 1101 Smart Array P416ie-m SR G10 + 152d 8a22 QS-8204-8i + 152d 8a23 QS-8238-16i + 152d 8a24 QS-8236-16i + 152d 8a36 QS-8240-24i + 152d 8a37 QS-8242-24i 9005 0800 SmartRAID 3154-8i 9005 0801 SmartRAID 3152-8i 9005 0802 SmartRAID 3151-4i @@ -29220,8 +29441,8 @@ bdbd Blackmagic Design a124 Intensity Extreme a126 Intensity Shuttle a127 UltraStudio Express - a129 UltraStudio Mini Monitor - a12a UltraStudio Mini Recorder + a129 UltraStudio Mini Recorder + a12a UltraStudio Mini Monitor a12d UltraStudio 4K a12e DeckLink 4K Extreme a12f DeckLink Mini Monitor @@ -29236,6 +29457,11 @@ bdbd Blackmagic Design a13e UltraStudio 4K Extreme a13f DeckLink Quad 2 a140 DeckLink Duo 2 + a141 UltraStudio 4K Extreme 3 + a142 UltraStudio HD Mini + a143 DeckLink Mini Recorder 4K + a144 DeckLink Mini Monitor 4K + a14b DeckLink 8K Pro c001 TSI Telsys c0a9 Micron/Crucial Technology c0de Motorola diff --git a/hwdb/usb.ids b/hwdb/usb.ids index ec20b2fa22..cc8556a420 100644 --- a/hwdb/usb.ids +++ b/hwdb/usb.ids @@ -9,8 +9,8 @@ # The latest version can be obtained from # http://www.linux-usb.org/usb.ids # -# Version: 2017.11.27 -# Date: 2017-11-27 20:34:05 +# Version: 2018.01.04 +# Date: 2018-01-04 20:34:07 # # Vendors, devices and interfaces. Please keep sorted. @@ -16161,6 +16161,35 @@ 0002 HDReye (before firmware loads) 1519 Comneon 0020 HSIC Device +151f Opal Kelly Incorporated + 0020 XEM3001v1 + 0021 XEM3001v2 + 0022 XEM3010 + 0023 XEM3005 + 0028 XEM3050 + 002b XEM5010 + 002c XEM6001 + 002d XEM6010-LX45 + 002e XEM6010-LX150 + 0030 XEM6006-LX16 + 0033 XEM6002-LX9 + 0034 XEM7001-A15 + 0036 XEM7010-A50 + 0037 XEM7010-A200 + 0120 ZEM4310 + 0121 XEM6310-LX45 + 0122 XEM6310-LX150 + 0123 XEM6310MT-LX45T + 0125 XEM7350-K70T + 0126 XEM7350-K160T + 0127 XEM7350-K410T + 0128 XEM6310MT-LX150T + 0129 ZEM5305-A2 + 012b XEM7360-K160T + 012c XEM7360-K410T + 012d ZEM5310-A4 + 0130 XEM7310-A75 + 0131 XEM7310-A200 1520 Bitwire Corp. 1524 ENE Technology Inc 6680 UTS 6680 @@ -18673,6 +18702,19 @@ 24e1 Paratronic 3001 Adp-usb 3005 Radius +2516 Cooler Master Co., Ltd. + 0003 Storm Xornet + 0004 Storm QuickFire Rapid Mechanical Keyboard + 0006 Storm Recon + 0007 Storm Sentinel Advance II + 0009 Storm Quick Fire PRO + 0011 Storm Quick Fire TK + 0017 CM Storm Quick Fire Stealth + 0020 QuickFire Rapid-i Keyboard + 0027 CM Storm Coolermaster Novatouch TKL + 002d Alcor mouse + 0047 MasterKeys Pro L + 9494 Sirus Headset 2632 TwinMOS 3209 7-in-1 Card Reader 2639 Xsens diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml index 5f55cb4db2..4b085bcc16 100644 --- a/man/binfmt.d.xml +++ b/man/binfmt.d.xml @@ -69,7 +69,7 @@ <para>Each file contains a list of binfmt_misc kernel binary format rules. Consult <ulink - url="https://www.kernel.org/doc/Documentation/binfmt_misc.txt">binfmt_misc.txt</ulink> + url="https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst">binfmt-misc.rst</ulink> for more information on registration of additional binary formats and how to write rules.</para> diff --git a/man/busctl.xml b/man/busctl.xml index 0c0d28b5d3..2320cb8ed3 100644 --- a/man/busctl.xml +++ b/man/busctl.xml @@ -241,6 +241,16 @@ </listitem> </varlistentry> + <varlistentry> + <term><option>--watch-bind=</option><replaceable>BOOL</replaceable></term> + + <listitem> + <para>Controls whether to wait for the specified <constant>AF_UNIX</constant> bus socket to appear in the + file system before connecting to it. Defaults to off. When enabled, the tool will watch the file system until + the socket is created and then connect to it.</para> + </listitem> + </varlistentry> + <xi:include href="user-system-options.xml" xpointer="user" /> <xi:include href="user-system-options.xml" xpointer="system" /> <xi:include href="user-system-options.xml" xpointer="host" /> diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml index 097296059f..f6ac86aaf5 100644 --- a/man/coredump.conf.xml +++ b/man/coredump.conf.xml @@ -146,6 +146,9 @@ </varlistentry> </variablelist> + <para>The defaults for all values are listed as comments in the + template <filename>/etc/systemd/coredump.conf</filename> file that + is installed by default.</para> </refsect1> <refsect1> diff --git a/man/crypttab.xml b/man/crypttab.xml index 474d3d83e0..dc43257d4e 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -218,16 +218,23 @@ <varlistentry> <term><option>noauto</option></term> - <listitem><para>This device will not be automatically unlocked - on boot.</para></listitem> + <listitem><para>This device will not be added to <filename>cryptsetup.target</filename>. + This means that it will not be automatically unlocked on boot, unless something else pulls + it in. In particular, if the device is used for a mount point, it'll be unlocked + automatically during boot, unless the mount point itself is also disabled with + <option>noauto</option>.</para></listitem> </varlistentry> <varlistentry> <term><option>nofail</option></term> - <listitem><para>The system will not wait for the device to - show up and be unlocked at boot, and not fail the boot if it - does not show up.</para></listitem> + <listitem><para>This device will not be a hard dependency of + <filename>cryptsetup.target</filename>. It'll be still pulled in and started, but the system + will not wait for the device to show up and be unlocked, and boot will not fail if this is + unsuccessful. Note that other units that depend on the unlocked device may still fail. In + particular, if the device is used for a mount point, the mount point itself is also needs to + have <option>noauto</option> option, or the boot will fail if the device is not unlocked + successfully.</para></listitem> </varlistentry> <varlistentry> diff --git a/man/custom-html.xsl b/man/custom-html.xsl index 47ce6abfee..e8a7404df3 100644 --- a/man/custom-html.xsl +++ b/man/custom-html.xsl @@ -73,6 +73,18 @@ </a> </xsl:template> +<xsl:template match="citerefentry[@project='wireguard']"> + <a> + <xsl:attribute name="href"> + <xsl:text>https://git.zx2c4.com/WireGuard/about/src/tools/</xsl:text> + <xsl:value-of select="refentrytitle"/> + <xsl:text>.</xsl:text> + <xsl:value-of select="manvolnum"/> + </xsl:attribute> + <xsl:call-template name="inline.charseq"/> + </a> +</xsl:template> + <xsl:template match="citerefentry[@project='mankier']"> <a> <xsl:attribute name="href"> diff --git a/man/file-hierarchy.xml b/man/file-hierarchy.xml index b1442dd82c..4220520a1f 100644 --- a/man/file-hierarchy.xml +++ b/man/file-hierarchy.xml @@ -605,8 +605,8 @@ daemon code, to create it via <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> fragments during boot, or via the - <varname>RuntimeDirectory=</varname> directive of service units - (see + <varname>StateDirectory=</varname> and <varname>RuntimeDirectory=</varname> + directives of service units (see <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details).</para> </refsect1> @@ -694,7 +694,7 @@ </row> <row> <entry><filename>/run/<replaceable>package</replaceable></filename></entry> - <entry>Runtime data for the package. Packages must be able to create the necessary subdirectories in this tree on their own, since the directory is flushed automatically on boot. Alternatively, a <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> fragment may be used to create the necessary directories during boot. Alternatively, the <varname>RuntimeDirectory=</varname> directive of service units may be used (see <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details.)</entry> + <entry>Runtime data for the package. Packages must be able to create the necessary subdirectories in this tree on their own, since the directory is flushed automatically on boot. Alternatively, a <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> fragment may be used to create the necessary directories during boot, or the <varname>RuntimeDirectory=</varname> directive of service units may be used to create them at service startup (see <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details).</entry> </row> <row> <entry><filename>/run/log/<replaceable>package</replaceable></filename></entry> @@ -702,15 +702,15 @@ </row> <row> <entry><filename>/var/cache/<replaceable>package</replaceable></filename></entry> - <entry>Persistent cache data of the package. If this directory is flushed, the application should work correctly on next invocation, though possibly slowed down due to the need to rebuild any local cache files. The application must be capable of recreating this directory should it be missing and necessary.</entry> + <entry>Persistent cache data of the package. If this directory is flushed, the application should work correctly on next invocation, though possibly slowed down due to the need to rebuild any local cache files. The application must be capable of recreating this directory should it be missing and necessary. To create an empty directory, a <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> fragment or the <varname>CacheDirectory=</varname> directive of service units (see <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>) may be used.</entry> </row> <row> <entry><filename>/var/lib/<replaceable>package</replaceable></filename></entry> - <entry>Persistent private data of the package. This is the primary place to put persistent data that does not fall into the other categories listed. Packages should be able to create the necessary subdirectories in this tree on their own, since the directory might be missing on boot. Alternatively, a <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> fragment may be used to create the necessary directories during boot.</entry> + <entry>Persistent private data of the package. This is the primary place to put persistent data that does not fall into the other categories listed. Packages should be able to create the necessary subdirectories in this tree on their own, since the directory might be missing on boot. To create an empty directory, a <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> fragment or the <varname>StateDirectory=</varname> directive of service units (see <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>) may be used.</entry> </row> <row> <entry><filename>/var/log/<replaceable>package</replaceable></filename></entry> - <entry>Persistent log data of the package. As above, the package should make sure to create this directory if necessary, as it might be missing.</entry> + <entry>Persistent log data of the package. As above, the package should make sure to create this directory if necessary, possibly using <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> or <varname>LogsDirectory=</varname> (see <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>), as it might be missing.</entry> </row> <row> <entry><filename>/var/spool/<replaceable>package</replaceable></filename></entry> diff --git a/man/halt.xml b/man/halt.xml index 0abcdb475c..78860d94dd 100644 --- a/man/halt.xml +++ b/man/halt.xml @@ -166,8 +166,12 @@ <refsect1> <title>Notes</title> - <para>These are legacy commands available for compatibility - only.</para> + <para>These commands are implemented in a way that preserves compatiblity with + the original SysV commands. + <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> + verbs <command>halt</command>, <command>poweroff</command>, + <command>reboot</command> provide the same functionality with some additional + features.</para> </refsect1> <refsect1> diff --git a/man/journalctl.xml b/man/journalctl.xml index 257ff5a816..37fb0d67fd 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -579,6 +579,29 @@ </varlistentry> <varlistentry> + <term><option>-g</option></term> + <term><option>--grep=</option></term> + + <listitem><para>Filter output to entries where the <varname>MESSAGE=</varname> + field matches the specified regular expression. PERL-compatible regular expressions + are used, see + <citerefentry><refentrytitle>pcre2pattern</refentrytitle><manvolnum>3</manvolnum></citerefentry> + for a detailed description of the syntax.</para> + + <para>If the pattern is all lowercase, matching is case insensitive. + Otherwise, matching is case sensitive. This can be overridden with the + <option>--case-sensitive</option> option, see below.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>--case-sensitive<optional>=BOOLEAN</optional></option></term> + + <listitem><para>Make pattern matching case sensitive or case insenstive.</para> + </listitem> + </varlistentry> + + <varlistentry> <term><option>-c</option></term> <term><option>--cursor=</option></term> diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index 422c0607da..be55f14e4f 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -85,6 +85,7 @@ <term><varname>systemd.crash_shell</varname></term> <term><varname>systemd.crash_reboot</varname></term> <term><varname>systemd.confirm_spawn</varname></term> + <term><varname>systemd.service_watchdogs</varname></term> <term><varname>systemd.show_status</varname></term> <term><varname>systemd.log_target=</varname></term> <term><varname>systemd.log_level=</varname></term> diff --git a/man/machinectl.xml b/man/machinectl.xml index 43f4d127b8..1adebf5da0 100644 --- a/man/machinectl.xml +++ b/man/machinectl.xml @@ -439,9 +439,9 @@ specified, the connection is made to the local host instead. This works similar to <command>login</command> but immediately invokes a user process. This command runs the - specified executable with the specified arguments, or - <filename>/bin/sh</filename> if none is specified. By default, - opens a <literal>root</literal> shell, but by using + specified executable with the specified arguments, or the + default shell for the user if none is specified, or + <filename>/bin/sh</filename> if no default shell is found. By default, <option>--uid=</option>, or by prefixing the machine name with a username and an <literal>@</literal> character, a different user may be selected. Use <option>--setenv=</option> to set @@ -881,7 +881,7 @@ </varlistentry> <varlistentry> - <term><command>cancel-transfers</command> <replaceable>ID</replaceable>…</term> + <term><command>cancel-transfer</command> <replaceable>ID</replaceable>…</term> <listitem><para>Aborts a download, import or export of the container or VM image with the specified ID. To list ongoing diff --git a/man/rules/meson.build b/man/rules/meson.build index 499fe6d19e..bfc267b544 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -105,7 +105,12 @@ manpages = [ ['sd-journal', '3', [], ''], ['sd-login', '3', [], 'HAVE_PAM'], ['sd_booted', '3', [], ''], - ['sd_bus_add_match', '3', [], ''], + ['sd_bus_add_match', + '3', + ['sd_bus_add_match_async', + 'sd_bus_match_signal', + 'sd_bus_match_signal_async'], + ''], ['sd_bus_creds_get_pid', '3', ['sd_bus_creds_get_audit_login_uid', @@ -181,6 +186,7 @@ manpages = [ ['SD_BUS_ERROR_END', 'SD_BUS_ERROR_MAP', 'sd_bus_error_map'], ''], ['sd_bus_get_fd', '3', [], ''], + ['sd_bus_is_open', '3', ['sd_bus_is_ready'], ''], ['sd_bus_message_append', '3', ['sd_bus_message_appendv'], ''], ['sd_bus_message_append_array', '3', @@ -200,6 +206,7 @@ manpages = [ ['sd_bus_message_get_realtime_usec', 'sd_bus_message_get_seqnum'], ''], ['sd_bus_message_read_basic', '3', [], ''], + ['sd_bus_message_set_destination', '3', ['sd_bus_message_set_sender'], ''], ['sd_bus_negotiate_fds', '3', ['sd_bus_negotiate_creds', 'sd_bus_negotiate_timestamp'], @@ -210,7 +217,15 @@ manpages = [ ['sd_bus_path_decode', 'sd_bus_path_decode_many', 'sd_bus_path_encode_many'], ''], ['sd_bus_process', '3', [], ''], - ['sd_bus_request_name', '3', ['sd_bus_release_name'], ''], + ['sd_bus_request_name', + '3', + ['sd_bus_release_name', + 'sd_bus_release_name_async', + 'sd_bus_request_name_async'], + ''], + ['sd_bus_set_connected_signal', '3', ['sd_bus_get_connected_signal'], ''], + ['sd_bus_set_sender', '3', ['sd_bus_get_sender'], ''], + ['sd_bus_set_watch_bind', '3', ['sd_bus_get_watch_bind'], ''], ['sd_bus_track_add_name', '3', ['sd_bus_track_add_sender', @@ -594,6 +609,7 @@ manpages = [ '8', ['systemd-random-seed'], 'ENABLE_RANDOMSEED'], + ['systemd-rc-local-generator', '8', [], ''], ['systemd-remount-fs.service', '8', ['systemd-remount-fs'], ''], ['systemd-resolve', '1', [], 'ENABLE_RESOLVE'], ['systemd-resolved.service', '8', ['systemd-resolved'], 'ENABLE_RESOLVE'], @@ -654,6 +670,7 @@ manpages = [ ['systemd', '1', ['init'], ''], ['systemd.automount', '5', [], ''], ['systemd.device', '5', [], ''], + ['systemd.dnssd', '5', [], 'ENABLE_RESOLVE'], ['systemd.environment-generator', '7', [], 'ENABLE_ENVIRONMENT_D'], ['systemd.exec', '5', [], ''], ['systemd.generator', '7', [], ''], @@ -662,7 +679,6 @@ manpages = [ ['systemd.link', '5', [], ''], ['systemd.mount', '5', [], ''], ['systemd.netdev', '5', [], 'ENABLE_NETWORKD'], - ['systemd.dnssd', '5', [], 'ENABLE_RESOLVE'], ['systemd.network', '5', [], 'ENABLE_NETWORKD'], ['systemd.nspawn', '5', [], ''], ['systemd.offline-updates', '7', [], ''], diff --git a/man/runlevel.xml b/man/runlevel.xml index b3d90d8ff4..596307af9f 100644 --- a/man/runlevel.xml +++ b/man/runlevel.xml @@ -173,10 +173,9 @@ <variablelist> <varlistentry> - <term><filename>/var/run/utmp</filename></term> + <term><filename>/run/utmp</filename></term> - <listitem><para>The utmp database <command>runlevel</command> - reads the previous and current runlevel + <listitem><para>The utmp database <command>runlevel</command> reads the previous and current runlevel from.</para></listitem> </varlistentry> </variablelist> diff --git a/man/sd_bus_add_match.xml b/man/sd_bus_add_match.xml index 4772c738ac..f11d078284 100644 --- a/man/sd_bus_add_match.xml +++ b/man/sd_bus_add_match.xml @@ -45,8 +45,11 @@ <refnamediv> <refname>sd_bus_add_match</refname> + <refname>sd_bus_add_match_async</refname> + <refname>sd_bus_match_signal</refname> + <refname>sd_bus_match_signal_async</refname> - <refpurpose>Add a match rule for message dispatching</refpurpose> + <refpurpose>Add a match rule for incoming message dispatching</refpurpose> </refnamediv> <refsynopsisdiv> @@ -54,6 +57,13 @@ <funcsynopsisinfo>#include <systemd/sd-bus.h></funcsynopsisinfo> <funcprototype> + <funcdef>typedef int (*<function>sd_bus_message_handler_t</function>)</funcdef> + <paramdef>sd_bus_message *<parameter>m</parameter></paramdef> + <paramdef>void *<parameter>userdata</parameter></paramdef> + <paramdef>sd_bus_error *<parameter>ret_error</parameter></paramdef> + </funcprototype> + + <funcprototype> <funcdef>int <function>sd_bus_add_match</function></funcdef> <paramdef>sd_bus *<parameter>bus</parameter></paramdef> <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> @@ -63,57 +73,111 @@ </funcprototype> <funcprototype> - <funcdef>typedef int (*<function>sd_bus_message_handler_t</function>)</funcdef> - <paramdef>sd_bus_message *<parameter>m</parameter></paramdef> + <funcdef>int <function>sd_bus_add_match_async</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> + <paramdef>const char *<parameter>match</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>callback</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>install_callback</parameter></paramdef> + <paramdef>void *<parameter>userdata</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_match_signal</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> + <paramdef>const char *<parameter>sender</parameter></paramdef> + <paramdef>const char *<parameter>path</parameter></paramdef> + <paramdef>const char *<parameter>interface</parameter></paramdef> + <paramdef>const char *<parameter>member</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>callback</parameter></paramdef> + <paramdef>void *<parameter>userdata</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_match_signal_async</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> + <paramdef>const char *<parameter>sender</parameter></paramdef> + <paramdef>const char *<parameter>path</parameter></paramdef> + <paramdef>const char *<parameter>interface</parameter></paramdef> + <paramdef>const char *<parameter>member</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>callback</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>install_callback</parameter></paramdef> <paramdef>void *<parameter>userdata</parameter></paramdef> - <paramdef>sd_bus_error *<parameter>ret_error</parameter></paramdef> </funcprototype> + </funcsynopsis> </refsynopsisdiv> <refsect1> <title>Description</title> - <para> - <function>sd_bus_add_match()</function> installs a match rule for incoming messages received on the specified bus - connection object <parameter>bus</parameter>. The syntax of the match rule expression passed in - <parameter>match</parameter> is described in the <ulink - url="https://dbus.freedesktop.org/doc/dbus-specification.html">D-Bus Specification</ulink>. The specified handler - function <parameter>callback</parameter> is called for eaching incoming message matching the specified - expression, the <parameter>userdata</parameter> parameter is passed as-is to the callback function. + <para><function>sd_bus_add_match()</function> installs a match rule for messages received on the specified bus + connection object <parameter>bus</parameter>. The syntax of the match rule expression passed in + <parameter>match</parameter> is described in the <ulink + url="https://dbus.freedesktop.org/doc/dbus-specification.html">D-Bus Specification</ulink>. The specified handler + function <parameter>callback</parameter> is called for eaching incoming message matching the specified expression, + the <parameter>userdata</parameter> parameter is passed as-is to the callback function. The match is installed + synchronously when connected to a bus broker, i.e. the call sends a control message requested the match to be added + to the broker and waits until the broker confirms the match has been installed successfully.</para> + + <para><function>sd_bus_add_match_async()</function> operates very similar to + <function>sd_bus_match_signal()</function>, however it installs the match asynchronously, in a non-blocking + fashion: a request is sent to the broker, but the call does not wait for a response. The + <parameter>install_callback</parameter> function is called when the response is later received, with the response + message from the broker as parameter. If this function is specified as <constant>NULL</constant> a default + implementation is used that terminates the bus connection should installing the match fail.</para> + + <para><function>sd_bus_match_signal()</function> is very similar to <function>sd_bus_add_match()</function>, but + only matches signals, and instead of a match expression accepts four parameters: <parameter>sender</parameter> (the + service name of the sender), <parameter>path</parameter> (the object path of the emitting object), + <parameter>interface</parameter> (the interface the signal belongs to), <parameter>member</parameter> (the signal + name), from which the match string is internally generated. Optionally, these parameters may be specified as + <constant>NULL</constant> in which case the relevant field of incoming signals is not tested.</para> + + <para><function>sd_bus_match_signal_async()</function> is combines the signal matching logic of + <function>sd_bus_match_signal()</function> with the asynchronous behaviour of + <function>sd_bus_add_match_async()</function>.</para> + + <para>On success, and if non-<constant>NULL</constant>, the <parameter>slot</parameter> return parameter will be + set to a slot object that may be used as a reference to the installed match, and may be utilized to remove it again + at a later time with + <citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If specified + as <constant>NULL</constant> the lifetime of the match is bound to the lifetime of the bus object itself, and the + match cannot be removed independently.</para> + + <para>The message <parameter>m</parameter> passed to the callback is only borrowed, that is, the callback should + not call <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry> + on it. If the callback wants to hold on to the message beyond the lifetime of the callback, it needs to call + <citerefentry><refentrytitle>sd_bus_message_ref</refentrytitle><manvolnum>3</manvolnum></citerefentry> to create a + new reference.</para> + + <para>If an error occurs during the callback invocation, the callback should return a negative error number + (optionally, a more precise error may be returned in <parameter>ret_error</parameter>, as well). If it wants other + callbacks that match the same rule to be called, it should return 0. Otherwise it should return a positive integer. </para> - <para> - On success, and if non-<constant>NULL</constant>, the <parameter>slot</parameter> return parameter will be set to - a slot object that may be used as a reference to the installed match, and may be utilized to remove it again at a - later time with - <citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If - specified as <constant>NULL</constant> the lifetime of the match is bound to the lifetime of the bus object itself, and the match - cannot be removed independently. - </para> + <para>If the <parameter>bus</parameter> refers to a direct connection (i.e. not a bus connection, as set with + <citerefentry><refentrytitle>sd_bus_set_bus_client</refentrytitle><manvolnum>3</manvolnum></citerefentry>) the + match is only installed on the client side, and the synchronous and asynchronous functions operate the same.</para> + </refsect1> - <para> - The message <parameter>m</parameter> passed to the callback is only borrowed, that is, the callback should not - call <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry> on - it. If the callback wants to hold on to the message beyond the lifetime of the callback, it needs to call - <citerefentry><refentrytitle>sd_bus_message_ref</refentrytitle><manvolnum>3</manvolnum></citerefentry> to create - a new reference. - </para> + <refsect1> + <title>Return Value</title> <para> - If an error occurs during the callback invocation, the callback should return a negative error number. If it - wants other callbacks that match the same rule to be called, it should return 0. Otherwise it should return a - positive integer. + On success, <function>sd_bus_add_match()</function> and the other calls return 0 or a positive integer. On + failure, they return a negative errno-style error code. </para> </refsect1> <refsect1> - <title>Return Value</title> + <title>Notes</title> - <para> - On success, <function>sd_bus_add_match()</function> returns 0 or a positive integer. On failure, it returns a - negative errno-style error code. - </para> + <para><function>sd_bus_add_match()</function> and the other functions described here are available as a shared + library, which can be compiled and linked to with the <constant>libsystemd</constant> <citerefentry + project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para> </refsect1> <refsect1> @@ -121,7 +185,10 @@ <para> <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, - <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry> + <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_message_ref</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_set_bus_client</refentrytitle><manvolnum>3</manvolnum></citerefentry> </para> </refsect1> diff --git a/man/sd_bus_creds_get_pid.xml b/man/sd_bus_creds_get_pid.xml index 6bc78edf07..d08a24ea80 100644 --- a/man/sd_bus_creds_get_pid.xml +++ b/man/sd_bus_creds_get_pid.xml @@ -369,7 +369,7 @@ <para><function>sd_bus_creds_get_cgroup()</function> will retrieve the control group path. See <ulink - url="https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">cgroups.txt</ulink>. + url="https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt">cgroups.txt</ulink>. </para> <para><function>sd_bus_creds_get_unit()</function> will retrieve diff --git a/man/sd_bus_is_open.xml b/man/sd_bus_is_open.xml new file mode 100644 index 0000000000..9bc671fc37 --- /dev/null +++ b/man/sd_bus_is_open.xml @@ -0,0 +1,137 @@ +<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*--> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" +"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> + +<!-- + SPDX-License-Identifier: LGPL-2.1+ + + This file is part of systemd. + + Copyright 2017 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +--> + +<refentry id="sd_bus_is_open"> + + <refentryinfo> + <title>sd_bus_is_open</title> + <productname>systemd</productname> + + <authorgroup> + <author> + <contrib>Developer</contrib> + <firstname>Lennart</firstname> + <surname>Poettering</surname> + <email>lennart@poettering.net</email> + </author> + </authorgroup> + </refentryinfo> + + <refmeta> + <refentrytitle>sd_bus_is_open</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>sd_bus_is_open</refname> + <refname>sd_bus_is_ready</refname> + + <refpurpose>Check whether the a bus connection is open or ready.</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo>#include <systemd/sd-bus.h></funcsynopsisinfo> + + <funcprototype> + <funcdef>int <function>sd_bus_is_open</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_is_ready</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + </funcprototype> + + </funcsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para><function>sd_bus_is_open()</function> checks whether the specified bus connection is open, i.e. in the + process of being established, already established or in the process of being torn down. It returns zero when the + connection has not been started yet + (i.e. <citerefentry><refentrytitle>sd_bus_start</refentrytitle><manvolnum>3</manvolnum></citerefentry> or some + equivalent call has not been invoked yet), or is fully terminated again (for example after + <citerefentry><refentrytitle>sd_bus_close</refentrytitle><manvolnum>3</manvolnum></citerefentry>), it returns + positive otherwise.</para> + + <para><function>sd_bus_is_ready()</function> checks whether the specified connection is fully established, + i.e. completed the connection and authentication phases of the protocol and received the + <function>Hello()</function> method call response, and is not in the process of being torn down again. It returns + zero outside of this state, and positive otherwise. Effectively, this function returns positive while regular + messages can be sent or received on the connection.</para> + + <para>To be notified when the connection is fully established, use + <citerefentry><refentrytitle>sd_bus_set_connected_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry> and + install a match for the <function>Connected()</function> signal on the + <literal>org.freedesktop.DBus.Local</literal> interface. To be notified when the connection is torn down again, + install a match for the <function>Disconnected()</function> signal on the + <literal>org.freedesktop.DBus.Local</literal> interface.</para> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para>On success, these functions return 0 or a positive integer. On failure, they return a negative errno-style + error code.</para> + </refsect1> + + <refsect1> + <title>Errors</title> + + <para>Returned errors may indicate the following problems:</para> + + <variablelist> + <varlistentry> + <term><constant>-ECHILD</constant></term> + + <listitem><para>The bus connection has been created in a different process.</para></listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Notes</title> + + <para><function>sd_bus_is_open()</function> and <function>sd_bus_is_ready()</function> are available as + a shared library, which can be compiled and linked to with the <constant>libsystemd</constant> <citerefentry + project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para> + </refsect1> + + <refsect1> + <title>See Also</title> + + <para> + <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_start</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_close</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_set_connected_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry> + </para> + </refsect1> + +</refentry> diff --git a/man/sd_bus_message_set_destination.xml b/man/sd_bus_message_set_destination.xml new file mode 100644 index 0000000000..ff69a23152 --- /dev/null +++ b/man/sd_bus_message_set_destination.xml @@ -0,0 +1,137 @@ +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" + "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> + +<!-- + SPDX-License-Identifier: LGPL-2.1+ + + This file is part of systemd. + + Copyright 2017 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +--> + +<refentry id="sd_bus_message_set_destination"> + + <refentryinfo> + <title>sd_bus_message_set_destination</title> + <productname>systemd</productname> + + <authorgroup> + <author> + <contrib>Developer</contrib> + <firstname>Lennart</firstname> + <surname>Poettering</surname> + <email>lennart@poettering.net</email> + </author> + </authorgroup> + </refentryinfo> + + <refmeta> + <refentrytitle>sd_bus_message_set_destination</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>sd_bus_message_set_destination</refname> + <refname>sd_bus_message_set_sender</refname> + <refpurpose>Set the destination or sender service name of a bus message</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo>#include <systemd/sd-bus.h></funcsynopsisinfo> + + <funcprototype> + <funcdef>int <function>sd_bus_message_set_destination</function></funcdef> + <paramdef>sd_bus_message *<parameter>message</parameter></paramdef> + <paramdef>const char *<parameter>destination</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_message_set_sender</function></funcdef> + <paramdef>sd_bus_message *<parameter>message</parameter></paramdef> + <paramdef>const char *<parameter>sender</parameter></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para><function>sd_bus_message_set_destination()</function> sets the destination service name for the specified bus + message object. The specified name must be a valid unique or well-known service name.</para> + + <para><function>sd_bus_message_set_sender()</function> sets the sender service name for the specified bus message + object. The specified name must be a valid unique or well-known service name. This function is useful only for + messages to send on direct connections as for connections to bus brokers the broker will fill in the destination + field anyway, and the sender field set by original sender is ignored.</para> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para>On success, these calls return 0 or a positive integer. On failure, these calls return a negative errno-style + error code.</para> + </refsect1> + + <refsect1> + <title>Errors</title> + + <para>Returned errors may indicate the following problems:</para> + + <variablelist> + <varlistentry> + <term><constant>-EINVAL</constant></term> + + <listitem><para>A specified parameter is invalid.</para></listitem> + </varlistentry> + + <varlistentry> + <term><constant>-EPERM</constant></term> + + <listitem><para>The message is already sealed.</para></listitem> + </varlistentry> + + <varlistentry> + <term><constant>-EEXIST</constant></term> + + <listitem><para>The message already has a destination or sender field set.</para></listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Notes</title> + + <para>The <function>sd_bus_message_set_destination()</function> and + <function>sd_bus_message_set_sender()</function> interfaces + are available as a shared library, which can be compiled and + linked to with the + <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> + file.</para> + </refsect1> + + <refsect1> + <title>See Also</title> + + <para> + <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry> + </para> + </refsect1> + +</refentry> diff --git a/man/sd_bus_request_name.xml b/man/sd_bus_request_name.xml index f44cfdb1ac..9e668f0b02 100644 --- a/man/sd_bus_request_name.xml +++ b/man/sd_bus_request_name.xml @@ -46,7 +46,9 @@ <refnamediv> <refname>sd_bus_request_name</refname> + <refname>sd_bus_request_name_async</refname> <refname>sd_bus_release_name</refname> + <refname>sd_bus_release_name_async</refname> <refpurpose>Request or release a well-known service name on a bus</refpurpose> </refnamediv> @@ -62,70 +64,102 @@ </funcprototype> <funcprototype> + <funcdef>int <function>sd_bus_request_name_async</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> + <paramdef>const char *<parameter>name</parameter></paramdef> + <paramdef>uint64_t <parameter>flags</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>callback</parameter></paramdef> + <paramdef>void *<parameter>userdata</parameter></paramdef> + </funcprototype> + + <funcprototype> <funcdef>int <function>sd_bus_release_name</function></funcdef> <paramdef>sd_bus *<parameter>bus</parameter></paramdef> <paramdef>const char *<parameter>name</parameter></paramdef> </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_release_name_async</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> + <paramdef>const char *<parameter>name</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>callback</parameter></paramdef> + <paramdef>void *<parameter>userdata</parameter></paramdef> + </funcprototype> </funcsynopsis> </refsynopsisdiv> <refsect1> <title>Description</title> - <para><function>sd_bus_request_name()</function> requests a - well-known service name on a bus. It takes a bus connection, a - valid bus name and a flags parameter. The flags parameter is a - combination of the following flags:</para> + <para><function>sd_bus_request_name()</function> requests a well-known service name on a bus. It takes a bus + connection, a valid bus name and a flags parameter. The flags parameter is a combination of the following + flags:</para> <variablelist> <varlistentry> <term><varname>SD_BUS_NAME_ALLOW_REPLACEMENT</varname></term> - <listitem><para>After acquiring the name successfully, permit - other peers to take over the name when they try to acquire it - with the <varname>SD_BUS_NAME_REPLACE_EXISTING</varname> flag - set. If <varname>SD_BUS_NAME_ALLOW_REPLACEMENT</varname> is - not set on the original request, such a request by other peers - will be denied.</para></listitem> + <listitem><para>After acquiring the name successfully, permit other peers to take over the name when they try + to acquire it with the <varname>SD_BUS_NAME_REPLACE_EXISTING</varname> flag set. If + <varname>SD_BUS_NAME_ALLOW_REPLACEMENT</varname> is not set on the original request, such a request by other + peers will be denied.</para></listitem> </varlistentry> <varlistentry> <term><varname>SD_BUS_NAME_REPLACE_EXISTING</varname></term> - <listitem><para>Take over the name if it is already acquired - by another peer, and that other peer has permitted takeover by - setting <varname>SD_BUS_NAME_ALLOW_REPLACEMENT</varname> while - acquiring it.</para></listitem> + <listitem><para>Take over the name if it is already acquired by another peer, and that other peer has permitted + takeover by setting <varname>SD_BUS_NAME_ALLOW_REPLACEMENT</varname> while acquiring it.</para></listitem> </varlistentry> <varlistentry> <term><varname>SD_BUS_NAME_QUEUE</varname></term> - <listitem><para>Queue the acquisition of the name when the - name is already taken.</para></listitem> + <listitem><para>Queue the acquisition of the name when the name is already taken.</para></listitem> </varlistentry> </variablelist> - <para><function>sd_bus_release_name()</function> releases an - acquired well-known name. It takes a bus connection and a valid - bus name as parameters.</para> + <para><function>sd_bus_request_name()</function> operates in a synchronous fashion: a message requesting the name + is sent to the bus broker, and the call waits until the broker responds.</para> + + <para><function>sd_bus_request_name_async()</function> is an asynchronous version of of + <function>sd_bus_release_name()</function>. Instead of waiting for the request to complete, the request message is + enqueued. The specified <parameter>callback</parameter> will be called when the broker's response is received. If + the parameter is specified as <constant>NULL</constant> a default implementation is used instead which will + terminate the connection when the name cannot be acquired. The function returns a slot object in its + <parameter>slot</parameter> parameter — if it is passed as non-<constant>NULL</constant> — which may be used as a + reference to the name request operation. Use + <citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry> to destroy + this reference. Note that destroying the reference will not unregister the name, but simply ensure the specified + callback is no longer called.</para> + + <para><function>sd_bus_release_name()</function> releases an acquired well-known name. It takes a bus connection + and a valid bus name as parameters. This function operates synchronously, sending a release request message to the + bus broker and waiting for it to reply.</para> + + <para><function>sd_bus_release_name_async()</function> is an asynchronous version of + <function>sd_bus_release_name()</function>. The specified <parameter>callback</parameter> function is called when + the name has been released successfully. If specified as <constant>NULL</constant> a generic implementation is used + that ignores the result of the operation. As above, the <parameter>slot</parameter> (if + non-<constant>NULL</constant>) is set to an object that may be used to reference the operation.</para> + + <para>These functions are supported only on bus connections, i.e. connections to a bus broker and not on direct + connections.</para> </refsect1> <refsect1> <title>Return Value</title> - <para>On success, these calls return 0 or a positive integer. On - failure, these calls return a negative errno-style error - code.</para> - - <para>If <varname>SD_BUS_NAME_QUEUE</varname> is specified, - <function>sd_bus_request_name()</function> will return 0 when the - name is already taken by another peer and the client has been - added to the queue for the name. In that case, the caller can - subscribe to <literal>NameOwnerChanged</literal> signals to be - notified when the name is successfully acquired. - <function>sd_bus_request_name()</function> returns > 0 when the - name has immediately been acquired successfully.</para> + <para>On success, these calls return 0 or a positive integer. On failure, these calls return a negative errno-style + error code.</para> + + <para>If <varname>SD_BUS_NAME_QUEUE</varname> is specified, <function>sd_bus_request_name()</function> will return + 0 when the name is already taken by another peer and the client has been added to the queue for the name. In that + case, the caller can subscribe to <literal>NameOwnerChanged</literal> signals to be notified when the name is + successfully acquired. <function>sd_bus_request_name()</function> returns > 0 when the name has immediately + been acquired successfully.</para> </refsect1> <refsect1> @@ -137,56 +171,50 @@ <varlistentry> <term><constant>-EALREADY</constant></term> - <listitem><para>The caller already is the owner of the - specified name.</para></listitem> + <listitem><para>The caller already is the owner of the specified name.</para></listitem> </varlistentry> <varlistentry> <term><constant>-EEXIST</constant></term> - <listitem><para>The name has already been acquired by a - different peer, and SD_BUS_NAME_REPLACE_EXISTING was not - specified or the other peer did not specify - SD_BUS_NAME_ALLOW_REPLACEMENT while acquiring the + <listitem><para>The name has already been acquired by a different peer, and SD_BUS_NAME_REPLACE_EXISTING was + not specified or the other peer did not specify SD_BUS_NAME_ALLOW_REPLACEMENT while acquiring the name.</para></listitem> </varlistentry> <varlistentry> <term><constant>-ESRCH</constant></term> - <listitem><para>It was attempted to release a name that is - currently not registered on the bus.</para></listitem> + <listitem><para>It was attempted to release a name that is currently not registered on the + bus.</para></listitem> </varlistentry> <varlistentry> <term><constant>-EADDRINUSE</constant></term> - <listitem><para>It was attempted to release a name that is - owned by a different peer on the bus.</para></listitem> + <listitem><para>It was attempted to release a name that is owned by a different peer on the + bus.</para></listitem> </varlistentry> <varlistentry> <term><constant>-EINVAL</constant></term> - <listitem><para>A specified parameter is invalid. This is also - generated when the requested name is a special service name - reserved by the D-Bus specification, or when the operation is - requested on a connection that does not refer to a - bus.</para></listitem> + <listitem><para>A specified parameter is invalid. This is also generated when the requested name is a special + service name reserved by the D-Bus specification, or when the operation is requested on a connection that does + not refer to a bus.</para></listitem> </varlistentry> <varlistentry> <term><constant>-ENOTCONN</constant></term> - <listitem><para>The bus connection has been - disconnected.</para></listitem> + <listitem><para>The bus connection has been disconnected.</para></listitem> </varlistentry> <varlistentry> <term><constant>-ECHILD</constant></term> - <listitem><para>The bus connection has been created in a - different process than the current one.</para></listitem> + <listitem><para>The bus connection has been created in a different process than the current + one.</para></listitem> </varlistentry> </variablelist> </refsect1> @@ -194,12 +222,9 @@ <refsect1> <title>Notes</title> - <para>The <function>sd_bus_acquire_name()</function> and - <function>sd_bus_release_name()</function> interfaces are - available as a shared library, which can be compiled and linked to - with the - <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> - file.</para> + <para>The <function>sd_bus_acquire_name()</function> and the other interfaces described here are available as a + shared library, which can be compiled and linked to with the <constant>libsystemd</constant> <citerefentry + project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para> </refsect1> <refsect1> @@ -208,7 +233,8 @@ <para> <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>, - <citerefentry><refentrytitle>sd_bus_new</refentrytitle><manvolnum>3</manvolnum></citerefentry> + <citerefentry><refentrytitle>sd_bus_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry> </para> </refsect1> diff --git a/man/sd_bus_set_connected_signal.xml b/man/sd_bus_set_connected_signal.xml new file mode 100644 index 0000000000..9374dac3a5 --- /dev/null +++ b/man/sd_bus_set_connected_signal.xml @@ -0,0 +1,143 @@ +<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*--> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" +"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> + +<!-- + SPDX-License-Identifier: LGPL-2.1+ + + This file is part of systemd. + + Copyright 2017 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +--> + +<refentry id="sd_bus_set_connected_signal"> + + <refentryinfo> + <title>sd_bus_set_connected_signal</title> + <productname>systemd</productname> + + <authorgroup> + <author> + <contrib>Developer</contrib> + <firstname>Lennart</firstname> + <surname>Poettering</surname> + <email>lennart@poettering.net</email> + </author> + </authorgroup> + </refentryinfo> + + <refmeta> + <refentrytitle>sd_bus_set_connected_signal</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>sd_bus_set_connected_signal</refname> + <refname>sd_bus_get_connected_signal</refname> + + <refpurpose>Control emmission of local connection establishment signal on bus connections</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo>#include <systemd/sd-bus.h></funcsynopsisinfo> + + <funcprototype> + <funcdef>int <function>sd_bus_set_connected_signal</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>int <parameter>b</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_get_connected_signal</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + </funcprototype> + + </funcsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para><function>sd_bus_set_connected_signal()</function> may be used to control whether a local, synthetic + <function>Connected()</function> signal message shall be generated and enqueued for dispatching when the connection + is fully established. If the <parameter>b</parameter> parameter is zero the message is not generated (the default), + otherwise it is generated.</para> + + <para><function>sd_bus_get_connected_signal()</function> may be used to query whether this feature is enabled. It + returns zero if not, positive otherwise.</para> + + <para>The <function>Connected()</function> signal message is generated from the + <literal>org.freedesktop.DBus.Local</literal> service and interface, and + <literal>/org/freedesktop/DBus/Local</literal> object path. Use + <citerefentry><refentrytitle>sd_bus_match_signal_async</refentrytitle><manvolnum>3</manvolnum></citerefentry> to + match on this signal.</para> + + <para>This message is particularly useful on slow transports where connections take a long time to be + established. This is especially the case when + <citerefentry><refentrytitle>sd_bus_set_watch_bind</refentrytitle><manvolnum>3</manvolnum></citerefentry> is + used. The signal is generated when the + <citerefentry><refentrytitle>sd_bus_is_ready</refentrytitle><manvolnum>3</manvolnum></citerefentry> returns + positive for the first time.</para> + + <para>The <function>Connected()</function> signal corresponds with the <function>Disconnected()</function> signal + that is synthesized locally when the connection is terminated. The latter is generated unconditionally however, + unlike the former which needs to be enabled explicitly before it is generated, with + <function>sd_bus_set_connected_signal()</function>.</para> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para>On success, these functions return 0 or a positive integer. On failure, they return a negative errno-style + error code.</para> + </refsect1> + + <refsect1> + <title>Errors</title> + + <para>Returned errors may indicate the following problems:</para> + + <variablelist> + <varlistentry> + <term><constant>-ECHILD</constant></term> + + <listitem><para>The bus connection has been created in a different process.</para></listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Notes</title> + + <para><function>sd_bus_set_connected_signal()</function> and <function>sd_bus_get_connected_signal()</function> are available as + a shared library, which can be compiled and linked to with the <constant>libsystemd</constant> <citerefentry + project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para> + </refsect1> + + <refsect1> + <title>See Also</title> + + <para> + <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_match_signal_async</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_set_watch_bind</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_is_ready</refentrytitle><manvolnum>3</manvolnum></citerefentry> + </para> + </refsect1> + +</refentry> diff --git a/man/sd_bus_set_sender.xml b/man/sd_bus_set_sender.xml new file mode 100644 index 0000000000..38efda7286 --- /dev/null +++ b/man/sd_bus_set_sender.xml @@ -0,0 +1,136 @@ +<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*--> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" +"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> + +<!-- + SPDX-License-Identifier: LGPL-2.1+ + + This file is part of systemd. + + Copyright 2017 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +--> + +<refentry id="sd_bus_set_sender"> + + <refentryinfo> + <title>sd_bus_set_sender</title> + <productname>systemd</productname> + + <authorgroup> + <author> + <contrib>Developer</contrib> + <firstname>Lennart</firstname> + <surname>Poettering</surname> + <email>lennart@poettering.net</email> + </author> + </authorgroup> + </refentryinfo> + + <refmeta> + <refentrytitle>sd_bus_set_sender</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>sd_bus_set_sender</refname> + <refname>sd_bus_get_sender</refname> + + <refpurpose>Configure default sender for outgoing messages</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo>#include <systemd/sd-bus.h></funcsynopsisinfo> + + <funcprototype> + <funcdef>int <function>sd_bus_set_sender</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>const char* <parameter>name</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_get_sender</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>const char** <parameter>name</parameter></paramdef> + </funcprototype> + + </funcsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para><function>sd_bus_set_sender()</function> configures the default sender service name to use for outgoing + messages. The service name specified in the <parameter>name</parameter> parameter is set on all outgoing messages + that are sent on the connection and have no sender set yet, for example through + <citerefentry><refentrytitle>sd_bus_message_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>. Note + that this function is only supported on direct connections, i.e. not on connections to a bus broker as the broker + will fill in the sender service name automatically anyway. By default no sender name is configured, and hence + messages are sent without sender field set. If the <parameter>name</parameter> parameter is specified as + <constant>NULL</constant> the default sender service name is cleared, returning to the default state if a default + sender service name was set before. If passed as non-<constant>NULL</constant> the specified name must be a valid + unique or well-known service name.</para> + + <para><function>sd_bus_get_sender()</function> may be used to query the current default service name for outgoing + messages.</para> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para>On success, these functions return 0 or a positive integer. On failure, they return a negative errno-style + error code.</para> + </refsect1> + + <refsect1> + <title>Errors</title> + + <para>Returned errors may indicate the following problems:</para> + + <variablelist> + <varlistentry> + <term><constant>-ECHILD</constant></term> + + <listitem><para>The bus connection has been created in a different process.</para></listitem> + </varlistentry> + + <varlistentry> + <term><constant>-EPERM</constant></term> + + <listitem><para>The specified bus connection object is a not a direct but a brokered connection.</para></listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Notes</title> + + <para><function>sd_bus_set_sender()</function> and <function>sd_bus_get_sender()</function> are available as + a shared library, which can be compiled and linked to with the <constant>libsystemd</constant> <citerefentry + project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para> + </refsect1> + + <refsect1> + <title>See Also</title> + + <para> + <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_message_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry> + </para> + </refsect1> + +</refentry> diff --git a/man/sd_bus_set_watch_bind.xml b/man/sd_bus_set_watch_bind.xml new file mode 100644 index 0000000000..5e6a6fa588 --- /dev/null +++ b/man/sd_bus_set_watch_bind.xml @@ -0,0 +1,152 @@ +<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*--> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" +"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> + +<!-- + SPDX-License-Identifier: LGPL-2.1+ + + This file is part of systemd. + + Copyright 2017 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +--> + +<refentry id="sd_bus_set_watch_bind"> + + <refentryinfo> + <title>sd_bus_set_watch_bind</title> + <productname>systemd</productname> + + <authorgroup> + <author> + <contrib>Developer</contrib> + <firstname>Lennart</firstname> + <surname>Poettering</surname> + <email>lennart@poettering.net</email> + </author> + </authorgroup> + </refentryinfo> + + <refmeta> + <refentrytitle>sd_bus_set_watch_bind</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>sd_bus_set_watch_bind</refname> + <refname>sd_bus_get_watch_bind</refname> + + <refpurpose>Control socket binding watching on bus connections</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo>#include <systemd/sd-bus.h></funcsynopsisinfo> + + <funcprototype> + <funcdef>int <function>sd_bus_set_watch_bind</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>int <parameter>b</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_get_watch_bind</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + </funcprototype> + + </funcsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para><function>sd_bus_set_watch_bind()</function> may be used to enable or disable client-side watching of server + socket binding for a bus connection object. If the <parameter>b</parameter> is true, the feature is enabled, + otherwise disabled (which is the default). When enabled, and the selected bus address refers to an + <filename>AF_UNIX</filename> socket in the file system which does not exist while the connection attempt is made an + <citerefentry><refentrytitle>inotify</refentrytitle><manvolnum>7</manvolnum></citerefentry> watch is installed on + it, waiting for the socket to appear. As soon as the socket appears the connection is made. This functionality is + useful in particular in early-boot programs that need to run before the system bus is available, but want to + connect to it the instant it may be connected to.</para> + + <para><function>sd_bus_get_watch_bind()</function> may be used to query the current setting of this feature. It + returns zero when the feature is disabled, and positive if enabled.</para> + + <para>Note that no timeout is applied while it is waited for the socket to appear. This means that any synchronous + remote operation (such as + <citerefentry><refentrytitle>sd_bus_call</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry> or + <citerefentry><refentrytitle>sd_bus_request_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>), that is + used on a connection with this feature enabled that is not established yet might block unbounded if the socket is + never created. However, asynchronous remote operations (such as + <citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_add_match_async</refentrytitle><manvolnum>3</manvolnum></citerefentry> or + <citerefentry><refentrytitle>sd_bus_request_match_async</refentrytitle><manvolnum>3</manvolnum></citerefentry>) do + not block in this case, and safely enqueue the requested operations to be dispatched the instant the connection is + set up.</para> + + <para>Use <citerefentry><refentrytitle>sd_bus_is_ready</refentrytitle><manvolnum>3</manvolnum></citerefentry> to + determine whether the connection is fully established, i.e. whether the peer socket has been bound, connected to + and authenticated. Use + <citerefentry><refentrytitle>sd_bus_set_connected_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry> to + be notified when the connection is fully established.</para> + + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para>On success, these functions return 0 or a positive integer. On failure, they return a negative errno-style + error code.</para> + </refsect1> + + <refsect1> + <title>Errors</title> + + <para>Returned errors may indicate the following problems:</para> + + <variablelist> + <varlistentry> + <term><constant>-ECHILD</constant></term> + + <listitem><para>The bus connection has been created in a different process.</para></listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Notes</title> + + <para><function>sd_bus_set_watch_bind()</function> and <function>sd_bus_get_watch_bind()</function> are available as + a shared library, which can be compiled and linked to with the <constant>libsystemd</constant> <citerefentry + project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para> + </refsect1> + + <refsect1> + <title>See Also</title> + + <para> + <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>inotify</refentrytitle><manvolnum>7</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_call</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_request_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_is_ready</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>sd_bus_set_connected_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry> + </para> + </refsect1> + +</refentry> diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml index b162b2bf11..b15fc1728c 100644 --- a/man/sd_journal_get_fd.xml +++ b/man/sd_journal_get_fd.xml @@ -231,6 +231,20 @@ else { </refsect1> <refsect1> + <title>Signal safety</title> + + <para>In general, <function>sd_journal_get_fd()</function>, <function>sd_journal_get_events()</function>, and + <function>sd_journal_get_timeout()</function> are <emphasis>not</emphasis> "async signal safe" in the meaning of + <citerefentry + project='man-pages'><refentrytitle>signal-safety</refentrytitle><manvolnum>7</manvolnum></citerefentry>. + Nevertheless, only the first call to any of those three functions performs unsafe operations, so subsequent calls + <emphasis>are</emphasis> safe.</para> + + <para><function>sd_journal_process()</function> and <function>sd_journal_wait()</function> are not + safe. <function>sd_journal_reliable_fd()</function> is safe.</para> + </refsect1> + + <refsect1> <title>Notes</title> <para>The <function>sd_journal_get_fd()</function>, diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml index f771ba307f..038d3bbbd4 100644 --- a/man/sd_journal_print.xml +++ b/man/sd_journal_print.xml @@ -205,8 +205,8 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( <title>Thread safety</title> <para>All functions listed here are thread-safe and may be called in parallel from multiple threads.</para> - <para><function>sd_journal_sendv()</function> is "async signal safe" in the meaning of - <citerefentry project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>. + <para><function>sd_journal_sendv()</function> is "async signal safe" in the meaning of <citerefentry + project='man-pages'><refentrytitle>signal-safety</refentrytitle><manvolnum>7</manvolnum></citerefentry>. </para> <para><function>sd_journal_print</function>, diff --git a/man/sd_journal_stream_fd.xml b/man/sd_journal_stream_fd.xml index 29d64f91d7..13972aea7c 100644 --- a/man/sd_journal_stream_fd.xml +++ b/man/sd_journal_stream_fd.xml @@ -94,6 +94,10 @@ <para>It is recommended that applications log UTF-8 messages only with this API, but this is not enforced.</para> + + <para>Each invocation of <function>sd_journal_stream_fd()</function> allocates a new log stream file descriptor, + that is not shared with prior or later invocations. The file descriptor is write-only (its reading direction is + shut down), and <constant>O_NONBLOCK</constant> is turned off initially.</para> </refsect1> <refsect1> @@ -104,11 +108,18 @@ </refsect1> <refsect1> + <title>Signal safety</title> + + <para><function>sd_journal_stream_fd()</function> is "async signal safe" in the meaning of <citerefentry + project='man-pages'><refentrytitle>signal-safety</refentrytitle><manvolnum>7</manvolnum></citerefentry>. + </para> + </refsect1> + + <refsect1> <title>Notes</title> <para>Function <function>sd_journal_stream_fd()</function> is thread-safe and may be called - from multiple threads. All calls will return the same file descriptor, although temporarily - multiple file descriptors may be open.</para> + from multiple threads.</para> <para>The <function>sd_journal_stream_fd()</function> interface is available as a shared library, which can be compiled and linked to diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index 876f96d559..4f7248cd0c 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -53,7 +53,7 @@ <refnamediv> <refname>systemd-analyze</refname> - <refpurpose>Analyze system boot-up performance</refpurpose> + <refpurpose>Analyze and debug system manager</refpurpose> </refnamediv> <refsynopsisdiv> @@ -94,24 +94,14 @@ <cmdsynopsis> <command>systemd-analyze</command> <arg choice="opt" rep="repeat">OPTIONS</arg> - <arg choice="plain">set-log-level</arg> - <arg choice="plain"><replaceable>LEVEL</replaceable></arg> + <arg choice="plain">log-level</arg> + <arg choice="opt"><replaceable>LEVEL</replaceable></arg> </cmdsynopsis> <cmdsynopsis> <command>systemd-analyze</command> <arg choice="opt" rep="repeat">OPTIONS</arg> - <arg choice="plain">set-log-target</arg> - <arg choice="plain"><replaceable>TARGET</replaceable></arg> - </cmdsynopsis> - <cmdsynopsis> - <command>systemd-analyze</command> - <arg choice="opt" rep="repeat">OPTIONS</arg> - <arg choice="plain">get-log-level</arg> - </cmdsynopsis> - <cmdsynopsis> - <command>systemd-analyze</command> - <arg choice="opt" rep="repeat">OPTIONS</arg> - <arg choice="plain">get-log-target</arg> + <arg choice="plain">log-target</arg> + <arg choice="opt"><replaceable>TARGET</replaceable></arg> </cmdsynopsis> <cmdsynopsis> <command>systemd-analyze</command> @@ -131,6 +121,12 @@ <arg choice="plain">calendar</arg> <arg choice="plain" rep="repeat"><replaceable>SPECS</replaceable></arg> </cmdsynopsis> + <cmdsynopsis> + <command>systemd-analyze</command> + <arg choice="opt" rep="repeat">OPTIONS</arg> + <arg choice="plain">service-watchdogs</arg> + <arg choice="opt"><replaceable>BOOL</replaceable></arg> + </cmdsynopsis> </refsynopsisdiv> <refsect1> @@ -139,7 +135,8 @@ <para><command>systemd-analyze</command> may be used to determine system boot-up performance statistics and retrieve other state and tracing information from the system and service manager, and to - verify the correctness of unit files.</para> + verify the correctness of unit files. It is also used to access + special functions useful for advanced system manager debugging.</para> <para><command>systemd-analyze time</command> prints the time spent in the kernel before userspace has been reached, the time @@ -191,26 +188,20 @@ state. Its format is subject to change without notice and should not be parsed by applications.</para> - <para><command>systemd-analyze set-log-level - <replaceable>LEVEL</replaceable></command> changes the current log - level of the <command>systemd</command> daemon to - <replaceable>LEVEL</replaceable> (accepts the same values as + <para><command>systemd-analyze log-level</command> + prints the current log level of the <command>systemd</command> daemon. + If an optional argument <replaceable>LEVEL</replaceable> is provided, then the command changes the current log + level of the <command>systemd</command> daemon to <replaceable>LEVEL</replaceable> (accepts the same values as <option>--log-level=</option> described in <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para> - <para><command>systemd-analyze set-log-target - <replaceable>TARGET</replaceable></command> changes the current log - target of the <command>systemd</command> daemon to - <replaceable>TARGET</replaceable> (accepts the same values as + <para><command>systemd-analyze log-target</command> + prints the current log target of the <command>systemd</command> daemon. + If an optional argument <replaceable>TARGET</replaceable> is provided, then the command changes the current log + target of the <command>systemd</command> daemon to <replaceable>TARGET</replaceable> (accepts the same values as <option>--log-target=</option>, described in <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para> - <para><command>systemd-analyze get-log-level</command> - prints the current log level of the <command>systemd</command> daemon.</para> - - <para><command>systemd-analyze get-log-target</command> - prints the current log target of the <command>systemd</command> daemon.</para> - <para><command>systemd-analyze syscall-filter <optional><replaceable>SET</replaceable>…</optional></command> will list system calls contained in the specified system call set <replaceable>SET</replaceable>, or all known sets if no sets are specified. Argument <replaceable>SET</replaceable> must include @@ -232,6 +223,14 @@ syntax described in <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para> + <para><command>systemd-analyze service-watchdogs</command> + prints the current state of service runtime watchdogs of the <command>systemd</command> daemon. + If an optional boolean argument is provided, then globally enables or disables the service + runtime watchdogs (<option>WatchdogSec=</option>) and emergency actions (e.g. + <option>OnFailure=</option> or <option>StartLimitAction=</option>); see + <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>. + The hardware watchdog is not affected by this setting.</para> + <para>If no command is passed, <command>systemd-analyze time</command> is implied.</para> diff --git a/man/systemd-getty-generator.xml b/man/systemd-getty-generator.xml index adb48a7fd6..17fd0e9c19 100644 --- a/man/systemd-getty-generator.xml +++ b/man/systemd-getty-generator.xml @@ -75,7 +75,7 @@ sufficient to redirect the kernel console with a kernel command line argument such as <varname>console=</varname> to get both kernel messages and a getty prompt on a serial TTY. See <ulink - url="https://www.kernel.org/doc/Documentation/kernel-parameters.txt"><filename>kernel-parameters.txt</filename></ulink> + url="https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt"><filename>kernel-parameters.txt</filename></ulink> for more information on the <varname>console=</varname> kernel parameter.</para> diff --git a/man/systemd-journal-gatewayd.service.xml b/man/systemd-journal-gatewayd.service.xml index 4d461d9be4..dbc859285b 100644 --- a/man/systemd-journal-gatewayd.service.xml +++ b/man/systemd-journal-gatewayd.service.xml @@ -281,7 +281,7 @@ <term><uri>boot</uri></term> <listitem><para>Limit events to the current boot of the system - (like <command>journalctl --this-boot</command>).</para></listitem> + (like <command>journalctl -b</command>).</para></listitem> </varlistentry> <varlistentry> diff --git a/man/systemd-logind.service.xml b/man/systemd-logind.service.xml index b51158b7cd..f3a3b24200 100644 --- a/man/systemd-logind.service.xml +++ b/man/systemd-logind.service.xml @@ -100,9 +100,9 @@ <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> for information about the configuration of this service.</para> - <para>See <ulink - url="https://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat - on Linux</ulink> for an introduction into basic concepts of logind + <para>See + <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry> + for information about the basic concepts of logind such as users, sessions and seats.</para> <para>See the <ulink @@ -123,6 +123,7 @@ <citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry> + <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry> </para> </refsect1> diff --git a/man/systemd-mount.xml b/man/systemd-mount.xml index 87bc2b36eb..76ea0550d7 100644 --- a/man/systemd-mount.xml +++ b/man/systemd-mount.xml @@ -160,6 +160,14 @@ </varlistentry> <varlistentry> + <term><option>--owner=<replaceable>USER</replaceable></option></term> + + <listitem><para>Let the specified user <replaceable>USER</replaceable> own the mounted file system. + This is done by appending <option>uid=</option> and <option>gid=</option> options to the list + of mount options. Only certain file systems support this option.</para></listitem> + </varlistentry> + + <varlistentry> <term><option>--fsck=</option></term> <listitem><para>Takes a boolean argument, defaults to on. Controls whether to run a file system check diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml index acd4ee41fc..874bdd882b 100644 --- a/man/systemd-notify.xml +++ b/man/systemd-notify.xml @@ -123,6 +123,15 @@ </varlistentry> <varlistentry> + <term><option>--uid=</option><replaceable>USER</replaceable></term> + + <listitem><para>Set the user ID to send the notification from. Takes a UNIX user name or numeric UID. When + specified the notification message will be sent with the specified UID as sender, in place of the user the + command was invoked as. This option requires sufficient privileges in order to be able manipulate the user + identity of the process.</para></listitem> + </varlistentry> + + <varlistentry> <term><option>--status=</option></term> <listitem><para>Send a free-form status string for the daemon diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index 3dbdf376d3..633d939384 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -149,7 +149,7 @@ <title>Options</title> <para>If option <option>-b</option> is specified, the arguments - are used as arguments for the init binary. Otherwise, + are used as arguments for the init program. Otherwise, <replaceable>COMMAND</replaceable> specifies the program to launch in the container, and the remaining arguments are used as arguments for this program. If <option>--boot</option> is not used and @@ -273,12 +273,12 @@ <term><option>--as-pid2</option></term> <listitem><para>Invoke the shell or specified program as process ID (PID) 2 instead of PID 1 (init). By - default, if neither this option nor <option>--boot</option> is used, the selected binary is run as process with - PID 1, a mode only suitable for programs that are aware of the special semantics that the process with PID 1 - has on UNIX. For example, it needs to reap all processes reparented to it, and should implement + default, if neither this option nor <option>--boot</option> is used, the selected program is run as the process + with PID 1, a mode only suitable for programs that are aware of the special semantics that the process with + PID 1 has on UNIX. For example, it needs to reap all processes reparented to it, and should implement <command>sysvinit</command> compatible signal handling (specifically: it needs to reboot on SIGINT, reexecute on SIGTERM, reload configuration on SIGHUP, and so on). With <option>--as-pid2</option> a minimal stub init - process is run as PID 1 and the selected binary is executed as PID 2 (and hence does not need to implement any + process is run as PID 1 and the selected program is executed as PID 2 (and hence does not need to implement any special semantics). The stub init process will reap processes as necessary and react appropriately to signals. It is recommended to use this mode to invoke arbitrary commands in containers, unless they have been modified to run correctly as PID 1. Or in other words: this switch should be used for pretty much all commands, @@ -291,9 +291,9 @@ <term><option>-b</option></term> <term><option>--boot</option></term> - <listitem><para>Automatically search for an init binary and invoke it as PID 1, instead of a shell or a user + <listitem><para>Automatically search for an init program and invoke it as PID 1, instead of a shell or a user supplied program. If this option is used, arguments specified on the command line are used as arguments for the - init binary. This option may not be combined with <option>--as-pid2</option>.</para> + init program. This option may not be combined with <option>--as-pid2</option>.</para> <para>The following table explains the different modes of invocation and relationship to <option>--as-pid2</option> (see above):</para> @@ -322,7 +322,7 @@ <row> <entry><option>--boot</option> specified</entry> - <entry>An init binary as automatically searched and run as PID 1 in the container. The passed parameters are used as invocation parameters for this process.</entry> + <entry>An init program is automatically searched for and run as PID 1 in the container. The passed parameters are used as invocation parameters for this process.</entry> </row> </tbody> @@ -398,6 +398,7 @@ </varlistentry> <varlistentry> + <term><option>-S</option></term> <term><option>--slice=</option></term> <listitem><para>Make the container part of the specified slice, instead of the default @@ -705,22 +706,17 @@ <varlistentry> <term><option>--capability=</option></term> - <listitem><para>List one or more additional capabilities to - grant the container. Takes a comma-separated list of - capability names, see + <listitem><para>List one or more additional capabilities to grant the container. + Takes a comma-separated list of capability names, see <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry> - for more information. Note that the following capabilities - will be granted in any way: CAP_CHOWN, CAP_DAC_OVERRIDE, - CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID, CAP_IPC_OWNER, - CAP_KILL, CAP_LEASE, CAP_LINUX_IMMUTABLE, - CAP_NET_BIND_SERVICE, CAP_NET_BROADCAST, CAP_NET_RAW, - CAP_SETGID, CAP_SETFCAP, CAP_SETPCAP, CAP_SETUID, - CAP_SYS_ADMIN, CAP_SYS_CHROOT, CAP_SYS_NICE, CAP_SYS_PTRACE, - CAP_SYS_TTY_CONFIG, CAP_SYS_RESOURCE, CAP_SYS_BOOT, - CAP_AUDIT_WRITE, CAP_AUDIT_CONTROL. Also CAP_NET_ADMIN is - retained if <option>--private-network</option> is specified. - If the special value <literal>all</literal> is passed, all - capabilities are retained.</para></listitem> + for more information. Note that the following capabilities will be granted in any way: + CAP_AUDIT_CONTROL, CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, + CAP_FOWNER, CAP_FSETID, CAP_IPC_OWNER, CAP_KILL, CAP_LEASE, CAP_LINUX_IMMUTABLE, + CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_BROADCAST, CAP_NET_RAW, CAP_SETFCAP, + CAP_SETGID, CAP_SETPCAP, CAP_SETUID, CAP_SYS_ADMIN, CAP_SYS_BOOT, CAP_SYS_CHROOT, + CAP_SYS_NICE, CAP_SYS_PTRACE, CAP_SYS_RESOURCE, CAP_SYS_TTY_CONFIG. Also CAP_NET_ADMIN + is retained if <option>--private-network</option> is specified. If the special value + <literal>all</literal> is passed, all capabilities are retained.</para></listitem> </varlistentry> <varlistentry> @@ -1114,7 +1110,7 @@ <example> <title>Spawn a shell in a container of a minimal Debian unstable distribution</title> - <programlisting># debootstrap --arch=amd64 unstable ~/debian-tree/ + <programlisting># debootstrap unstable ~/debian-tree/ # systemd-nspawn -D ~/debian-tree/</programlisting> <para>This installs a minimal Debian unstable distribution into diff --git a/man/systemd-rc-local-generator.xml b/man/systemd-rc-local-generator.xml new file mode 100644 index 0000000000..89cd7ec614 --- /dev/null +++ b/man/systemd-rc-local-generator.xml @@ -0,0 +1,86 @@ +<?xml version="1.0"?> +<!--*-nxml-*--> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> +<!-- + SPDX-License-Identifier: LGPL-2.1+ + + This file is part of systemd. + + Copyright 2017 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +--> +<refentry id="systemd-rc-local-generator"> + + <refentryinfo> + <title>systemd-rc-local-generator</title> + <productname>systemd</productname> + + <authorgroup> + <author> + <contrib>Developer</contrib> + <firstname>Lennart</firstname> + <surname>Poettering</surname> + <email>lennart@poettering.net</email> + </author> + </authorgroup> + </refentryinfo> + + <refmeta> + <refentrytitle>systemd-rc-local-generator</refentrytitle> + <manvolnum>8</manvolnum> + </refmeta> + + <refnamediv> + <refname>systemd-rc-local-generator</refname> + <refpurpose>Compatibility generator for starting <filename>/etc/rc.local</filename> and <filename>/usr/sbin/halt.local</filename> during boot and shutdown</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <para><filename>/usr/lib/systemd/system-generators/systemd-rc-local-generator</filename></para> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para><filename>systemd-rc-local-generator</filename> is a generator that checks whether + <filename>/etc/rc.local</filename> exists and is executable, and if it is pulls the + <filename>rc-local.service</filename> unit into the boot process. This unit is responsible for running this script + during late boot. Note that the script will be run with slightly different semantics than the original System V + version, which was run "last" in the boot process, which is a concept that does not translate to systemd. The + script is run after <filename>network.target</filename>, but in parallel with most other regular system + services.</para> + + <para><filename>systemd-rc-local-generator</filename> also checks whether <filename>/usr/sbin/halt.local</filename> + exists and is executable, and if it is pulls the <filename>halt-local.service</filename> unit into the shutdown + process. This unit is responsible for running this script during later shutdown.</para> + + <para>Support for both <filename>/etc/rc.local</filename> and <filename>/usr/sbin/halt.local</filename> is provided + for compatibility with specific System V systems only. However, it is strongly recommended to avoid making use of + these scripts today, and instead provide proper unit files with appropriate dependencies for any scripts to run + during the boot or shutdown processes.</para> + + <para><filename>systemd-rc-local-generator</filename> implements + <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para> + </refsect1> + + <refsect1> + <title>See Also</title> + <para> + <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, + <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> + </para> + </refsect1> + +</refentry> diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 9db6a26dfd..cfdbd2289f 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -47,7 +47,7 @@ <refnamediv> <refname>systemd-run</refname> - <refpurpose>Run programs in transient scope units, service units, or timer-scheduled service units</refpurpose> + <refpurpose>Run programs in transient scope units, service units, or path-, socket-, or timer-triggered service units</refpurpose> </refnamediv> <refsynopsisdiv> @@ -61,6 +61,20 @@ <cmdsynopsis> <command>systemd-run</command> <arg choice="opt" rep="repeat">OPTIONS</arg> + <arg choice="opt" rep="repeat">PATH OPTIONS</arg> + <arg choice="req"><replaceable>COMMAND</replaceable></arg> + <arg choice="opt" rep="repeat">ARGS</arg> + </cmdsynopsis> + <cmdsynopsis> + <command>systemd-run</command> + <arg choice="opt" rep="repeat">OPTIONS</arg> + <arg choice="opt" rep="repeat">SOCKET OPTIONS</arg> + <arg choice="req"><replaceable>COMMAND</replaceable></arg> + <arg choice="opt" rep="repeat">ARGS</arg> + </cmdsynopsis> + <cmdsynopsis> + <command>systemd-run</command> + <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">TIMER OPTIONS</arg> <arg choice="req"><replaceable>COMMAND</replaceable></arg> <arg choice="opt" rep="repeat">ARGS</arg> @@ -72,8 +86,8 @@ <para><command>systemd-run</command> may be used to create and start a transient <filename>.service</filename> or <filename>.scope</filename> unit and run the specified <replaceable>COMMAND</replaceable> in it. It may also be - used to create and start a transient <filename>.timer</filename> unit, that activates a - <filename>.service</filename> unit when elapsing.</para> + used to create and start a transient <filename>.path</filename>, <filename>.socket</filename>, or + <filename>.timer</filename> unit, that activates a <filename>.service</filename> unit when elapsing.</para> <para>If a command is run as transient service unit, it will be started and managed by the service manager like any other service, and thus shows up in the output of <command>systemctl list-units</command> like any other unit. It @@ -88,12 +102,13 @@ list-units</command>. Execution in this case is synchronous, and will return only when the command finishes. This mode is enabled via the <option>--scope</option> switch (see below). </para> - <para>If a command is run with timer options such as <option>--on-calendar=</option> (see below), a transient timer - unit is created alongside the service unit for the specified command. Only the transient timer unit is started - immediately, the transient service unit will be started when the timer elapses. If the <option>--unit=</option> - option is specified, the <replaceable>COMMAND</replaceable> may be omitted. In this case, - <command>systemd-run</command> creates only a <filename>.timer</filename> unit that invokes the specified unit when - elapsing.</para> + <para>If a command is run with path, socket, or timer options such as <option>--on-calendar=</option> (see below), + a transient path, socket, or timer unit is created alongside the service unit for the specified command. Only the + transient path, socket, or timer unit is started immediately, the transient service unit will be triggered by the + path, socket, or timer unit. If the <option>--unit=</option> option is specified, the + <replaceable>COMMAND</replaceable> may be omitted. In this case, <command>systemd-run</command> creates only a + <filename>.path</filename>, <filename>.socket</filename>, or <filename>.timer</filename> unit that triggers the + specified unit.</para> </refsect1> <refsect1> @@ -140,8 +155,8 @@ <varlistentry> <term><option>--description=</option></term> - <listitem><para>Provide a description for the service, scope or timer unit. If not specified, the command - itself will be used as a description. See <varname>Description=</varname> in + <listitem><para>Provide a description for the service, scope, path, socket, or timer unit. If not specified, + the command itself will be used as a description. See <varname>Description=</varname> in <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. </para></listitem> </varlistentry> @@ -155,6 +170,7 @@ </varlistentry> <varlistentry> + <term><option>-r</option></term> <term><option>--remain-after-exit</option></term> <listitem><para>After the service process has terminated, keep the service around until it is explicitly @@ -278,7 +294,8 @@ command. See <varname>OnActiveSec=</varname>, <varname>OnBootSec=</varname>, <varname>OnStartupSec=</varname>, <varname>OnUnitActiveSec=</varname> and <varname>OnUnitInactiveSec=</varname> in <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry> for - details. These options may not be combined with <option>--scope</option> or <option>--pty</option>.</para> + details. These options are shortcuts for <command>--timer-property=</command> with the relevant properties. + These options may not be combined with <option>--scope</option> or <option>--pty</option>.</para> </listitem> </varlistentry> @@ -287,20 +304,23 @@ <listitem><para>Defines a calendar timer for starting the specified command. See <varname>OnCalendar=</varname> in <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>. This - option may not be combined with <option>--scope</option> or <option>--pty</option>.</para> + option is a shortcut for <command>--timer-property=OnCalendar=</command>. This option may not be combined with + <option>--scope</option> or <option>--pty</option>.</para> </listitem> </varlistentry> <varlistentry> + <term><option>--path-property=</option></term> + <term><option>--socket-property=</option></term> <term><option>--timer-property=</option></term> - <listitem><para>Sets a property on the timer unit that is created. This option is similar to - <option>--property=</option> but applies to the transient timer unit rather than the transient service unit - created. This option only has an effect in conjunction with <option>--on-active=</option>, - <option>--on-boot=</option>, <option>--on-startup=</option>, <option>--on-unit-active=</option>, - <option>--on-unit-inactive=</option> or <option>--on-calendar=</option>. This option takes an assignment in the - same format as <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s - <command>set-property</command> command.</para> </listitem> + <listitem><para>Sets a property on the path, socket, or timer unit that is created. This option is similar to + <option>--property=</option> but applies to the transient path, socket, or timer unit rather than the + transient service unit created. This option takes an assignment in the same format as + <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s + <command>set-property</command> command. These options may not be combined with + <option>--scope</option> or <option>--pty</option>.</para> + </listitem> </varlistentry> <varlistentry> @@ -323,7 +343,7 @@ completed). On exit, terse information about the unit's runtime is shown, including total runtime (as well as CPU usage, if <option>--property=CPUAccounting=1</option> was set) and the exit code and status of the main process. This output may be suppressed with <option>--quiet</option>. This option may not be combined with - <option>--no-block</option>, <option>--scope</option> or the various timer options.</para></listitem> + <option>--no-block</option>, <option>--scope</option> or the various path, socket, or timer options.</para></listitem> </varlistentry> <varlistentry> @@ -352,8 +372,8 @@ <para>All command line arguments after the first non-option argument become part of the command line of the launched - process. If a command is run as service unit, its first argument - needs to be an absolute binary path.</para> + process. If a command is run as service unit, the first argument + needs to be an absolute program path.</para> </refsect1> <refsect1> diff --git a/man/systemd-socket-activate.xml b/man/systemd-socket-activate.xml index 79e35dd30e..ff9e7758b3 100644 --- a/man/systemd-socket-activate.xml +++ b/man/systemd-socket-activate.xml @@ -62,8 +62,9 @@ <refsect1> <title>Description</title> - <para><command>systemd-socket-activate</command> may be used to launch a socket-activated service binary from the command - line for testing purposes. It may also be used to launch individual instances of the service binary per connection. + <para><command>systemd-socket-activate</command> may be used to launch a socket-activated service program from the + command line for testing purposes. It may also be used to launch individual instances of the service program per + connection. </para> <para>The daemon to launch and its options should be specified @@ -97,7 +98,7 @@ <term><option>-a</option></term> <term><option>--accept</option></term> - <listitem><para>Launch an instance of the service binary for each connection and pass the connection + <listitem><para>Launch an instance of the service program for each connection and pass the connection socket.</para></listitem> </varlistentry> diff --git a/man/systemd.dnssd.xml b/man/systemd.dnssd.xml index 1270e08cd2..054f6615c2 100644 --- a/man/systemd.dnssd.xml +++ b/man/systemd.dnssd.xml @@ -206,7 +206,7 @@ <programlisting># /etc/systemd/dnssd/http.dnssd [Service] -Name=%h +Name=%H Type=_http._tcp Port=80 TxtText=path=/stats/index.html t=temperature_sensor</programlisting> diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 3d81e45732..2f62f1cd6b 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -376,12 +376,14 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting> <listitem><para>Takes a boolean argument. If true, ensures that the service process and all its children can never gain new privileges through <function>execve()</function> (e.g. via setuid or setgid bits, or filesystem capabilities). This is the simplest and most effective way to ensure that a process and its children can never - elevate privileges again. Defaults to false, but certain settings force <varname>NoNewPrivileges=yes</varname>, - ignoring the value of this setting. This is the case when <varname>SystemCallFilter=</varname>, + elevate privileges again. Defaults to false, but certain settings override this and ignore the value of this + setting. This is the case when <varname>SystemCallFilter=</varname>, <varname>SystemCallArchitectures=</varname>, <varname>RestrictAddressFamilies=</varname>, <varname>RestrictNamespaces=</varname>, <varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>, <varname>ProtectKernelModules=</varname>, - <varname>MemoryDenyWriteExecute=</varname>, or <varname>RestrictRealtime=</varname> are specified. Also see + <varname>MemoryDenyWriteExecute=</varname>, <varname>RestrictRealtime=</varname>, or + <varname>LockPersonality=</varname> are specified. Note that even if this setting is overridden by them, + <command>systemctl show</command> shows the original value of this setting. Also see <ulink url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges Flag</ulink>. </para></listitem> </varlistentry> diff --git a/man/systemd.generator.xml b/man/systemd.generator.xml index 55bb2b4a90..7ed6a2dc82 100644 --- a/man/systemd.generator.xml +++ b/man/systemd.generator.xml @@ -261,7 +261,7 @@ <para>Of these two rules the first rule is probably the more important one and breaks the second one sometimes. Hence, - when deciding whether to user argv[1], argv[2], or argv[3], + when deciding whether to use argv[1], argv[2], or argv[3], your default choice should probably be argv[1].</para> </listitem> @@ -336,6 +336,7 @@ find $dir</programlisting> <citerefentry><refentrytitle>systemd-getty-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd-hibernate-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>, + <citerefentry><refentrytitle>systemd-rc-local-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd-sysv-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>, diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index b08ef1777e..15a166280b 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -339,7 +339,7 @@ <varlistentry> <term><varname>_STREAM_ID=</varname></term> <listitem> - <para>Only applies to <literal>_TRANSPORT=stream</literal> records: specifies a randomized 128bit ID assigned + <para>Only applies to <literal>_TRANSPORT=stdout</literal> records: specifies a randomized 128bit ID assigned to the stream connection when it was first created. This ID is useful to reconstruct individual log streams from the log records: all log records carrying the same stream ID originate from the same stream.</para> </listitem> @@ -347,7 +347,7 @@ <varlistentry> <term><varname>_LINE_BREAK=</varname></term> <listitem> - <para>Only applies to <literal>_TRANSPORT=stream</literal> records: indicates that the log message in the + <para>Only applies to <literal>_TRANSPORT=stdout</literal> records: indicates that the log message in the standard output/error stream was not terminated with a normal newline character (<literal>\n</literal>, i.e. ASCII 10). Specifically, when set this field is one of <option>nul</option> (in case the line was terminated by a NUL byte), <option>line-max</option> (in case the maximum log line length was reached, as diff --git a/man/systemd.link.xml b/man/systemd.link.xml index 162674f769..794e0e06fc 100644 --- a/man/systemd.link.xml +++ b/man/systemd.link.xml @@ -172,6 +172,17 @@ for details.</para> </listitem> </varlistentry> + <varlistentry> + <term><varname>KernelVersion=</varname></term> + <listitem> + <para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain + expression (or if prefixed with the exclamation mark does not match it). See + <literal>ConditionKernelVersion=</literal> in + <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for + details. + </para> + </listitem> + </varlistentry> <varlistentry> <term><varname>Architecture=</varname></term> <listitem> @@ -442,6 +453,8 @@ </listitem> </varlistentry> </variablelist> + + <para>Defaults to <literal>off</literal>.</para> </listitem> </varlistentry> <varlistentry> diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index 663e7fa3ac..8607bd797f 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -71,18 +71,22 @@ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>, which define the execution environment the <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry> - binary is executed in, and in + program is executed in, and in <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>, which define the way the processes are terminated, and in <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>, which configure resource control settings for the processes of the - service. Note that the User= and Group= options are not - particularly useful for mount units specifying a - <literal>Type=</literal> option or using configuration not - specified in <filename>/etc/fstab</filename>; + service.</para> + + <para>Note that the options <varname>User=</varname> and + <varname>Group=</varname> are not useful for mount units. + systemd passes two parameters to + <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>; + the values of <varname>What=</varname> and <varname>Where=</varname>. + When invoked in this way, <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry> - will refuse options that are not listed in - <filename>/etc/fstab</filename> if it is not run as UID 0.</para> + does not read any options from <filename>/etc/fstab</filename>, and + must be run as UID 0.</para> <para>Mount units must be named after the mount point directories they control. Example: the mount point <filename noindex='true'>/home/lennart</filename> must be configured in a unit file <filename>home-lennart.mount</filename>. diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index c92792341b..eb86db9792 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -184,6 +184,9 @@ <entry>The virtual CAN tunnel driver (vxcan). Similar to the virtual ethernet driver veth, vxcan implements a local CAN traffic tunnel between two virtual CAN network devices. When creating a vxcan, two vxcan devices are created as pair. When one end receives the packet it appears on its pair and vice versa. The vxcan can be used for cross namespace communication. </entry></row> + <row><entry><varname>wireguard</varname></entry> + <entry>WireGuard Secure Network Tunnel.</entry></row> + </tbody> </tgroup> </table> @@ -233,6 +236,16 @@ </listitem> </varlistentry> <varlistentry> + <term><varname>KernelVersion=</varname></term> + <listitem> + <para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain + expression (or if prefixed with the exclamation mark does not match it). See + <literal>ConditionKernelVersion=</literal> in + <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>Architecture=</varname></term> <listitem> <para>Checks whether the system is running on a specific @@ -499,7 +512,15 @@ <term><varname>Mode=</varname></term> <listitem> <para>The IPVLAN mode to use. The supported options are - <literal>L2</literal> and <literal>L3</literal>. + <literal>L2</literal>,<literal>L3</literal> and <literal>L3S</literal>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>Flags=</varname></term> + <listitem> + <para>The IPVLAN flags to use. The supported options are + <literal>bridge</literal>,<literal>private</literal> and <literal>vepa</literal>. </para> </listitem> </varlistentry> @@ -871,6 +892,14 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term><varname>AllowLocalRemote=</varname></term> + <listitem> + <para>A boolean. When true allows tunnel traffic on <varname>ip6tnl</varname> devices where the remote endpoint is a local host address. + Defaults to unset. + </para> + </listitem> + </varlistentry> </variablelist> </refsect1> <refsect1> @@ -984,6 +1013,103 @@ </refsect1> <refsect1> + <title>[WireGuard] Section Options</title> + + <para>The <literal>[WireGuard]</literal> section accepts the following + keys:</para> + + <variablelist class='network-directives'> + <varlistentry> + <term><varname>PrivateKey=</varname></term> + <listitem> + <para>The Base64 encoded private key for the interface. It can be + generated using the <command>wg genkey</command> command + (see <citerefentry project="wireguard"><refentrytitle>wg</refentrytitle><manvolnum>8</manvolnum></citerefentry>). + This option is mandatory to use wireguard.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>ListenPort=</varname></term> + <listitem> + <para>Sets UDP port for listening. Takes either value between 1 and 65535 + or <literal>auto</literal>. If <literal>auto</literal> is specified, + the port is automatically generated based on interface name. + Defaults to <literal>auto</literal>.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>FwMark=</varname></term> + <listitem> + <para>Sets a firewall mark on outgoing wireguard packets from this interface.</para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>[WireGuardPeer] Section Options</title> + + <para>The <literal>[WireGuardPeer]</literal> section accepts the following + keys:</para> + + <variablelist class='network-directives'> + <varlistentry> + <term><varname>PublicKey=</varname></term> + <listitem> + <para>Sets a Base64 encoded public key calculated by <command>wg pubkey</command> + (see <citerefentry project="wireguard"><refentrytitle>wg</refentrytitle><manvolnum>8</manvolnum></citerefentry>) + from a private key, and usually transmitted out of band to the + author of the configuration file. This option is mandatory for this + section.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>PresharedKey=</varname></term> + <listitem> + <para>Optional preshared key for the interface. It can be generated + by the <command>wg genpsk</command> command. This option adds an + additional layer of symmetric-key cryptography to be mixed into the + already existing public-key cryptography, for post-quantum + resistance.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>AllowedIPs=</varname></term> + <listitem> + <para>Sets a comma-separated list of IP (v4 or v6) addresses with CIDR masks + from which this peer is allowed to send incoming traffic and to + which outgoing traffic for this peer is directed. The catch-all + 0.0.0.0/0 may be specified for matching all IPv4 addresses, and + ::/0 may be specified for matching all IPv6 addresses. </para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>Endpoint=</varname></term> + <listitem> + <para>Sets an endpoint IP address or hostname, followed by a colon, and then + a port number. This endpoint will be updated automatically once to + the most recent source IP address and port of correctly + authenticated packets from the peer at configuration time.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>PersistentKeepalive=</varname></term> + <listitem> + <para>Sets a seconds interval, between 1 and 65535 inclusive, of how often + to send an authenticated empty packet to the peer for the purpose + of keeping a stateful firewall or NAT mapping valid persistently. + For example, if the interface very rarely sends traffic, but it + might at anytime receive traffic from a peer, and it is behind NAT, + the interface might benefit from having a persistent keepalive + interval of 25 seconds. If set to 0 or "off", this option is + disabled. By default or when unspecified, this option is off. + Most users will not need this.</para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> <title>[Bond] Section Options</title> <para>The <literal>[Bond]</literal> section accepts the following @@ -1365,6 +1491,21 @@ Name=macvtap-test Kind=macvtap </programlisting> </example> + <example> + <title>/etc/systemd/network/25-wireguard.netdev</title> + <programlisting>[NetDev] +Name=wg0 +Kind=wireguard + +[WireGuard] +PrivateKey=EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong= +ListenPort=51820 + +[WireGuardPeer] +PublicKey=RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA= +AllowedIPs=fd31:bf08:57cb::/48,192.168.26.0/24 +Endpoint=wireguard.example.com:51820</programlisting> + </example> </refsect1> <refsect1> <title>See Also</title> diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 3466f3a3cf..80d2802610 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -194,6 +194,17 @@ </listitem> </varlistentry> <varlistentry> + <term><varname>KernelVersion=</varname></term> + <listitem> + <para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain + expression (or if prefixed with the exclamation mark does not match it). See + <literal>ConditionKernelVersion=</literal> in + <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for + details. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>Architecture=</varname></term> <listitem> <para>Checks whether the system is running on a specific @@ -656,8 +667,16 @@ <varlistentry> <term><varname>IPv6PrefixDelegation=</varname></term> <listitem><para>Whether to enable or disable Router Advertisement sending on a link. - Defaults to <literal>false</literal>. See the <literal>[IPv6PrefixDelegation]</literal> - and the <literal>[IPv6Prefix]</literal> sections for configuration options. + Allowed values are <literal>static</literal> which distributes prefixes as defined in + the <literal>[IPv6PrefixDelegation]</literal> and any <literal>[IPv6Prefix]</literal> + sections, <literal>dhcpv6</literal> which requests prefixes using a DHCPv6 client + configured for another link and any values configured in the + <literal>[IPv6PrefixDelegation]</literal> section while ignoring all static prefix + configuration sections, <literal>yes</literal> which uses both static configuration + and DHCPv6, and <literal>false</literal> which turns off IPv6 prefix delegation + altogether. Defaults to <literal>false</literal>. See the + <literal>[IPv6PrefixDelegation]</literal> and the <literal>[IPv6Prefix]</literal> + sections for more configuration options. </para></listitem> </varlistentry> <varlistentry> @@ -1056,6 +1075,33 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term><varname>InitialCongestionWindow=</varname></term> + <listitem> + <para>The TCP initial congestion window is used during the start of a TCP connection. During the start of a TCP + session, when a client requests a resource, the server's initial congestion window determines how many data bytes + will be sent during the initial burst of data. Takes a size in bytes between 1 and 4294967295 (2^32 - 1). The usual + suffixes K, M, G are supported and are understood to the base of 1024. Defaults to unset. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>InitialAdvertisedReceiveWindow=</varname></term> + <listitem> + <para>The TCP initial advertised receive window is the amount of receive data (in bytes) that can initally be buffered at one time + on a connection. The sending host can send only that amount of data before waiting for an acknowledgment and window update + from the receiving host. Takes a size in bytes between 1 and 4294967295 (2^32 - 1). The usual suffixes K, M, G are supported + and are understood to the base of 1024. Defaults to unset. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>QuickAck=</varname></term> + <listitem> + <para>Takes a boolean argument. When true enables TCP quick ack mode for the route. Defaults to unset. + </para> + </listitem> + </varlistentry> </variablelist> </refsect1> @@ -1266,6 +1312,20 @@ <para>Allow setting custom port for the DHCP client to listen on.</para> </listitem> </varlistentry> + + <varlistentry> + <term><varname>RapidCommit=</varname></term> + <listitem> + <para>A boolean. The DHCPv6 client can obtain configuration parameters from a DHCPv6 server through + a rapid two-message exchange (solicit and reply). When the rapid commit option is enabled by both + the DHCPv6 client and the DHCPv6 server, the two-message exchange is used, rather than the default + four-method exchange (solicit, advertise, request, and reply). The two-message exchange provides + faster client configuration and is beneficial in environments in which networks are under a heavy load. + See <ulink url="https://tools.ietf.org/html/rfc3315#section-17.2.1">RFC 3315</ulink> for details. + Defaults to true.</para> + </listitem> + </varlistentry> + </variablelist> </refsect1> diff --git a/man/systemd.offline-updates.xml b/man/systemd.offline-updates.xml index 01dd6c55e4..ca7d6d3c18 100644 --- a/man/systemd.offline-updates.xml +++ b/man/systemd.offline-updates.xml @@ -82,7 +82,7 @@ <citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry> checks whether <filename>/system-update</filename> exists. If so, it (temporarily and for this boot only) redirects (i.e. symlinks) <filename>default.target</filename> to - <filename>system-update.target</filename>, a special target that is pulls in the base system + <filename>system-update.target</filename>, a special target that pulls in the base system (i.e. <filename>sysinit.target</filename>, so that all file systems are mounted but little else) and the system update units.</para> </listitem> diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml index 482856221c..7b978f7915 100644 --- a/man/systemd.preset.xml +++ b/man/systemd.preset.xml @@ -136,23 +136,26 @@ </refsect1> <refsect1> - <title>Example</title> + <title>Examples</title> <example> - <title>Default off example <filename>/usr/lib/systemd/system-preset/99-default.preset</filename>:</title> + <title>Default to off</title> - <programlisting>disable *</programlisting> + <programlisting># /usr/lib/systemd/system-preset/99-default.preset + +disable *</programlisting> </example> <para>This disables all units. Due to the filename prefix <literal>99-</literal>, it will be read last and hence can easily - be overridden by spin or administrator preset policy or - suchlike.</para> + be overridden by spin or administrator preset policy.</para> <example> - <title>A GNOME spin example <filename>/usr/lib/systemd/system-preset/50-gnome.preset</filename>:</title> + <title>A GNOME spin</title> - <programlisting>enable gdm.service + <programlisting># /usr/lib/systemd/system-preset/50-gnome.preset + +enable gdm.service enable colord.service enable accounts-daemon.service enable avahi-daemon.*</programlisting> @@ -168,9 +171,11 @@ enable avahi-daemon.*</programlisting> example like the one from the first example above.</para> <example> - <title>Administrator policy <filename>/etc/systemd/system-preset/00-lennart.preset</filename>:</title> + <title>Administrator policy</title> + + <programlisting># /etc/systemd/system-preset/00-lennart.preset - <programlisting>enable httpd.service +enable httpd.service enable sshd.service enable postfix.service disable *</programlisting> @@ -179,8 +184,8 @@ disable *</programlisting> <para>This enables three specific services and disables all others. This is useful for administrators to specifically select the units to enable, and disable all others. Due to the filename - prefix <literal>00-</literal> it will be read early and hence - overrides all other preset policy files.</para> + prefix <literal>00-</literal> it will be read early and + override all other preset policy files.</para> </refsect1> <refsect1> diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml index 092361c6b0..1128d236ce 100644 --- a/man/systemd.scope.xml +++ b/man/systemd.scope.xml @@ -100,8 +100,6 @@ late system shutdown should disable <varname>DefaultDependencies=</varname> option.</para></listitem> </itemizedlist> - - <para></para> </refsect1> <refsect1> diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 76dfe60be4..e796245ae5 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -228,10 +228,10 @@ <varname>PrivateNetwork=</varname><option>yes</option>.</para> <para>Behavior of <option>idle</option> is very similar to <option>simple</option>; however, actual execution - of the service binary is delayed until all active jobs are dispatched. This may be used to avoid interleaving + of the service program is delayed until all active jobs are dispatched. This may be used to avoid interleaving of output of shell services with the status output on the console. Note that this type is useful only to improve console output, it is not useful as a general unit ordering tool, and the effect of this service type - is subject to a 5s time-out, after which the service binary is invoked anyway.</para> + is subject to a 5s time-out, after which the service program is invoked anyway.</para> </listitem> </varlistentry> @@ -264,16 +264,14 @@ <varlistentry> <term><varname>PIDFile=</varname></term> - <listitem><para>Takes an absolute filename pointing to the - PID file of this daemon. Use of this option is recommended for - services where <varname>Type=</varname> is set to - <option>forking</option>. systemd will read the PID of the - main process of the daemon after start-up of the service. - systemd will not write to the file configured here, although - it will remove the file after the service has shut down if it - still exists. - </para> - </listitem> + <listitem><para>Takes an absolute path referring to the PID file of the service. Usage of this option is + recommended for services where <varname>Type=</varname> is set to <option>forking</option>. The service manager + will read the PID of the main process of the service from this file after start-up of the service. The service + manager will not write to the file configured here, although it will remove the file after the service has shut + down if it still exists. The PID file does not need to be owned by a privileged user, but if it is owned by an + unprivileged user additional safety restrictions are enforced: the file may not be a symlink to a file owned by + a different user (neither directly nor indirectly), and the PID file must refer to a process already belonging + to the service.</para></listitem> </varlistentry> <varlistentry> @@ -754,7 +752,8 @@ limiting configured with <varname>StartLimitIntervalSec=</varname> and <varname>StartLimitBurst=</varname>, see <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> - for details.</para> + for details. A restarted service enters the failed state only + after the start limits are reached.</para> <para>Setting this to <option>on-failure</option> is the recommended choice for long-running services, in order to diff --git a/man/systemd.special.xml b/man/systemd.special.xml index 18689a0a9e..2810d6f52c 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -278,17 +278,6 @@ </listitem> </varlistentry> <varlistentry> - <term><filename>getty-pre.target</filename></term> - <listitem> - <para>A special passive target unit. Users of this target - are expected to pull it in the boot transaction via - a dependency (e.g. <varname>Wants=</varname>). Order your - unit before this unit if you want to make use of the console - just before <filename>getty</filename> is started. - </para> - </listitem> - </varlistentry> - <varlistentry> <term><filename>graphical.target</filename></term> <listitem> <para>A special target unit for setting up a graphical login @@ -355,6 +344,29 @@ </listitem> </varlistentry> <varlistentry> + <term><filename>initrd-root-device.target</filename></term> + <listitem> + <para>A special initrd target unit that is reached when the root filesystem device is available, but before + it has been mounted. + <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry> + and + <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry> + automatically setup the appropriate dependencies to make this happen. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><filename>initrd-root-fs.target</filename></term> + <listitem> + <para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry> + automatically adds dependencies of type + <varname>Before=</varname> to the + <filename>sysroot.mount</filename> unit, which is generated + from the kernel command line. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><filename>kbrequest.target</filename></term> <listitem> <para>systemd starts this target whenever Alt+ArrowUp is @@ -539,29 +551,6 @@ </listitem> </varlistentry> <varlistentry> - <term><filename>initrd-root-device.target</filename></term> - <listitem> - <para>A special initrd target unit that is reached when the root filesystem device is available, but before - it has been mounted. - <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry> - and - <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry> - automatically setup the appropriate dependencies to make this happen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><filename>initrd-root-fs.target</filename></term> - <listitem> - <para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry> - automatically adds dependencies of type - <varname>Before=</varname> to the - <filename>sysroot.mount</filename> unit, which is generated - from the kernel command line. - </para> - </listitem> - </varlistentry> - <varlistentry> <term><filename>runlevel2.target</filename></term> <term><filename>runlevel3.target</filename></term> <term><filename>runlevel4.target</filename></term> @@ -821,6 +810,17 @@ </listitem> </varlistentry> <varlistentry> + <term><filename>getty-pre.target</filename></term> + <listitem> + <para>A special passive target unit. Users of this target + are expected to pull it in the boot transaction via + a dependency (e.g. <varname>Wants=</varname>). Order your + unit before this unit if you want to make use of the console + just before <filename>getty</filename> is started. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><filename>local-fs-pre.target</filename></term> <listitem> <para>This target unit is diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index 707b04b208..acedb9fb25 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -72,7 +72,7 @@ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>, which define the execution environment the <citerefentry project='man-pages'><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry> - binary is executed in, in + program is executed in, in <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>, which define the way these processes are terminated, and in diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 5cd8be310d..90ca378e84 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -505,8 +505,8 @@ <listitem><para>Configures requirement dependencies on other units. If this unit gets activated, the units listed here will be activated as well. If one of the other units fails to activate, and an ordering dependency <varname>After=</varname> on the failing unit is set, this unit will not be started. Besides, with or without - specifying <varname>After=</varname>, this unit will be deactivated if one of the other units get deactivated. - This option may be specified more than once or multiple space-separated units may be + specifying <varname>After=</varname>, this unit will be stopped if one of the other units is explicitly + stopped. This option may be specified more than once or multiple space-separated units may be specified in one option in which case requirement dependencies for all listed names will be created. Note that requirement dependencies do not influence the order in which services are started or stopped. This has to be configured independently with the <varname>After=</varname> or <varname>Before=</varname> options. If a unit @@ -665,7 +665,9 @@ <listitem><para>A space-separated list of one or more units that are activated when this unit enters the - <literal>failed</literal> state.</para></listitem> + <literal>failed</literal> state. A service unit using + <varname>Restart=</varname> enters the failed state only after + the start limits are reached.</para></listitem> </varlistentry> <varlistentry> @@ -921,6 +923,7 @@ <term><varname>ConditionVirtualization=</varname></term> <term><varname>ConditionHost=</varname></term> <term><varname>ConditionKernelCommandLine=</varname></term> + <term><varname>ConditionKernelVersion=</varname></term> <term><varname>ConditionSecurity=</varname></term> <term><varname>ConditionCapability=</varname></term> <term><varname>ConditionACPower=</varname></term> @@ -937,6 +940,7 @@ <term><varname>ConditionFileIsExecutable=</varname></term> <term><varname>ConditionUser=</varname></term> <term><varname>ConditionGroup=</varname></term> + <term><varname>ConditionControlGroupController=</varname></term> <!-- We do not document ConditionNull= here, as it is not particularly @@ -1047,6 +1051,17 @@ the exact assignment is looked for with right and left hand side matching.</para> + <para><varname>ConditionKernelVersion=</varname> may be used to check whether the kernel version (as reported + by <command>uname -r</command>) matches a certain expression (or if prefixed with the exclamation mark does not + match it). The argument must be a single string. If the string starts with one of <literal><</literal>, + <literal><=</literal>, <literal>=</literal>, <literal>>=</literal>, <literal>></literal> a relative + version comparison is done, otherwise the specified string is matched with shell-style globs.</para> + + <para>Note that using the kernel version string is an unreliable way to determine which features are supported + by a kernel, because of the widespread practice of backporting drivers, features, and fixes from newer upstream + kernels into older versions provided by distributions. Hence, this check is inherently unportable and should + not be used for units which may be used on different distributions.</para> + <para><varname>ConditionSecurity=</varname> may be used to check whether the given security module is enabled on the system. Currently, the recognized values are @@ -1164,6 +1179,18 @@ auxiliary groups match the specified group or GID. This setting does not have a special value <literal>@system</literal>.</para> + <para><varname>ConditionControlGroupController=</varname> takes a + cgroup controller name (eg. <option>cpu</option>), verifying that it is + available for use on the system. For example, a particular controller + may not be available if it was disabled on the kernel command line with + <literal>cgroup_disable=</literal><replaceable>controller</replaceable>. + Multiple controllers may be passed with a space separating them; in + this case the condition will only pass if all listed controllers are + available for use. Controllers unknown to systemd are ignored. Valid + controllers are <option>cpu</option>, <option>cpuacct</option>, + <option>io</option>, <option>blkio</option>, <option>memory</option>, + <option>devices</option>, and <option>pids</option>.</para> + <para>If multiple conditions are specified, the unit will be executed if all of them apply (i.e. a logical AND is applied). Condition checks can be prefixed with a pipe symbol (|) in @@ -1186,6 +1213,7 @@ <term><varname>AssertVirtualization=</varname></term> <term><varname>AssertHost=</varname></term> <term><varname>AssertKernelCommandLine=</varname></term> + <term><varname>AssertKernelVersion=</varname></term> <term><varname>AssertSecurity=</varname></term> <term><varname>AssertCapability=</varname></term> <term><varname>AssertACPower=</varname></term> @@ -1202,6 +1230,7 @@ <term><varname>AssertFileIsExecutable=</varname></term> <term><varname>AssertUser=</varname></term> <term><varname>AssertGroup=</varname></term> + <term><varname>AssertControlGroupController=</varname></term> <listitem><para>Similar to the <varname>ConditionArchitecture=</varname>, <varname>ConditionVirtualization=</varname>, …, condition settings described above, these settings add diff --git a/man/systemd.xml b/man/systemd.xml index 62ececb6e9..ad2c1e4f0b 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -273,6 +273,15 @@ to all zeros.</para></listitem> </varlistentry> + <varlistentry> + <term><option>--service-watchdogs=</option></term> + + <listitem><para>Globally enable/disable all service watchdog timeouts and emergency + actions. This setting may also be specified during boot, on the kernel + command line via the <varname>systemd.service_watchdogs=</varname> + option, see below. Defaults to enabled.</para></listitem> + </varlistentry> + <xi:include href="standard-options.xml" xpointer="help" /> <xi:include href="standard-options.xml" xpointer="version" /> </variablelist> @@ -297,11 +306,12 @@ states are called "activating", "deactivating"). A special "failed" state is available as well, which is very similar to "inactive" and is entered when the service failed in some way - (process returned error code on exit, or crashed, or an operation - timed out). If this state is entered, the cause will be logged, - for later reference. Note that the various unit types may have a - number of additional substates, which are mapped to the five - generalized unit states described here.</para> + (process returned error code on exit, or crashed, an operation + timed out, or after too many restarts). If this state is entered, + the cause will be logged, for later reference. Note that the + various unit types may have a number of additional substates, + which are mapped to the five generalized unit states described + here.</para> <para>The following unit types are available:</para> @@ -404,7 +414,7 @@ <para>Processes systemd spawns are placed in individual Linux control groups named after the unit which they belong to in the private systemd hierarchy. (see <ulink - url="https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">cgroups.txt</ulink> + url="https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt">cgroups.txt</ulink> for more information about control groups, or short "cgroups"). systemd uses this to effectively keep track of processes. Control group information is maintained in the kernel, and is accessible @@ -573,7 +583,7 @@ <listitem><para>Upon receiving this signal the systemd system manager will start the <filename>ctrl-alt-del.target</filename> unit. This is mostly - equivalent to <command>systemctl start ctl-alt-del.target + equivalent to <command>systemctl start ctrl-alt-del.target --job-mode=replace-irreversible</command>. If this signal is received more than 7 times per 2s, an immediate reboot is triggered. Note that pressing Ctrl-Alt-Del on the console @@ -964,6 +974,19 @@ </varlistentry> <varlistentry> + <term><varname>systemd.service_watchdogs=</varname></term> + + <listitem><para>Takes a boolean argument. If disabled, all service runtime + watchdogs (<option>WatchdogSec=</option>) and emergency actions (e.g. + <option>OnFailure=</option> or <option>StartLimitAction=</option>) are + ignored by the system manager (PID 1); see + <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>. + Defaults to enabled, i.e. watchdogs and failure actions are processed + normally. The hardware watchdog is not affected by this + option.</para></listitem> + </varlistentry> + + <varlistentry> <term><varname>systemd.show_status</varname></term> <listitem><para>Takes a boolean argument or the constant diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml index 38b749cf15..c0d8a1682a 100644 --- a/man/sysusers.d.xml +++ b/man/sysusers.d.xml @@ -191,7 +191,10 @@ u root 0 "Superuser" /root</programlisting> in the file system. In this case, the UID/GID is read from the path's owner/group. This is useful to create users whose UID/GID match the owners of pre-existing files (such as SUID or SGID - binaries).</para> + binaries). + The syntax <literal><replaceable>uid</replaceable>:<replaceable>gid</replaceable></literal> is also supported to + allow creating user and group pairs with different numeric UID and GID values. The group with the indicated GID must get created explicitly before or it must already exist. + </para> <para>For <varname>m</varname> lines, this field should contain the group name to add to a user to.</para> diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index f5d97aa38f..c3a43d36e4 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -147,9 +147,8 @@ L /tmp/foobar - - - - /dev/null</programlisting> <variablelist> <varlistentry> <term><varname>f</varname></term> - <listitem><para>Create a file if it does not exist yet. If - the argument parameter is given, it will be written to the - file. Does not follow symlinks.</para></listitem> + <listitem><para>Create a file if it does not exist yet. If the argument parameter is given and the file did + not exist yet, it will be written to the file. Does not follow symlinks.</para></listitem> </varlistentry> <varlistentry> @@ -484,6 +483,13 @@ r! /tmp/.X[0-9]*-lock</programlisting> The second line in contrast to the first one would break a running system, and will only be executed with <option>--boot</option>.</para> + + <para>Note that for all line types that result in creation of any kind of file node + (i.e. <varname>f</varname>/<varname>F</varname>, + <varname>d</varname>/<varname>D</varname>/<varname>v</varname>/<varname>q</varname>/<varname>Q</varname>, + <varname>p</varname>, <varname>L</varname>, <varname>c</varname>/<varname>b</varname> and <varname>C</varname>) + leading directories are implicitly created if needed, owned by root with an access mode of 0755. In order to + create them with different modes or ownership make sure to add appropriate <varname>d</varname> lines.</para> </refsect2> <refsect2> @@ -578,21 +584,14 @@ r! /tmp/.X[0-9]*-lock</programlisting> <refsect2> <title>Argument</title> - <para>For <varname>L</varname> lines determines the destination - path of the symlink. For <varname>c</varname> and - <varname>b</varname>, determines the major/minor of the device - node, with major and minor formatted as integers, separated by - <literal>:</literal>, e.g. <literal>1:3</literal>. For - <varname>f</varname>, <varname>F</varname>, and - <varname>w</varname>, the argument may be used to specify a short string that - is written to the file, suffixed by a newline. For - <varname>C</varname>, specifies the source file or - directory. For <varname>t</varname> and <varname>T</varname>, - determines extended attributes to be set. For - <varname>a</varname> and <varname>A</varname>, determines ACL - attributes to be set. For <varname>h</varname> and - <varname>H</varname>, determines the file attributes to - set. Ignored for all other lines.</para> + <para>For <varname>L</varname> lines determines the destination path of the symlink. For <varname>c</varname> and + <varname>b</varname>, determines the major/minor of the device node, with major and minor formatted as integers, + separated by <literal>:</literal>, e.g. <literal>1:3</literal>. For <varname>f</varname>, <varname>F</varname>, + and <varname>w</varname>, the argument may be used to specify a short string that is written to the file, + suffixed by a newline. For <varname>C</varname>, specifies the source file or directory. For <varname>t</varname> + and <varname>T</varname>, determines extended attributes to be set. For <varname>a</varname> and + <varname>A</varname>, determines ACL attributes to be set. For <varname>h</varname> and <varname>H</varname>, + determines the file attributes to set. Ignored for all other lines.</para> <para>This field can contain specifiers, see below.</para> </refsect2> @@ -697,7 +696,7 @@ d /run/uscreens 0755 root screen 10d12h </programlisting> <para>Contents of <filename>/run/screens</filename> and /run/uscreens will - cleaned up after 10 and 10½ days, respectively.</para> + be cleaned up after 10 and 10½ days, respectively.</para> </example> <example> diff --git a/man/udev.xml b/man/udev.xml index 7b42d2326b..8e58ead0ba 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -465,6 +465,9 @@ <para>Starting daemons or other long-running processes is not appropriate for udev; the forked processes, detached or not, will be unconditionally killed after the event handling has finished.</para> + <para>Note that running programs that access the network or mount/unmount + filesystems is not allowed inside of udev rules, due to the default sandbox + that is enforced on <filename>systemd-udevd.service</filename>.</para> </listitem> </varlistentry> diff --git a/meson.build b/meson.build index ddc061c126..36a62d280d 100644 --- a/meson.build +++ b/meson.build @@ -16,7 +16,7 @@ # along with systemd; If not, see <http://www.gnu.org/licenses/>. project('systemd', 'c', - version : '236', + version : '237', license : 'LGPLv2+', default_options: [ 'c_std=gnu99', @@ -27,8 +27,8 @@ project('systemd', 'c', meson_version : '>= 0.41', ) -libsystemd_version = '0.20.0' -libudev_version = '1.6.8' +libsystemd_version = '0.21.0' +libudev_version = '1.6.9' # We need the same data in three different formats, ugh! # Also, for hysterical reasons, we use different variable @@ -67,7 +67,7 @@ endif sysvinit_path = get_option('sysvinit-path') sysvrcnd_path = get_option('sysvrcnd-path') -have = sysvinit_path != '' or sysvrcnd_path != '' +have = sysvinit_path != '' and sysvrcnd_path != '' conf.set10('HAVE_SYSV_COMPAT', have, description : 'SysV init scripts and rcN.d links are supported') m4_defines += have ? ['-DHAVE_SYSV_COMPAT'] : [] @@ -259,11 +259,27 @@ substs.set('RC_LOCAL_SCRIPT_PATH_STOP', get_option('halt-l cc = meson.get_compiler('c') pkgconfig = import('pkgconfig') check_compilation_sh = find_program('tools/meson-check-compilation.sh') +meson_build_sh = find_program('tools/meson-build.sh') -cxx = find_program('c++', required : false) -if cxx.found() - # Used only for tests - add_languages('cpp') +if get_option('tests') != 'false' + cxx = find_program('c++', required : false) + if cxx.found() + # Used only for tests + add_languages('cpp') + endif +endif + +want_ossfuzz = get_option('oss-fuzz') +want_libfuzzer = get_option('llvm-fuzz') +fuzzer_build = want_ossfuzz or want_libfuzzer +if want_ossfuzz and want_libfuzzer + error('only one of oss-fuzz and llvm-fuzz can be specified') +endif +if want_libfuzzer + fuzzing_engine = meson.get_compiler('cpp').find_library('Fuzzer') +endif +if want_ossfuzz + fuzzing_engine = meson.get_compiler('cpp').find_library('FuzzingEngine') endif foreach arg : ['-Wextra', @@ -300,7 +316,6 @@ foreach arg : ['-Wextra', '-fvisibility=hidden', '-fstack-protector', '-fstack-protector-strong', - '-fPIE', '--param=ssp-buffer-size=4', ] if cc.has_argument(arg) @@ -308,6 +323,14 @@ foreach arg : ['-Wextra', endif endforeach +# the oss-fuzz fuzzers are not built with -fPIE, so don't +# enable it when we are linking against them +if not fuzzer_build + if cc.has_argument('-fPIE') + add_project_arguments('-fPIE', language : 'c') + endif +endif + # "negative" arguments: gcc on purpose does not return an error for "-Wno-" # arguments, just emits a warnings. So test for the "positive" version instead. foreach arg : ['unused-parameter', @@ -358,11 +381,25 @@ foreach arg : ['-Wl,-z,relro', cc.cmd_array(), '-x', 'c', arg, '-include', link_test_c).returncode() == 0 message('Linking with @0@ supported: @1@'.format(arg, have ? 'yes' : 'no')) - if have + if have and (arg != '-pie' or not fuzzer_build) add_project_link_arguments(arg, language : 'c') endif endforeach +# Check if various sanitizers are supported +sanitizers = [] +foreach arg : ['address'] + + have = run_command(check_compilation_sh, + cc.cmd_array(), '-x', 'c', + '-fsanitize=@0@'.format(arg), + '-include', link_test_c).returncode() == 0 + message('@0@ sanitizer supported: @1@'.format(arg, have ? 'yes' : 'no')) + if have + sanitizers += arg + endif +endforeach + if get_option('buildtype') != 'debug' foreach arg : ['-ffunction-sections', '-fdata-sections'] @@ -422,7 +459,7 @@ foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'], ['IN6_ADDR_GEN_MODE_STABLE_PRIVACY', 'linux/if_link.h'], ['IFLA_VRF_TABLE', 'linux/if_link.h'], ['IFLA_MACVLAN_FLAGS', 'linux/if_link.h'], - ['IFLA_IPVLAN_MODE', 'linux/if_link.h'], + ['IFLA_IPVLAN_FLAGS', 'linux/if_link.h'], ['IFLA_PHYS_PORT_ID', 'linux/if_link.h'], ['IFLA_BOND_AD_INFO', 'linux/if_link.h'], ['IFLA_VLAN_PROTOCOL', 'linux/if_link.h'], @@ -437,6 +474,7 @@ foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'], ['IFLA_BRPORT_PROXYARP', 'linux/if_link.h'], ['IFLA_BRPORT_LEARNING_SYNC', 'linux/if_link.h'], ['IFLA_BR_VLAN_DEFAULT_PVID', 'linux/if_link.h'], + ['IPVLAN_F_PRIVATE', 'linux/if_link.h'], ['NDA_IFINDEX', 'linux/neighbour.h'], ['IFA_FLAGS', 'linux/if_addr.h'], ['FRA_UID_RANGE', 'linux/fib_rules.h'], @@ -453,17 +491,17 @@ foreach ident : ['secure_getenv', '__secure_getenv'] endforeach foreach ident : [ - ['memfd_create', '''#define _GNU_SOURCE - #include <sys/mman.h>'''], - ['gettid', '''#include <sys/types.h>'''], - ['pivot_root', '''#include <stdlib.h>'''], # no known header declares pivot_root - ['name_to_handle_at', '''#define _GNU_SOURCE - #include <sys/types.h> + ['memfd_create', '''#include <sys/mman.h>'''], + ['gettid', '''#include <sys/types.h> + #include <unistd.h>'''], + ['pivot_root', '''#include <stdlib.h> + #include <unistd.h>'''], # no known header declares pivot_root + ['name_to_handle_at', '''#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>'''], - ['setns', '''#define _GNU_SOURCE - #include <sched.h>'''], - ['renameat2', '''#include <stdio.h>'''], + ['setns', '''#include <sched.h>'''], + ['renameat2', '''#include <stdio.h> + #include <fcntl.h>'''], ['kcmp', '''#include <linux/kcmp.h>'''], ['keyctl', '''#include <sys/types.h> #include <keyutils.h>'''], @@ -474,11 +512,11 @@ foreach ident : [ ['explicit_bzero' , '''#include <string.h>'''], ] - have = cc.has_function(ident[0], prefix : ident[1]) + have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE') conf.set10('HAVE_' + ident[0].to_upper(), have) endforeach -if cc.has_function('getrandom', prefix : '''#include <sys/random.h>''') +if cc.has_function('getrandom', prefix : '''#include <sys/random.h>''', args : '-D_GNU_SOURCE') conf.set10('USE_SYS_RANDOM_H', true) conf.set10('HAVE_GETRANDOM', true) else @@ -494,6 +532,7 @@ awk = find_program('awk') m4 = find_program('m4') stat = find_program('stat') git = find_program('git', required : false) +env = find_program('env') meson_make_symlink = meson.source_root() + '/tools/meson-make-symlink.sh' mkdir_p = 'mkdir -p $DESTDIR/@0@' @@ -502,8 +541,7 @@ splash_bmp = files('test/splash.bmp') # if -Dxxx-path option is found, use that. Otherwise, check in $PATH, # /usr/sbin, /sbin, and fall back to the default from middle column. -progs = [['telinit', '/lib/sysvinit/telinit'], - ['quotaon', '/usr/sbin/quotaon' ], +progs = [['quotaon', '/usr/sbin/quotaon' ], ['quotacheck', '/usr/sbin/quotacheck' ], ['kill', '/usr/bin/kill' ], ['kmod', '/usr/bin/kmod' ], @@ -530,6 +568,8 @@ foreach prog : progs substs.set(name, path) endforeach +conf.set_quoted('TELINIT', get_option('telinit-path')) + if run_command('ln', '--relative', '--help').returncode() != 0 error('ln does not support --relative') endif @@ -565,7 +605,8 @@ conf.set('GPERF_LEN_TYPE', gperf_len_type, if not cc.has_header('sys/capability.h') error('POSIX caps headers not found') endif -foreach header : ['linux/btrfs.h', +foreach header : ['crypt.h', + 'linux/btrfs.h', 'linux/memfd.h', 'linux/vm_sockets.h', 'sys/auxv.h', @@ -763,10 +804,11 @@ if not libcap.found() endif libmount = dependency('mount', - version : '>= 2.30') + version : '>= 2.30', + required : not fuzzer_build) want_seccomp = get_option('seccomp') -if want_seccomp != 'false' +if want_seccomp != 'false' and not fuzzer_build libseccomp = dependency('libseccomp', version : '>= 2.3.1', required : want_seccomp == 'true') @@ -779,7 +821,7 @@ conf.set10('HAVE_SECCOMP', have) m4_defines += have ? ['-DHAVE_SECCOMP'] : [] want_selinux = get_option('selinux') -if want_selinux != 'false' +if want_selinux != 'false' and not fuzzer_build libselinux = dependency('libselinux', version : '>= 2.1.9', required : want_selinux == 'true') @@ -792,7 +834,7 @@ conf.set10('HAVE_SELINUX', have) m4_defines += have ? ['-DHAVE_SELINUX'] : [] want_apparmor = get_option('apparmor') -if want_apparmor != 'false' +if want_apparmor != 'false' and not fuzzer_build libapparmor = dependency('libapparmor', required : want_apparmor == 'true') have = libapparmor.found() @@ -812,7 +854,7 @@ endif want_polkit = get_option('polkit') install_polkit = false install_polkit_pkla = false -if want_polkit != 'false' +if want_polkit != 'false' and not fuzzer_build install_polkit = true libpolkit = dependency('polkit-gobject-1', @@ -825,7 +867,7 @@ endif conf.set10('ENABLE_POLKIT', install_polkit) want_acl = get_option('acl') -if want_acl != 'false' +if want_acl != 'false' and not fuzzer_build libacl = cc.find_library('acl', required : want_acl == 'true') have = libacl.found() else @@ -836,7 +878,7 @@ conf.set10('HAVE_ACL', have) m4_defines += have ? ['-DHAVE_ACL'] : [] want_audit = get_option('audit') -if want_audit != 'false' +if want_audit != 'false' and not fuzzer_build libaudit = dependency('audit', required : want_audit == 'true') have = libaudit.found() else @@ -846,7 +888,7 @@ endif conf.set10('HAVE_AUDIT', have) want_blkid = get_option('blkid') -if want_blkid != 'false' +if want_blkid != 'false' and not fuzzer_build libblkid = dependency('blkid', required : want_blkid == 'true') have = libblkid.found() else @@ -856,7 +898,7 @@ endif conf.set10('HAVE_BLKID', have) want_kmod = get_option('kmod') -if want_kmod != 'false' +if want_kmod != 'false' and not fuzzer_build libkmod = dependency('libkmod', version : '>= 15', required : want_kmod == 'true') @@ -868,7 +910,7 @@ endif conf.set10('HAVE_KMOD', have) want_pam = get_option('pam') -if want_pam != 'false' +if want_pam != 'false' and not fuzzer_build libpam = cc.find_library('pam', required : want_pam == 'true') libpam_misc = cc.find_library('pam_misc', required : want_pam == 'true') have = libpam.found() and libpam_misc.found() @@ -881,7 +923,7 @@ conf.set10('HAVE_PAM', have) m4_defines += have ? ['-DHAVE_PAM'] : [] want_microhttpd = get_option('microhttpd') -if want_microhttpd != 'false' +if want_microhttpd != 'false' and not fuzzer_build libmicrohttpd = dependency('libmicrohttpd', version : '>= 0.9.33', required : want_microhttpd == 'true') @@ -894,7 +936,7 @@ conf.set10('HAVE_MICROHTTPD', have) m4_defines += have ? ['-DHAVE_MICROHTTPD'] : [] want_libcryptsetup = get_option('libcryptsetup') -if want_libcryptsetup != 'false' +if want_libcryptsetup != 'false' and not fuzzer_build libcryptsetup = dependency('libcryptsetup', version : '>= 1.6.0', required : want_libcryptsetup == 'true') @@ -906,7 +948,7 @@ endif conf.set10('HAVE_LIBCRYPTSETUP', have) want_libcurl = get_option('libcurl') -if want_libcurl != 'false' +if want_libcurl != 'false' and not fuzzer_build libcurl = dependency('libcurl', version : '>= 7.32.0', required : want_libcurl == 'true') @@ -924,7 +966,7 @@ if want_libidn == 'true' and want_libidn2 == 'true' error('libidn and libidn2 cannot be requested simultaneously') endif -if want_libidn != 'false' and want_libidn2 != 'true' +if want_libidn != 'false' and want_libidn2 != 'true' and not fuzzer_build libidn = dependency('libidn', required : want_libidn == 'true') have = libidn.found() @@ -934,7 +976,7 @@ else endif conf.set10('HAVE_LIBIDN', have) m4_defines += have ? ['-DHAVE_LIBIDN'] : [] -if not have and want_libidn2 != 'false' +if not have and want_libidn2 != 'false' and not fuzzer_build # libidn is used for both libidn and libidn2 objects libidn = dependency('libidn2', required : want_libidn2 == 'true') @@ -946,7 +988,7 @@ conf.set10('HAVE_LIBIDN2', have) m4_defines += have ? ['-DHAVE_LIBIDN2'] : [] want_libiptc = get_option('libiptc') -if want_libiptc != 'false' +if want_libiptc != 'false' and not fuzzer_build libiptc = dependency('libiptc', required : want_libiptc == 'true') have = libiptc.found() @@ -958,7 +1000,7 @@ conf.set10('HAVE_LIBIPTC', have) m4_defines += have ? ['-DHAVE_LIBIPTC'] : [] want_qrencode = get_option('qrencode') -if want_qrencode != 'false' +if want_qrencode != 'false' and not fuzzer_build libqrencode = dependency('libqrencode', required : want_qrencode == 'true') have = libqrencode.found() @@ -969,7 +1011,7 @@ endif conf.set10('HAVE_QRENCODE', have) want_gcrypt = get_option('gcrypt') -if want_gcrypt != 'false' +if want_gcrypt != 'false' and not fuzzer_build libgcrypt = cc.find_library('gcrypt', required : want_gcrypt == 'true') libgpg_error = cc.find_library('gpg-error', required : want_gcrypt == 'true') have = libgcrypt.found() and libgpg_error.found() @@ -984,7 +1026,7 @@ endif conf.set10('HAVE_GCRYPT', have) want_gnutls = get_option('gnutls') -if want_gnutls != 'false' +if want_gnutls != 'false' and not fuzzer_build libgnutls = dependency('gnutls', version : '>= 3.1.4', required : want_gnutls == 'true') @@ -996,7 +1038,7 @@ endif conf.set10('HAVE_GNUTLS', have) want_elfutils = get_option('elfutils') -if want_elfutils != 'false' +if want_elfutils != 'false' and not fuzzer_build libdw = dependency('libdw', required : want_elfutils == 'true') have = libdw.found() @@ -1007,7 +1049,7 @@ endif conf.set10('HAVE_ELFUTILS', have) want_zlib = get_option('zlib') -if want_zlib != 'false' +if want_zlib != 'false' and not fuzzer_build libz = dependency('zlib', required : want_zlib == 'true') have = libz.found() @@ -1018,7 +1060,7 @@ endif conf.set10('HAVE_ZLIB', have) want_bzip2 = get_option('bzip2') -if want_bzip2 != 'false' +if want_bzip2 != 'false' and not fuzzer_build libbzip2 = cc.find_library('bz2', required : want_bzip2 == 'true') have = libbzip2.found() @@ -1029,7 +1071,7 @@ endif conf.set10('HAVE_BZIP2', have) want_xz = get_option('xz') -if want_xz != 'false' +if want_xz != 'false' and not fuzzer_build libxz = dependency('liblzma', required : want_xz == 'true') have = libxz.found() @@ -1040,7 +1082,7 @@ endif conf.set10('HAVE_XZ', have) want_lz4 = get_option('lz4') -if want_lz4 != 'false' +if want_lz4 != 'false' and not fuzzer_build liblz4 = dependency('liblz4', required : want_lz4 == 'true') have = liblz4.found() @@ -1051,7 +1093,7 @@ endif conf.set10('HAVE_LZ4', have) want_xkbcommon = get_option('xkbcommon') -if want_xkbcommon != 'false' +if want_xkbcommon != 'false' and not fuzzer_build libxkbcommon = dependency('xkbcommon', version : '>= 0.3.0', required : want_xkbcommon == 'true') @@ -1062,8 +1104,19 @@ else endif conf.set10('HAVE_XKBCOMMON', have) +want_pcre2 = get_option('pcre2') +if want_pcre2 != 'false' + libpcre2 = dependency('libpcre2-8', + required : want_pcre2 == 'true') + have = libpcre2.found() +else + have = false + libpcre2 = [] +endif +conf.set10('HAVE_PCRE2', have) + want_glib = get_option('glib') -if want_glib != 'false' +if want_glib != 'false' and not fuzzer_build libglib = dependency('glib-2.0', version : '>= 2.22.0', required : want_glib == 'true') @@ -1082,7 +1135,7 @@ endif conf.set10('HAVE_GLIB', have) want_dbus = get_option('dbus') -if want_dbus != 'false' +if want_dbus != 'false' and not fuzzer_build libdbus = dependency('dbus-1', version : '>= 1.3.2', required : want_dbus == 'true') @@ -1094,6 +1147,9 @@ endif conf.set10('HAVE_DBUS', have) default_dnssec = get_option('default-dnssec') +if fuzzer_build + default_dnssec = 'no' +endif if default_dnssec != 'no' and conf.get('HAVE_GCRYPT') == 0 message('default-dnssec cannot be set to yes or allow-downgrade when gcrypt is disabled. Setting default-dnssec to no.') default_dnssec = 'no' @@ -1173,9 +1229,11 @@ endforeach want_tests = get_option('tests') install_tests = get_option('install-tests') +slow_tests = get_option('slow-tests') tests = [] +fuzzers = [] -conf.set10('SYSTEMD_SLOW_TESTS_DEFAULT', get_option('slow-tests')) +conf.set10('SYSTEMD_SLOW_TESTS_DEFAULT', slow_tests) ##################################################################### @@ -1231,14 +1289,10 @@ includes = include_directories('src/basic', 'src/libsystemd/sd-netlink', 'src/libsystemd/sd-network', 'src/libsystemd-network', - '.', - ) + '.') add_project_arguments('-include', 'config.h', language : 'c') -gcrypt_util_sources = files('src/shared/gcrypt-util.h', - 'src/shared/gcrypt-util.c') - subdir('po') subdir('catalog') subdir('src/systemd') @@ -1258,15 +1312,16 @@ libjournal_core = static_library( libsystemd_sym_path = '@0@/@1@'.format(meson.current_source_dir(), libsystemd_sym) libsystemd = shared_library( 'systemd', - libsystemd_internal_sources, - journal_internal_sources, + 'src/systemd/sd-id128.h', # pick a header file at random to work around old meson bug version : libsystemd_version, include_directories : includes, link_args : ['-shared', '-Wl,--version-script=' + libsystemd_sym_path], - link_with : [libbasic], + link_with : [libbasic, + libbasic_gcrypt], + link_whole : [libsystemd_static, + libjournal_client], dependencies : [threads, - libgcrypt, librt, libxz, liblz4], @@ -1302,6 +1357,7 @@ subdir('src/vconsole') subdir('src/boot/efi') subdir('src/test') +subdir('src/fuzz') subdir('rules') subdir('test') @@ -1338,7 +1394,7 @@ foreach tuple : [['myhostname', 'ENABLE_MYHOSTNAME'], '-shared', '-Wl,--version-script=' + version_script_arg, '-Wl,--undefined'], - link_with : [libsystemd_internal, + link_with : [libsystemd_static, libbasic], dependencies : [threads, librt], @@ -1420,7 +1476,8 @@ exe = executable('journalctl', dependencies : [threads, libqrencode, libxz, - liblz4], + liblz4, + libpcre2], install_rpath : rootlibexecdir, install : true, install_dir : rootbindir) @@ -1507,11 +1564,11 @@ endif if conf.get('ENABLE_RESOLVE') == 1 executable('systemd-resolved', systemd_resolved_sources, - gcrypt_util_sources, include_directories : includes, - link_with : [libshared], + link_with : [libshared, + libbasic_gcrypt, + libsystemd_resolve_core], dependencies : [threads, - libgcrypt, libgpg_error, libm, libidn], @@ -1521,11 +1578,11 @@ if conf.get('ENABLE_RESOLVE') == 1 exe = executable('systemd-resolve', systemd_resolve_sources, - gcrypt_util_sources, include_directories : includes, - link_with : [libshared], + link_with : [libshared, + libbasic_gcrypt, + libsystemd_resolve_core], dependencies : [threads, - libgcrypt, libgpg_error, libm, libidn], @@ -1576,7 +1633,7 @@ if conf.get('ENABLE_LOGIND') == 1 include_directories : includes, link_args : ['-shared', '-Wl,--version-script=' + version_script_arg], - link_with : [libsystemd_internal, + link_with : [libsystemd_static, libshared_static], dependencies : [threads, libpam, @@ -2229,7 +2286,7 @@ if conf.get('ENABLE_HWDB') == 1 'src/hwdb/hwdb.c', 'src/libsystemd/sd-hwdb/hwdb-internal.h', include_directories : includes, - link_with : [libudev_internal], + link_with : [libudev_static], install_rpath : udev_rpath, install : true, install_dir : rootbindir) @@ -2262,7 +2319,7 @@ exe = executable('systemd-udevd', c_args : ['-DLOG_REALM=LOG_REALM_UDEV'], link_with : [libudev_core, libsystemd_network, - libudev_internal], + libudev_static], dependencies : [threads, libkmod, libidn, @@ -2275,10 +2332,11 @@ public_programs += [exe] exe = executable('udevadm', udevadm_sources, + c_args : ['-DLOG_REALM=LOG_REALM_UDEV'], include_directories : includes, link_with : [libudev_core, libsystemd_network, - libudev_internal], + libudev_static], dependencies : [threads, libkmod, libidn, @@ -2352,7 +2410,7 @@ if conf.get('ENABLE_NETWORKD') == 1 include_directories : includes, link_with : [libnetworkd_core, libsystemd_network, - libudev_internal, + libudev_static, libshared], dependencies : [threads], install_rpath : rootlibexecdir, @@ -2404,8 +2462,9 @@ foreach tuple : tests timeout = type.split('=')[1].to_int() type = '' endif - - if condition == '' or conf.get(condition) == 1 + if want_tests == 'false' + message('Not compiling @0@ because tests is set to false'.format(name)) + elif condition == '' or conf.get(condition) == 1 exe = executable( name, sources, @@ -2454,6 +2513,39 @@ test('test-libudev-sym', ############################################################ +fuzzer_exes = [] + +foreach tuple : fuzzers + sources = tuple[0] + link_with = tuple[1].length() > 0 ? tuple[1] : [libshared] + dependencies = tuple[2] + defs = tuple.length() >= 4 ? tuple[3] : [] + incs = tuple.length() >= 5 ? tuple[4] : includes + + if fuzzer_build + dependencies += fuzzing_engine + else + sources += 'src/fuzz/fuzz-main.c' + endif + + name = sources[0].split('/')[-1].split('.')[0] + + fuzzer_exes += executable( + name, + sources, + include_directories : [incs, include_directories('src/fuzz')], + link_with : link_with, + dependencies : dependencies, + c_args : defs, + install : false) +endforeach + +run_target('fuzzers', + depends : fuzzer_exes, + command : ['true']) + +############################################################ + make_directive_index_py = find_program('tools/make-directive-index.py') make_man_index_py = find_program('tools/make-man-index.py') xml_helper_py = find_program('tools/xml_helper.py') @@ -2489,6 +2581,8 @@ install_data('README', 'ENVIRONMENT.md', 'LICENSE.GPL2', 'LICENSE.LGPL2.1', + 'TRANSIENT-SETTINGS.md', + 'UIDS-GIDS.md', 'src/libsystemd/sd-bus/GVARIANT-SERIALIZATION', install_dir : docdir) @@ -2508,6 +2602,50 @@ endforeach ############################################################ +prev = '' +foreach p : fuzz_regression_tests + a = p.split('/')[-3] + b = p.split('/')[-2] + c = p.split('/')[-1] + + if a == 'address' + build = sanitize_address + else + error('unknown sanitizer @0@'.format(a)) + endif + + name = '@1@:@0@'.format(a, b) + + if name != prev + if want_tests == 'false' + message('Not compiling @0@ because tests is set to false'.format(name)) + elif not sanitizers.contains(a) + message('Not compiling @0@ because @1@ sanitizer is not available'.format(name, a)) + elif slow_tests + exe = custom_target( + name, + output : name, + depends : build, + command : [env, 'ln', '-fs', + join_paths(build.full_path(), b), + '@OUTPUT@'], + build_by_default : true) + else + message('Not compiling @0@ because slow-tests is set to false'.format(name)) + endif + endif + prev = name + + if want_tests != 'false' and slow_tests + test(c, env, args : [exe.full_path(), + join_paths(meson.source_root(), + 'test/fuzz-regressions', + p)]) + endif +endforeach + +############################################################ + if git.found() all_files = run_command( git, @@ -2519,11 +2657,11 @@ if git.found() custom_target( 'tags', output : 'tags', - command : ['env', 'etags', '-o', '@0@/TAGS'.format(meson.current_source_dir())] + all_files) + command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.current_source_dir())] + all_files) custom_target( 'ctags', output : 'ctags', - command : ['env', 'ctags', '-o', '@0@/tags'.format(meson.current_source_dir())] + all_files) + command : [env, 'ctags', '-o', '@0@/tags'.format(meson.current_source_dir())] + all_files) endif if git.found() @@ -2554,6 +2692,14 @@ endif ############################################################ +meson_check_api_docs_sh = find_program('tools/meson-check-api-docs.sh') +run_target( + 'check-api-docs', + depends : [man, libsystemd, libudev], + command : [meson_check_api_docs_sh, libsystemd.full_path(), libudev.full_path()]) + +############################################################ + status = [ '@0@ @1@'.format(meson.project_name(), meson.project_version()), @@ -2683,6 +2829,7 @@ foreach tuple : [ ['gnu-efi', have_gnu_efi], ['kmod'], ['xkbcommon'], + ['pcre2'], ['blkid'], ['dbus'], ['glib'], diff --git a/meson_options.txt b/meson_options.txt index f0c0506ff1..39822d6cdc 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -29,7 +29,8 @@ option('sysvinit-path', type : 'string', value : '/etc/init.d', description : 'the directory where the SysV init scripts are located') option('sysvrcnd-path', type : 'string', value : '/etc/rc.d', description : 'the base directory for SysV rcN.d directories') -option('telinit-path', type : 'string', description : 'path to telinit') +option('telinit-path', type : 'string', value : '/lib/sysvinit/telinit', + description : 'path to telinit') option('rc-local', type : 'string', value : '/etc/rc.local') option('halt-local', type : 'string', @@ -259,6 +260,8 @@ option('lz4', type : 'combo', choices : ['auto', 'true', 'false'], description : 'lz4 compression support') option('xkbcommon', type : 'combo', choices : ['auto', 'true', 'false'], description : 'xkbcommon keymap support') +option('pcre2', type : 'combo', choices : ['auto', 'true', 'false'], + description : 'regexp matching support using pcre2') option('glib', type : 'combo', choices : ['auto', 'true', 'false'], description : 'libglib support (for tests only)') option('dbus', type : 'combo', choices : ['auto', 'true', 'false'], @@ -284,9 +287,14 @@ option('bashcompletiondir', type : 'string', option('zshcompletiondir', type : 'string', description : 'directory for zsh completion scripts ["no" disables]') -option('tests', type : 'combo', choices : ['true', 'unsafe'], +option('tests', type : 'combo', choices : ['true', 'unsafe', 'false'], description : 'enable extra tests with =unsafe') option('slow-tests', type : 'boolean', value : 'false', description : 'run the slow tests by default') option('install-tests', type : 'boolean', value : 'false', description : 'install test executables') + +option('oss-fuzz', type : 'boolean', value : 'false', + description : 'build against oss-fuzz') +option('llvm-fuzz', type : 'boolean', value : 'false', + description : 'build against LLVM libFuzzer') diff --git a/mkosi.build b/mkosi.build index 0781f0d9c4..38cfe25025 100755 --- a/mkosi.build +++ b/mkosi.build @@ -1,4 +1,5 @@ -#!/bin/sh -ex +#!/bin/sh +set -ex # This file is part of systemd. # @@ -73,7 +73,7 @@ msgstr "Pro nastavení lokálního názvu stroje je vyžadováno ověření." #: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3 msgid "Set static host name" -msgstr "Nastavit statický název stoje" +msgstr "Nastavit statický název stroje" #: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4 msgid "" diff --git a/rules/50-udev-default.rules.in b/rules/50-udev-default.rules.in index 71e716913c..191f56f42e 100644 --- a/rules/50-udev-default.rules.in +++ b/rules/50-udev-default.rules.in @@ -78,7 +78,8 @@ KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun" KERNEL=="fuse", MODE="0666", OPTIONS+="static_node=fuse" -KERNEL=="kvm", GROUP="kvm", MODE="@DEV_KVM_MODE@" +# The static_node is required on s390x and ppc (they are using MODULE_ALIAS) +KERNEL=="kvm", GROUP="kvm", MODE="@DEV_KVM_MODE@", OPTIONS+="static_node=kvm" SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK += "ptp_kvm" diff --git a/scripts/coverity.sh b/scripts/coverity.sh new file mode 100755 index 0000000000..3e8d874728 --- /dev/null +++ b/scripts/coverity.sh @@ -0,0 +1,224 @@ +#!/bin/env bash + +# Declare build command +COVERITY_SCAN_BUILD_COMMAND="ninja -C cov-build" + +# Environment check +# Use default values if not set +SCAN_URL=${SCAN_URL:="https://scan.coverity.com"} +TOOL_BASE=${TOOL_BASE:="/tmp/coverity-scan-analysis"} +UPLOAD_URL=${UPLOAD_URL:="https://scan.coverity.com/builds"} + +# These must be set by environment +echo -e "\033[33;1mNote: COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN are available on Project Settings page on scan.coverity.com\033[0m" +[ -z "$COVERITY_SCAN_PROJECT_NAME" ] && echo "ERROR: COVERITY_SCAN_PROJECT_NAME must be set" && exit 1 +[ -z "$COVERITY_SCAN_NOTIFICATION_EMAIL" ] && echo "ERROR: COVERITY_SCAN_NOTIFICATION_EMAIL must be set" && exit 1 +[ -z "$COVERITY_SCAN_BRANCH_PATTERN" ] && echo "ERROR: COVERITY_SCAN_BRANCH_PATTERN must be set" && exit 1 +[ -z "$COVERITY_SCAN_BUILD_COMMAND" ] && echo "ERROR: COVERITY_SCAN_BUILD_COMMAND must be set" && exit 1 +[ -z "$COVERITY_SCAN_TOKEN" ] && echo "ERROR: COVERITY_SCAN_TOKEN must be set" && exit 1 + +# Do not run on pull requests +if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then + echo -e "\033[33;1mINFO: Skipping Coverity Analysis: branch is a pull request.\033[0m" + exit 0 +fi + +# Verify this branch should run +if [[ "${TRAVIS_BRANCH^^}" =~ "${COVERITY_SCAN_BRANCH_PATTERN^^}" ]]; then + echo -e "\033[33;1mCoverity Scan configured to run on branch ${TRAVIS_BRANCH}\033[0m" +else + echo -e "\033[33;1mCoverity Scan NOT configured to run on branch ${TRAVIS_BRANCH}\033[0m" + exit 1 +fi + +# Verify upload is permitted +AUTH_RES=`curl -s --form project="$COVERITY_SCAN_PROJECT_NAME" --form token="$COVERITY_SCAN_TOKEN" $SCAN_URL/api/upload_permitted` +if [ "$AUTH_RES" = "Access denied" ]; then + echo -e "\033[33;1mCoverity Scan API access denied. Check COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN.\033[0m" + exit 1 +else + AUTH=`echo $AUTH_RES | python -c "import sys, json; print json.load(sys.stdin)['upload_permitted']"` + if [ "$AUTH" = "True" ]; then + echo -e "\033[33;1mCoverity Scan analysis authorized per quota.\033[0m" + else + WHEN=`echo $AUTH_RES | python -c "import sys; json; print json.load(sys.stdin)['next_upload_permitted_at']"` + echo -e "\033[33;1mCoverity Scan analysis NOT authorized until $WHEN.\033[0m" + exit 0 + fi +fi + +TOOL_DIR=`find $TOOL_BASE -type d -name 'cov-analysis*'` +export PATH="$TOOL_DIR/bin:$PATH" + +# Disable CCACHE for cov-build to compilation units correctly +export CCACHE_DISABLE=1 + +# FUNCTION DEFINITIONS +# -------------------- +_help() +{ + # displays help and exits + cat <<-EOF + USAGE: $0 [CMD] [OPTIONS] + + CMD + build Issue Coverity build + upload Upload coverity archive for analysis + Note: By default, archive is created from default results directory. + To provide custom archive or results directory, see --result-dir + and --tar options below. + + OPTIONS + -h,--help Display this menu and exits + + Applicable to build command + --------------------------- + -o,--out-dir Specify Coverity intermediate directory (defaults to 'cov-int') + -t,--tar bool, archive the output to .tgz file (defaults to false) + + Applicable to upload command + ---------------------------- + -d, --result-dir Specify result directory if different from default ('cov-int') + -t, --tar ARCHIVE Use custom .tgz archive instead of intermediate directory or pre-archived .tgz + (by default 'analysis-result.tgz' + EOF + return; +} + +_pack() +{ + RESULTS_ARCHIVE=${RESULTS_ARCHIVE:-'analysis-results.tgz'} + + echo -e "\033[33;1mTarring Coverity Scan Analysis results...\033[0m" + tar czf $RESULTS_ARCHIVE $RESULTS_DIR + SHA=`git rev-parse --short HEAD` + + PACKED=true +} + + +_build() +{ + echo -e "\033[33;1mRunning Coverity Scan Analysis Tool...\033[0m" + local _cov_build_options="" + #local _cov_build_options="--return-emit-failures 8 --parse-error-threshold 85" + eval "${COVERITY_SCAN_BUILD_COMMAND_PREPEND}" + COVERITY_UNSUPPORTED=1 cov-build --dir $RESULTS_DIR $_cov_build_options sh -c "$COVERITY_SCAN_BUILD_COMMAND" + cov-import-scm --dir $RESULTS_DIR --scm git --log $RESULTS_DIR/scm_log.txt + + if [ $? != 0 ]; then + echo -e "\033[33;1mCoverity Scan Build failed: $TEXT.\033[0m" + return 1 + fi + + [ -z $TAR ] || [ $TAR = false ] && return 0 + + if [ "$TAR" = true ]; then + _pack + fi +} + + +_upload() +{ + # pack results + [ -z $PACKED ] || [ $PACKED = false ] && _pack + + # Upload results + echo -e "\033[33;1mUploading Coverity Scan Analysis results...\033[0m" + response=$(curl \ + --silent --write-out "\n%{http_code}\n" \ + --form project=$COVERITY_SCAN_PROJECT_NAME \ + --form token=$COVERITY_SCAN_TOKEN \ + --form email=$COVERITY_SCAN_NOTIFICATION_EMAIL \ + --form file=@$RESULTS_ARCHIVE \ + --form version=$SHA \ + --form description="Travis CI build" \ + $UPLOAD_URL) + status_code=$(echo "$response" | sed -n '$p') + if [ "$status_code" != "201" ]; then + TEXT=$(echo "$response" | sed '$d') + echo -e "\033[33;1mCoverity Scan upload failed: $TEXT.\033[0m" + exit 1 + fi + + echo -e "\n\033[33;1mCoverity Scan Analysis completed succesfully.\033[0m" + exit 0 +} + +# PARSE COMMAND LINE OPTIONS +# -------------------------- + +case $1 in + -h|--help) + _help + exit 0 + ;; + build) + CMD='build' + TEMP=`getopt -o ho:t --long help,out-dir:,tar -n '$0' -- "$@"` + _ec=$? + [[ $_ec -gt 0 ]] && _help && exit $_ec + shift + ;; + upload) + CMD='upload' + TEMP=`getopt -o hd:t: --long help,result-dir:tar: -n '$0' -- "$@"` + _ec=$? + [[ $_ec -gt 0 ]] && _help && exit $_ec + shift + ;; + *) + _help && exit 1 ;; +esac + +RESULTS_DIR='cov-int' + +eval set -- "$TEMP" +if [ $? != 0 ] ; then exit 1 ; fi + +# extract options and their arguments into variables. +if [[ $CMD == 'build' ]]; then + TAR=false + while true ; do + case $1 in + -h|--help) + _help + exit 0 + ;; + -o|--out-dir) + RESULTS_DIR="$2" + shift 2 + ;; + -t|--tar) + TAR=true + shift + ;; + --) _build; shift ; break ;; + *) echo "Internal error" ; _help && exit 6 ;; + esac + done + +elif [[ $CMD == 'upload' ]]; then + while true ; do + case $1 in + -h|--help) + _help + exit 0 + ;; + -d|--result-dir) + CHANGE_DEFAULT_DIR=true + RESULTS_DIR="$2" + shift 2 + ;; + -t|--tar) + RESULTS_ARCHIVE="$2" + [ -z $CHANGE_DEFAULT_DIR ] || [ $CHANGE_DEFAULT_DIR = false ] && PACKED=true + shift 2 + ;; + --) _upload; shift ; break ;; + *) echo "Internal error" ; _help && exit 6 ;; + esac + done + +fi diff --git a/scripts/oss-fuzz.sh b/scripts/oss-fuzz.sh new file mode 100755 index 0000000000..2c4e58e29d --- /dev/null +++ b/scripts/oss-fuzz.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1+ +# +# Copyright 2017 Jonathan Rudenberg +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see <http://www.gnu.org/licenses/>. + +set -ex + +export LC_CTYPE=C.UTF-8 + +SANITIZER=${SANITIZER:-address -fsanitize-address-use-after-scope} +flags="-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=$SANITIZER -fsanitize-coverage=trace-pc-guard,trace-cmp" + +export CFLAGS=${CFLAGS:-$flags} +export CXXFLAGS=${CXXFLAGS:-$flags} +export CC=${CC:-clang} +export CXX=${CXX:-clang++} +export WORK=${WORK:-$(pwd)} +export OUT=${OUT:-$(pwd)/out} +mkdir -p $OUT + +build=$WORK/build +rm -rf $build +mkdir -p $build + +fuzzflag="oss-fuzz=true" +if [ -z "$FUZZING_ENGINE" ]; then + fuzzflag="llvm-fuzz=true" +fi + +meson $build -D$fuzzflag -Db_lundef=false +ninja -C $build fuzzers + +for d in "$(dirname "$0")/../test/fuzz-corpus/"*; do + zip -jqr $OUT/fuzz-$(basename "$d")_seed_corpus.zip "$d" +done + +# get fuzz-dns-packet corpus +df=$build/dns-fuzzing +git clone --depth 1 https://github.com/CZ-NIC/dns-fuzzing $df +zip -jqr $OUT/fuzz-dns-packet_seed_corpus.zip $df/packet + +mkdir -p $OUT/src/shared +mv $build/src/shared/libsystemd-shared-*.so $OUT/src/shared + +find $build -maxdepth 1 -type f -executable -name "fuzz-*" -exec mv {} $OUT \; +cp src/fuzz/*.options $OUT diff --git a/shell-completion/bash/bootctl b/shell-completion/bash/bootctl index 34b1b552d9..9d7b51bcec 100644 --- a/shell-completion/bash/bootctl +++ b/shell-completion/bash/bootctl @@ -29,7 +29,8 @@ _bootctl() { local i verb comps local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local -A OPTS=( - [STANDALONE]='-h --help --version' + [STANDALONE]='-h --help --no-variables -p --print-path --version' + [ARG]='--path' ) if [[ "$cur" = -* ]]; then @@ -38,7 +39,7 @@ _bootctl() { fi local -A VERBS=( - [STANDALONE]='status' + [STANDALONE]='help install list remove status update' ) for ((i=0; i < COMP_CWORD; i++)); do diff --git a/shell-completion/bash/busctl b/shell-completion/bash/busctl index aa4c1d74d9..d077675a32 100644 --- a/shell-completion/bash/busctl +++ b/shell-completion/bash/busctl @@ -78,9 +78,10 @@ _busctl() { local -A OPTS=( [STANDALONE]='-h --help --version --no-pager --no-legend --system --user --show-machine --unique --acquired --activatable --list - --quiet --verbose --expect-reply=no --auto-start=no - --allow-interactive-authorization=yes --augment-creds=no' - [ARG]='-H --host -M --machine --address --match --timeout' + -q --quiet --verbose --expect-reply=no --auto-start=no + --allow-interactive-authorization=no --augment-creds=no + --watch-bind=yes' + [ARG]='--address -H --host -M --machine --match --timeout --size' ) if __contains_word "--user" ${COMP_WORDS[*]}; then diff --git a/shell-completion/bash/coredumpctl b/shell-completion/bash/coredumpctl index 842e4943ff..bc069a7644 100644 --- a/shell-completion/bash/coredumpctl +++ b/shell-completion/bash/coredumpctl @@ -39,22 +39,25 @@ _coredumpctl() { local i verb comps local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local OPTS='-h --help --version --no-pager --no-legend -o --output -F --field -1 - -r --reverse -S --since -U --until' + -r --reverse -S --since -U --until -D --directory -q --quiet' local -A VERBS=( - [LIST]='list' + [LIST]='list info' [DUMP]='dump gdb' ) if __contains_word "$prev" '--output -o'; then comps=$( compgen -A file -- "$cur" ) compopt -o filenames - elif __contains_word "$prev" '--FIELD -F'; then + elif __contains_word "$prev" '-D --directory'; then + comps=$( compgen -A directory -- "$cur" ) + compopt -o filenames + elif __contains_word "$prev" '--field -F'; then comps=$( compgen -W '${__journal_fields[*]}' -- "$cur" ) elif [[ $cur = -* ]]; then comps=${OPTS} elif __contains_word "$prev" ${VERBS[*]} && - ! __contains_word ${COMP_WORDS[COMP_CWORD-2]} '--output -o -F --field'; then + ! __contains_word ${COMP_WORDS[COMP_CWORD-2]} '--output -o -D --directory -F --field'; then compopt -o nospace COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") ) return 0 diff --git a/shell-completion/bash/hostnamectl b/shell-completion/bash/hostnamectl index a35ac7f9a0..1b41603010 100644 --- a/shell-completion/bash/hostnamectl +++ b/shell-completion/bash/hostnamectl @@ -29,7 +29,7 @@ _hostnamectl() { local i verb comps local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local OPTS='-h --help --version --transient --static --pretty - --no-ask-password -H --host --machine' + --no-ask-password -H --host -M --machine' if [[ $cur = -* ]]; then COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl index 03ee733d7e..d2b9a04706 100644 --- a/shell-completion/bash/journalctl +++ b/shell-completion/bash/journalctl @@ -39,25 +39,25 @@ _journalctl() { [STANDALONE]='-a --all --full --system --user --disk-usage -f --follow --header -h --help -l --local --new-id128 -m --merge --no-pager - --no-tail -q --quiet --setup-keys --this-boot --verify + --no-tail -q --quiet --setup-keys --verify --version --list-catalog --update-catalog --list-boots --show-cursor --dmesg -k --pager-end -e -r --reverse --utc -x --catalog --no-full --force --dump-catalog - --flush --rotate --sync --no-hostname' - [ARG]='-b --boot --this-boot -D --directory --file -F --field + --flush --rotate --sync --no-hostname -N --fields' + [ARG]='-b --boot -D --directory --file -F --field -t --identifier -M --machine -o --output -u --unit --user-unit -p --priority - --vacuum-size --vacuum-time --vacuum-files' - [ARGUNKNOWN]='-c --cursor --interval -n --lines -S --since -U --until - --after-cursor --verify-key -t --identifier --root' + [ARGUNKNOWN]='-c --cursor --interval -n --lines -S --since -U --until + --after-cursor --verify-key + --vacuum-size --vacuum-time --vacuum-files --output-fields' ) if __contains_word "$prev" ${OPTS[ARG]} ${OPTS[ARGUNKNOWN]}; then case $prev in - --boot|--this-boot|-b) + --boot|-b) comps=$(journalctl -F '_BOOT_ID' 2>/dev/null) ;; - --directory|-D) + --directory|-D|--root) comps=$(compgen -d -- "$cur") compopt -o filenames ;; @@ -66,7 +66,7 @@ _journalctl() { compopt -o filenames ;; --output|-o) - comps='short short-full short-iso short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat' + comps='short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat' ;; --field|-F) comps=$(journalctl --fields | sort 2>/dev/null) diff --git a/shell-completion/bash/kernel-install b/shell-completion/bash/kernel-install index 5a78528d36..f291d3e63a 100644 --- a/shell-completion/bash/kernel-install +++ b/shell-completion/bash/kernel-install @@ -38,7 +38,7 @@ _kernel_install() { fi ;; 3) - [[ "$cur" ]] || cur=/boot/vmlinuz-${COMP_WORDS[2]} + [[ "$cur" ]] || cur=/lib/modules/${COMP_WORDS[2]}/vmlinuz comps=$(compgen -f -- "$cur") compopt -o filenames ;; diff --git a/shell-completion/bash/localectl b/shell-completion/bash/localectl index 97c91a4ce2..f02476f733 100644 --- a/shell-completion/bash/localectl +++ b/shell-completion/bash/localectl @@ -35,7 +35,7 @@ _localectl() { local i verb comps locale_vals local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local OPTS='-h --help --version --no-convert --no-pager --no-ask-password - -H --host --machine' + -H --host -M --machine' if __contains_word "$prev" $OPTS; then case $prev in @@ -53,10 +53,11 @@ _localectl() { fi local -A VERBS=( - [STANDALONE]='status list-locales list-keymaps' - [LOCALES]='set-locale' - [KEYMAPS]='set-keymap' - [X11]='set-x11-keymap' + [STANDALONE]='status list-locales list-keymaps list-x11-keymap-models list-x11-keymap-layouts list-x11-keymap-options' + [VARIANTS]='list-x11-keymap-variants' + [LOCALES]='set-locale' + [KEYMAPS]='set-keymap' + [X11]='set-x11-keymap' ) for ((i=0; i < COMP_CWORD; i++)); do @@ -68,6 +69,8 @@ _localectl() { if [[ -z $verb ]]; then comps=${VERBS[*]} + elif __contains_word "$verb" ${VERBS[VARIANTS]}; then + comps=$(command localectl list-x11-keymap-layouts) elif __contains_word "$verb" ${VERBS[LOCALES]}; then if [[ $cur = *=* ]]; then mapfile -t locale_vals < <(command localectl list-locales 2>/dev/null) diff --git a/shell-completion/bash/loginctl b/shell-completion/bash/loginctl index d8d14f889a..f78139b266 100644 --- a/shell-completion/bash/loginctl +++ b/shell-completion/bash/loginctl @@ -34,10 +34,11 @@ _loginctl () { local i verb comps local -A OPTS=( - [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version - --no-legend --no-ask-password -l --full' - [ARG]='--host -H --kill-who --property -p --signal -s --machine' - ) + [STANDALONE]='--all -a --help -h --no-pager --version + --no-legend --no-ask-password -l --full --value' + [ARG]='--host -H --kill-who --property -p --signal -s -M --machine + -n --lines -o --output' + ) if __contains_word "$prev" ${OPTS[ARG]}; then case $prev in @@ -69,7 +70,7 @@ _loginctl () { [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session' [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user' [SEATS]='seat-status show-seat terminate-seat' - [STANDALONE]='list-sessions list-users list-seats flush-devices' + [STANDALONE]='list-sessions lock-sessions unlock-sessions list-users list-seats flush-devices' [ATTACH]='attach' ) diff --git a/shell-completion/bash/machinectl b/shell-completion/bash/machinectl index 7865a99882..30cf9448e5 100644 --- a/shell-completion/bash/machinectl +++ b/shell-completion/bash/machinectl @@ -36,13 +36,17 @@ _machinectl() { local i verb comps local -A OPTS=( - [STANDALONE]='--all -a --full --help -h --no-ask-password --no-legend --no-pager --version' - [ARG]='--host -H --kill-who -M --machine --property -p --signal -s' + [STANDALONE]='--all -a -l --full --help -h --no-ask-password --no-legend --no-pager --version --value + --mkdir --read-only --force -q --quiet' + [ARG]='--host -H --kill-who -M --machine --property -p --signal -s --uid -E --setenv -n --lines + -o --output --verify --format --max-addresses' ) local -A VERBS=( - [STANDALONE]='list list-images pull-tar pull-raw import-tar import-raw export-tar export-raw list-transfers cancel-transfer' - [MACHINES]='status show start stop login shell enable disable poweroff reboot terminate kill copy-to copy-from image-status show-image clone rename read-only remove set-limit' + [STANDALONE]='list list-images clean pull-tar pull-raw list-transfers cancel-transfer' + [MACHINES]='status show start stop login shell enable disable poweroff reboot terminate kill bind copy-to copy-from + image-status show-image clone rename read-only remove set-limit export-tar export-raw' + [FILE]='import-tar import-raw' ) _init_completion || return @@ -73,6 +77,9 @@ _machinectl() { --property|-p) comps='' ;; + --output|-o) + comps='short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat' + ;; esac COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) return 0 @@ -91,6 +98,10 @@ _machinectl() { elif __contains_word "$verb" ${VERBS[MACHINES]}; then comps=$( __get_machines ) + + elif __contains_word "$verb" ${VERBS[FILE]}; then + comps=$(compgen -f -- "cur") + compopt -o filenames fi COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) diff --git a/shell-completion/bash/networkctl b/shell-completion/bash/networkctl index 0c36aaf464..fb92c675d2 100644 --- a/shell-completion/bash/networkctl +++ b/shell-completion/bash/networkctl @@ -37,8 +37,8 @@ _networkctl() { ) local -A VERBS=( - [STANDALONE]='list lldp label' - [LINKS]='status' + [STANDALONE]='label' + [LINKS]='status list lldp' ) _init_completion || return diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in index 5a353f7107..080deeaace 100644 --- a/shell-completion/bash/systemctl.in +++ b/shell-completion/bash/systemctl.in @@ -126,10 +126,10 @@ _systemctl () { local -A OPTS=( [STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --now - --quiet -q --privileged -P --system --user --version --runtime --recursive -r --firmware-setup - --show-types -i --ignore-inhibitors --plain --failed' + --quiet -q --system --user --version --runtime --recursive -r --firmware-setup + --show-types -i --ignore-inhibitors --plain --failed --value --fail --dry-run --wait' [ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root - --preset-mode -n --lines -o --output -M --machine' + --preset-mode -n --lines -o --output -M --machine --message' ) if __contains_word "--user" ${COMP_WORDS[*]}; then @@ -203,14 +203,15 @@ _systemctl () { [TARGET_AND_UNITS]='add-wants add-requires' [MASKED_UNITS]='unmask' [JOBS]='cancel' - [ENVS]='set-environment unset-environment' + [ENVS]='set-environment unset-environment import-environment' [STANDALONE]='daemon-reexec daemon-reload default emergency exit halt hibernate hybrid-sleep kexec list-jobs list-sockets list-timers list-units list-unit-files poweroff reboot rescue show-environment suspend get-default - is-system-running' + is-system-running preset-all' [FILE]='link switch-root' [TARGETS]='set-default' + [MACHINES]='list-machines' ) for ((i=0; i < COMP_CWORD; i++)); do @@ -294,12 +295,13 @@ _systemctl () { elif __contains_word "$verb" ${VERBS[ENVS]}; then comps=$( __systemctl $mode show-environment \ - | while read -r line; do echo " ${line%%=*}=";done ) + | while read -r line; do echo " ${line%%=*}="; done ) compopt -o nospace elif __contains_word "$verb" ${VERBS[FILE]}; then comps=$( compgen -A file -- "$cur" ) compopt -o filenames + elif __contains_word "$verb" ${VERBS[TARGETS]}; then comps=$( __systemctl $mode list-unit-files --type target --full --all \ | { while read -r a b; do echo " $a"; done; } ) diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze index 45ff7a1f3e..fb30487613 100644 --- a/shell-completion/bash/systemd-analyze +++ b/shell-completion/bash/systemd-analyze @@ -36,18 +36,20 @@ _systemd_analyze() { local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local -A OPTS=( - [STANDALONE]='--help --version --system --user --order --require --no-pager --man' - [ARG]='-H --host -M --machine --fuzz --from-pattern --to-pattern ' + [STANDALONE]='-h --help --version --system --user --order --require --no-pager + --man=no --generators=yes' + [ARG]='-H --host -M --machine --fuzz --from-pattern --to-pattern' ) local -A VERBS=( - [STANDALONE]='time blame plot dump get-log-level get-log-target' + [STANDALONE]='time blame plot dump calendar' [CRITICAL_CHAIN]='critical-chain' [DOT]='dot' - [LOG_LEVEL]='set-log-level' - [LOG_TARGET]='set-log-target' + [LOG_LEVEL]='log-level' + [LOG_TARGET]='log-target' [VERIFY]='verify' [SECCOMP_FILTER]='syscall-filter' + [SERVICE_WATCHDOGS]='service-watchdogs' ) _init_completion || return @@ -117,12 +119,19 @@ _systemd_analyze() { elif __contains_word "$verb" ${VERBS[VERIFY]}; then if [[ $cur = -* ]]; then - comps='--help --version --system --user --man' + comps='--help --version --system --user --man=no --generators=yes' else comps=$( compgen -A file -- "$cur" ) compopt -o filenames fi + elif __contains_word "$verb" ${VERBS[SERVICE_WATCHDOGS]}; then + if [[ $cur = -* ]]; then + comps='--help --version --system --user' + else + comps='on off' + fi + fi COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) diff --git a/shell-completion/bash/systemd-cgls b/shell-completion/bash/systemd-cgls index 0f579a6e67..34c7b9e67f 100644 --- a/shell-completion/bash/systemd-cgls +++ b/shell-completion/bash/systemd-cgls @@ -30,13 +30,21 @@ __get_machines() { machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; }; } +__get_units_have_cgroup() { + systemctl $1 list-units | { + while read -r a b c d; do + [[ $c == "active" && ${a##*.} =~ (service|socket|mount|swap|slice|scope) ]] && echo " $a" + done + }; +} + _systemd_cgls() { local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local i verb comps local -A OPTS=( [STANDALONE]='-h --help --version --all -l --full -k --no-pager' - [ARG]='-M --machine' + [ARG]='-M --machine -u --unit --user-unit' ) _init_completion || return @@ -46,6 +54,12 @@ _systemd_cgls() { --machine|-M) comps=$( __get_machines ) ;; + --unit|-u) + comps=$( __get_units_have_cgroup --system ) + ;; + --user-unit) + comps=$( __get_units_have_cgroup --user ) + ;; esac COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) return 0 diff --git a/shell-completion/bash/systemd-detect-virt b/shell-completion/bash/systemd-detect-virt index 21dca2b966..5fab7cb12e 100644 --- a/shell-completion/bash/systemd-detect-virt +++ b/shell-completion/bash/systemd-detect-virt @@ -30,7 +30,8 @@ _systemd_detect_virt() { local i verb comps local -A OPTS=( - [STANDALONE]='-h --help --version -c --container -v --vm -q --quiet' + [STANDALONE]='-h --help --version -c --container -v --vm -q --quiet + --private-users' ) _init_completion || return diff --git a/shell-completion/bash/systemd-nspawn b/shell-completion/bash/systemd-nspawn index 4f2fbef84f..660972d9f1 100644 --- a/shell-completion/bash/systemd-nspawn +++ b/shell-completion/bash/systemd-nspawn @@ -57,12 +57,13 @@ _systemd_nspawn() { local i verb comps local -A OPTS=( - [STANDALONE]='-h --help --version --private-network -b --boot --read-only -q --quiet --share-system --keep-unit --network-veth -j' - [ARG]='-D --directory -u --user --uuid --capability --drop-capability --link-journal --bind --bind-ro -M --machine - -S --slice --setenv -Z --selinux-context -L --selinux-apifs-context --register --network-interface --network-bridge - --personality -i --image --tmpfs --volatile - --network-macvlan --kill-signal --template - --notify-ready' + [STANDALONE]='-h --help --version --private-network -b --boot --read-only -q --quiet --share-system --keep-unit -n --network-veth + -j -x --ephemeral -a --as-pid2 --private-users-chown -U' + [ARG]='-D --directory -u --user --uuid --capability --drop-capability --link-journal --bind --bind-ro -M --machine + -S --slice -E --setenv -Z --selinux-context -L --selinux-apifs-context --register --network-interface --network-bridge + --personality -i --image --tmpfs --volatile --network-macvlan --kill-signal --template --notify-ready --root-hash + --chdir --pivot-root --property --private-users --network-namespace-path --network-ipvlan --network-veth-extra + --network-zone -p --port --system-call-filter --overlay --overlay-ro --settings' ) _init_completion || return @@ -76,7 +77,7 @@ _systemd_nspawn() { --user|-u) comps=$( __get_users ) ;; - --uuid) + --uuid|--root-hash) comps='' ;; --capability) @@ -106,7 +107,7 @@ _systemd_nspawn() { --slice|-S) comps=$( __get_slices ) ;; - --setenv) + --setenv|-E) comps=$( __get_env ) ;; --selinux-context|-Z) @@ -143,7 +144,15 @@ _systemd_nspawn() { ;; --notify-ready) comps='yes no' - return + ;; + --private-users) + comps='yes no pick' + ;; + --network-namespace-path) + comps=$( compgen -A file -- "$cur" ) + ;; + --settings) + comps='yes no override trusted' ;; esac COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) diff --git a/shell-completion/bash/systemd-resolve b/shell-completion/bash/systemd-resolve index 3f789e80d0..ecd1ebad54 100644 --- a/shell-completion/bash/systemd-resolve +++ b/shell-completion/bash/systemd-resolve @@ -36,11 +36,13 @@ _systemd-resolve() { local i comps local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local -A OPTS=( - [STANDALONE]='-h --help --version -4 -6 + [STANDALONE]='-h --help --version --no-pager -4 -6 --service --openpgp --tlsa --status --statistics --reset-statistics --service-address=no --service-txt=no - --cname=no --search=no --legend=no' - [ARG]='-i --interface -p --protocol -t --type -c --class' + --cname=no --search=no --legend=no --flush-caches + --reset-server-features --revert' + [ARG]='-i --interface -p --protocol -t --type -c --class --raw + --set-dns --set-domain --set-llmnr --set-mdns --set-dnssec --set-nta' ) if __contains_word "$prev" ${OPTS[ARG]}; then @@ -51,6 +53,18 @@ _systemd-resolve() { --protocol|-p|--type|-t|--class|-c) comps=$( systemd-resolve --legend=no "$prev" help; echo help ) ;; + --raw) + comps="payload packet" + ;; + --set-dns|--set-domain|--set-nta) + comps="" + ;; + --set-llmnr|--set-mdns) + comps="yes no resolve" + ;; + --set-dnssec) + comps="yes no allow-downgrade" + ;; esac COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) return 0 diff --git a/shell-completion/bash/systemd-run b/shell-completion/bash/systemd-run index 125cd306f0..b9114fc1b5 100644 --- a/shell-completion/bash/systemd-run +++ b/shell-completion/bash/systemd-run @@ -36,15 +36,16 @@ _systemd_run() { local OPTS='-h --help --version --user --system --scope --unit --description --slice -r --remain-after-exit --send-sighup -H --host -M --machine --service-type --on-active --on-boot --on-startup --on-unit-active --on-unit-inactive - --on-calendar --timer-property -t --pty -q --quiet --no-block - --uid --gid --nice --setenv -p --property --no-ask-password - --wait' + --on-calendar --timer-property --path-property --socket-property -t --pty + -q --quiet --no-block --uid --gid --nice -E --setenv -p --property + --no-ask-password --wait -P --pipe -G --collect' local mode=--system local i local opts_with_values=( --unit --description --slice --service-type -H --host -M --machine -p --property --on-active --on-boot --on-startup --on-unit-active --on-unit-inactive --on-calendar --timer-property + --path-property --socket-property --uid --gid --nice -E --setenv ) for (( i=1; i <= COMP_CWORD; i++ )); do if [[ ${COMP_WORDS[i]} != -* ]]; then diff --git a/shell-completion/bash/timedatectl b/shell-completion/bash/timedatectl index b9d00811e3..13b99f22ba 100644 --- a/shell-completion/bash/timedatectl +++ b/shell-completion/bash/timedatectl @@ -25,16 +25,24 @@ __contains_word () { done } +__get_machines() { + local a b + machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; }; +} + _timedatectl() { local i verb comps local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local OPTS='-h --help --version --adjust-system-clock --no-pager - --no-ask-password -H --host --machine' + --no-ask-password -H --host -M --machine' if __contains_word "$prev" $OPTS; then case $prev in --host|-H) - comps='' + comps=$(compgen -A hostname) + ;; + --machine|-M) + comps=$( __get_machines ) ;; esac COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) @@ -48,7 +56,7 @@ _timedatectl() { local -A VERBS=( [BOOLEAN]='set-local-rtc set-ntp' - [STANDALONE]='status set-time list-timezones' + [STANDALONE]='status list-timezones' [TIMEZONES]='set-timezone' [TIME]='set-time' ) diff --git a/shell-completion/zsh/_coredumpctl b/shell-completion/zsh/_coredumpctl index ea8cfb2dec..f727820660 100644 --- a/shell-completion/zsh/_coredumpctl +++ b/shell-completion/zsh/_coredumpctl @@ -16,10 +16,9 @@ _coredumpctl_command(){ local -a _dumps cmd="${${_coredumpctl_cmds[(r)$words[1]:*]%%:*}}" if (( $#cmd )); then - # user can set zstyle ':completion:*:*:coredumpctl:*' sort no for coredumps to be ordered by date, otherwise they get ordered by pid - _dumps=( "${(foa)$(coredumpctl list --no-legend | awk 'BEGIN{OFS=":"} {sub(/[[ \t]+/, ""); print $5,$0}' 2>/dev/null)}" ) + _dumps=( "${(f)$(coredumpctl list --no-legend | awk 'BEGIN{OFS=":"} {sub(/[[ \t]+/, ""); print $4,$0}' 2>/dev/null)}" ) if [[ -n "$_dumps" ]]; then - _describe -t pids 'coredumps' _dumps + _describe -V -t pids 'coredumps' _dumps else _message "no coredumps" fi diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in index 47ec9970e1..a3df9a0457 100644 --- a/shell-completion/zsh/_systemctl.in +++ b/shell-completion/zsh/_systemctl.in @@ -140,20 +140,19 @@ _systemctl_get_template_names() { echo -E - ${^${(M)${(f)"$(__systemctl list-uni _systemctl_active_units() {_sys_active_units=( ${${(f)"$(__systemctl list-units "*$PREFIX*$SUFFIX*" )"}%% *} )} _systemctl_startable_units(){ - _sys_startable_units=( $( _filter_units_by_property ActiveState inactive $( - _filter_units_by_property CanStart yes $( - __systemctl $mode list-unit-files --state enabled,disabled,static "*$PREFIX*$SUFFIX*" | \ - { while read -r a b; do [[ $a =~ @\. ]] || echo -E - " $a"; done; } - __systemctl $mode list-units --state inactive,failed "*$PREFIX*$SUFFIX*" | \ - { while read -r a b; do echo -E - " $a"; done; } )) ) ) + _sys_startable_units=( $( _filter_units_by_property ActiveState inactive $( + _filter_units_by_property CanStart yes ${${${(f)"$( + __systemctl $mode list-unit-files --state enabled,disabled,static "*$PREFIX*$SUFFIX*" + __systemctl $mode list-units --state inactive,failed "*$PREFIX*$SUFFIX*" + )"}:#*@.*}%%[[:space:]]*} + )) ) } _systemctl_restartable_units(){ - _sys_restartable_units=( $(_filter_units_by_property CanStart yes $( - __systemctl $mode list-unit-files --state enabled,disabled,static "*$PREFIX*$SUFFIX*" | \ - { while read -r a b; do [[ $a =~ @\. ]] || echo -E - " $a"; done; } - __systemctl $mode list-units "*$PREFIX*$SUFFIX*" | \ - { while read -r a b; do echo -E - " $a"; done; } )) ) + _sys_restartable_units=( $( _filter_units_by_property CanStart yes ${${${(f)"$( + __systemctl $mode list-unit-files --state enabled,disabled,static "*$PREFIX*$SUFFIX*" + __systemctl $mode list-units "*$PREFIX*$SUFFIX*" + )"}:#*@.*}%%[[:space:]]*} ) ) } _systemctl_failed_units() {_sys_failed_units=( ${${(f)"$(__systemctl list-units --state=failed "*$PREFIX*$SUFFIX*" )"}%% *} ) } diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze index ce22217fbc..ae13f4bbde 100644 --- a/shell-completion/zsh/_systemd-analyze +++ b/shell-completion/zsh/_systemd-analyze @@ -1,13 +1,13 @@ #compdef systemd-analyze # SPDX-License-Identifier: LGPL-2.1+ -_systemd_analyze_set-log-level() { +_systemd_analyze_log-level() { local -a _levels _levels=(debug info notice warning err crit alert emerg) _describe -t level 'logging level' _levels || compadd "$@" } -_systemd_analyze_set-log-target() { +_systemd_analyze_log-target() { local -a _targets _targets=(console journal kmsg journal-or-kmsg null) _describe -t target 'logging target' _targets || compadd "$@" @@ -17,6 +17,12 @@ _systemd_analyze_verify() { _sd_unit_files } +_systemd_analyze_service-watchdogs() { + local -a _states + _states=(on off) + _describe -t state 'state' _states || compadd "$@" +} + _systemd_analyze_command(){ local -a _systemd_analyze_cmds # Descriptions taken from systemd-analyze --help. @@ -27,10 +33,9 @@ _systemd_analyze_command(){ 'plot:Output SVG graphic showing service initialization' 'dot:Dump dependency graph (in dot(1) format)' 'dump:Dump server status' - 'set-log-level:Set systemd log threshold' - 'set-log-target:Set systemd log target' - 'get-log-level:Get systemd log threshold' - 'get-log-target:Get systemd log target' + 'log-level:Get/set systemd log threshold' + 'log-target:Get/set systemd log target' + 'service-watchdogs:Get/set service watchdog status' 'syscall-filter:List syscalls in seccomp filter' 'verify:Check unit files for correctness' ) diff --git a/src/activate/activate.c b/src/activate/activate.c index 83807efdcf..c07dcb8626 100644 --- a/src/activate/activate.c +++ b/src/activate/activate.c @@ -267,38 +267,23 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd, static int fork_and_exec_process(const char* child, char** argv, char **env, int fd) { _cleanup_free_ char *joined = NULL; - pid_t parent_pid, child_pid; + pid_t child_pid; + int r; joined = strv_join(argv, " "); if (!joined) return log_oom(); - parent_pid = getpid_cached(); - - child_pid = fork(); - if (child_pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - - /* In the child */ - if (child_pid == 0) { - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - - /* Make sure the child goes away when the parent dies */ - if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) - _exit(EXIT_FAILURE); - - /* Check whether our parent died before we were able - * to set the death signal */ - if (getppid() != parent_pid) - _exit(EXIT_SUCCESS); - + r = safe_fork("(activate)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &child_pid); + if (r < 0) + return r; + if (r == 0) { + /* In the child */ exec_process(child, argv, env, fd, 1); _exit(EXIT_FAILURE); } - log_info("Spawned %s (%s) as PID %d", child, joined, child_pid); + log_info("Spawned %s (%s) as PID " PID_FMT ".", child, joined, child_pid); return 0; } diff --git a/src/analyze/analyze-verify.c b/src/analyze/analyze-verify.c index 461e7852ac..f475b6598c 100644 --- a/src/analyze/analyze-verify.c +++ b/src/analyze/analyze-verify.c @@ -220,7 +220,7 @@ static int verify_unit(Unit *u, bool check_man) { assert(u); - if (log_get_max_level() >= LOG_DEBUG) + if (DEBUG_LOGGING) unit_dump(u, stdout, "\t"); log_unit_debug(u, "Creating %s/start job", u->id); diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index d45c1dc496..834620a4cd 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -47,6 +47,7 @@ #include "terminal-util.h" #include "unit-name.h" #include "util.h" +#include "verbs.h" #define SCALE_X (0.1 / 1000.0) /* pixels per us */ #define SCALE_Y (20.0) @@ -78,7 +79,7 @@ static char** arg_dot_to_patterns = NULL; static usec_t arg_fuzz = 0; static bool arg_no_pager = false; static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; -static char *arg_host = NULL; +static const char *arg_host = NULL; static bool arg_user = false; static bool arg_man = true; static bool arg_generators = false; @@ -130,6 +131,13 @@ struct host_info { char *architecture; }; +static int acquire_bus(bool need_full_bus, sd_bus **bus) { + if (need_full_bus) + return bus_connect_transport(arg_transport, arg_host, arg_user, bus); + else + return bus_connect_transport_systemd(arg_transport, arg_host, arg_user, bus); +} + static int bus_get_uint64_property(sd_bus *bus, const char *path, const char *interface, const char *property, uint64_t *val) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; @@ -521,7 +529,7 @@ static int pretty_boot_time(sd_bus *bus, char **_buf) { "ActiveEnterTimestampMonotonic", &activated_time); if (r < 0) { - log_info_errno(r, "default.target seems not to be started. Continuing..."); + log_info_errno(r, "Could not get time to reach default.target. Continuing..."); activated_time = USEC_INFINITY; } @@ -541,8 +549,15 @@ static int pretty_boot_time(sd_bus *bus, char **_buf) { size = strpcpyf(&ptr, size, "%s (userspace) ", format_timespan(ts, sizeof(ts), t->finish_time - t->userspace_time, USEC_PER_MSEC)); strpcpyf(&ptr, size, "= %s", format_timespan(ts, sizeof(ts), t->firmware_time + t->finish_time, USEC_PER_MSEC)); - if (unit_id && activated_time != USEC_INFINITY) + if (unit_id && (activated_time > 0 && activated_time != USEC_INFINITY)) size = strpcpyf(&ptr, size, "\n%s reached after %s in userspace", unit_id, format_timespan(ts, sizeof(ts), activated_time - t->userspace_time, USEC_PER_MSEC)); + else if (unit_id && activated_time == 0) + size = strpcpyf(&ptr, size, "\n%s was never reached", unit_id); + else if (unit_id && activated_time == USEC_INFINITY) + size = strpcpyf(&ptr, size, "\nCould not get time to reach %s.",unit_id); + else if (!unit_id) + size = strpcpyf(&ptr, size, "\ncould not find default.target"); + ptr = strdup(buf); if (!ptr) @@ -575,15 +590,20 @@ static void svg_graph_box(double height, double begin, double end) { } } -static int analyze_plot(sd_bus *bus) { +static int analyze_plot(int argc, char *argv[], void *userdata) { _cleanup_(free_host_infop) struct host_info *host = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; struct unit_times *times; struct boot_times *boot; - int n, m = 1, y=0; + int n, m = 1, y = 0, r; double width; _cleanup_free_ char *pretty_times = NULL; struct unit_times *u; + r = acquire_bus(true, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); + n = acquire_boot_times(bus, &boot); if (n < 0) return n; @@ -977,24 +997,29 @@ static int list_dependencies(sd_bus *bus, const char *name) { return list_dependencies_one(bus, name, 0, &units, 0); } -static int analyze_critical_chain(sd_bus *bus, char *names[]) { +static int analyze_critical_chain(int argc, char *argv[], void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; struct unit_times *times; unsigned int i; Hashmap *h; int n, r; + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); + n = acquire_time_data(bus, ×); if (n <= 0) return n; h = hashmap_new(&string_hash_ops); if (!h) - return -ENOMEM; + return log_oom(); - for (i = 0; i < (unsigned)n; i++) { + for (i = 0; i < (unsigned) n; i++) { r = hashmap_put(h, times[i].name, ×[i]); if (r < 0) - return r; + return log_error_errno(r, "Failed to add entry to hashmap: %m"); } unit_times_hashmap = h; @@ -1003,22 +1028,27 @@ static int analyze_critical_chain(sd_bus *bus, char *names[]) { puts("The time after the unit is active or started is printed after the \"@\" character.\n" "The time the unit takes to start is printed after the \"+\" character.\n"); - if (!strv_isempty(names)) { + if (argc > 1) { char **name; - STRV_FOREACH(name, names) + STRV_FOREACH(name, strv_skip(argv, 1)) list_dependencies(bus, *name); } else list_dependencies(bus, SPECIAL_DEFAULT_TARGET); - hashmap_free(h); + h = hashmap_free(h); free_unit_times(times, (unsigned) n); return 0; } -static int analyze_blame(sd_bus *bus) { +static int analyze_blame(int argc, char *argv[], void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; struct unit_times *times; unsigned i; - int n; + int n, r; + + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); n = acquire_time_data(bus, ×); if (n <= 0) @@ -1039,10 +1069,15 @@ static int analyze_blame(sd_bus *bus) { return 0; } -static int analyze_time(sd_bus *bus) { +static int analyze_time(int argc, char *argv[], void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_free_ char *buf = NULL; int r; + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); + r = pretty_boot_time(bus, &buf); if (r < 0) return r; @@ -1163,16 +1198,21 @@ static int expand_patterns(sd_bus *bus, char **patterns, char ***ret) { return 0; } -static int dot(sd_bus *bus, char* patterns[]) { +static int dot(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_strv_free_ char **expanded_patterns = NULL; _cleanup_strv_free_ char **expanded_from_patterns = NULL; _cleanup_strv_free_ char **expanded_to_patterns = NULL; int r; UnitInfo u; - r = expand_patterns(bus, patterns, &expanded_patterns); + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); + + r = expand_patterns(bus, strv_skip(argv, 1), &expanded_patterns); if (r < 0) return r; @@ -1228,28 +1268,28 @@ static int dot(sd_bus *bus, char* patterns[]) { return 0; } -static int dump(sd_bus *bus, char **args) { - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; +static int dump(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; const char *text = NULL; int r; - if (!strv_isempty(args)) { - log_error("Too many arguments."); - return -E2BIG; - } + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); pager_open(arg_no_pager, false); r = sd_bus_call_method( bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "Dump", - &error, - &reply, - ""); + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Dump", + &error, + &reply, + NULL); if (r < 0) return log_error_errno(r, "Failed issue method call: %s", bus_error_message(&error, r)); @@ -1261,17 +1301,17 @@ static int dump(sd_bus *bus, char **args) { return 0; } -static int set_log_level(sd_bus *bus, char **args) { +static int set_log_level(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; - assert(bus); - assert(args); + assert(argc == 2); + assert(argv); - if (strv_length(args) != 1) { - log_error("This command expects one argument only."); - return -E2BIG; - } + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); r = sd_bus_set_property( bus, @@ -1281,25 +1321,22 @@ static int set_log_level(sd_bus *bus, char **args) { "LogLevel", &error, "s", - args[0]); + argv[1]); if (r < 0) return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r)); return 0; } -static int get_log_level(sd_bus *bus, char **args) { +static int get_log_level(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - int r; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_free_ char *level = NULL; + int r; - assert(bus); - assert(args); - - if (!strv_isempty(args)) { - log_error("Too many arguments."); - return -E2BIG; - } + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); r = sd_bus_get_property_string( bus, @@ -1316,17 +1353,21 @@ static int get_log_level(sd_bus *bus, char **args) { return 0; } -static int set_log_target(sd_bus *bus, char **args) { +static int get_or_set_log_level(int argc, char *argv[], void *userdata) { + return (argc == 1) ? get_log_level(argc, argv, userdata) : set_log_level(argc, argv, userdata); +} + +static int set_log_target(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; - assert(bus); - assert(args); + assert(argc == 2); + assert(argv); - if (strv_length(args) != 1) { - log_error("This command expects one argument only."); - return -E2BIG; - } + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); r = sd_bus_set_property( bus, @@ -1336,25 +1377,22 @@ static int set_log_target(sd_bus *bus, char **args) { "LogTarget", &error, "s", - args[0]); + argv[1]); if (r < 0) return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r)); return 0; } -static int get_log_target(sd_bus *bus, char **args) { +static int get_log_target(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - int r; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_free_ char *target = NULL; + int r; - assert(bus); - assert(args); - - if (!strv_isempty(args)) { - log_error("Too many arguments."); - return -E2BIG; - } + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); r = sd_bus_get_property_string( bus, @@ -1371,6 +1409,10 @@ static int get_log_target(sd_bus *bus, char **args) { return 0; } +static int get_or_set_log_target(int argc, char *argv[], void *userdata) { + return (argc == 1) ? get_log_target(argc, argv, userdata) : set_log_target(argc, argv, userdata); +} + #if HAVE_SECCOMP static void dump_syscall_filter(const SyscallFilterSet *set) { const char *syscall; @@ -1381,12 +1423,12 @@ static void dump_syscall_filter(const SyscallFilterSet *set) { printf(" %s\n", syscall); } -static int dump_syscall_filters(char** names) { +static int dump_syscall_filters(int argc, char *argv[], void *userdata) { bool first = true; pager_open(arg_no_pager, false); - if (strv_isempty(names)) { + if (strv_isempty(strv_skip(argv, 1))) { int i; for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) { @@ -1398,7 +1440,7 @@ static int dump_syscall_filters(char** names) { } else { char **name; - STRV_FOREACH(name, names) { + STRV_FOREACH(name, strv_skip(argv, 1)) { const SyscallFilterSet *set; if (!first) @@ -1422,25 +1464,20 @@ static int dump_syscall_filters(char** names) { } #else -static int dump_syscall_filters(char** names) { +static int dump_syscall_filters(int argc, char *argv[], void *userdata) { log_error("Not compiled with syscall filters, sorry."); return -EOPNOTSUPP; } #endif -static int test_calendar(char **args) { +static int test_calendar(int argc, char *argv[], void *userdata) { int ret = 0, r; char **p; usec_t n; - if (strv_isempty(args)) { - log_error("Expected at least one calendar specification string as argument."); - return -EINVAL; - } - n = now(CLOCK_REALTIME); - STRV_FOREACH(p, args) { + STRV_FOREACH(p, strv_skip(argv, 1)) { _cleanup_(calendar_spec_freep) CalendarSpec *spec = NULL; _cleanup_free_ char *t = NULL; usec_t next; @@ -1492,7 +1529,67 @@ static int test_calendar(char **args) { return ret; } -static void help(void) { +static int service_watchdogs(int argc, char *argv[], void *userdata) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + int b, r; + + assert(IN_SET(argc, 1, 2)); + assert(argv); + + r = acquire_bus(false, &bus); + if (r < 0) + return log_error_errno(r, "Failed to create bus connection: %m"); + + /* get ServiceWatchdogs */ + if (argc == 1) { + r = sd_bus_get_property_trivial( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ServiceWatchdogs", + &error, + 'b', + &b); + if (r < 0) + return log_error_errno(r, "Failed to get service-watchdog state: %s", bus_error_message(&error, r)); + + printf("%s\n", yes_no(!!b)); + + return 0; + } + + /* set ServiceWatchdogs */ + b = parse_boolean(argv[1]); + if (b < 0) { + log_error("Failed to parse service-watchdogs argument."); + return -EINVAL; + } + + r = sd_bus_set_property( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ServiceWatchdogs", + &error, + "b", + b); + if (r < 0) + return log_error_errno(r, "Failed to set service-watchdog state: %s", bus_error_message(&error, r)); + + return 0; +} + +static int do_verify(int argc, char *argv[], void *userdata) { + return verify_units(strv_skip(argv, 1), + arg_user ? UNIT_FILE_USER : UNIT_FILE_SYSTEM, + arg_man, + arg_generators); +} + +static int help(int argc, char *argv[], void *userdata) { pager_open(arg_no_pager, false); @@ -1516,22 +1613,23 @@ static void help(void) { "Commands:\n" " time Print time spent in the kernel\n" " blame Print list of running units ordered by time to init\n" - " critical-chain Print a tree of the time critical chain of units\n" + " critical-chain [UNIT...] Print a tree of the time critical chain of units\n" " plot Output SVG graphic showing service initialization\n" - " dot Output dependency graph in man:dot(1) format\n" - " set-log-level LEVEL Set logging threshold for manager\n" - " set-log-target TARGET Set logging target for manager\n" - " get-log-level Get logging threshold for manager\n" - " get-log-target Get logging target for manager\n" + " dot [UNIT...] Output dependency graph in man:dot(1) format\n" + " log-level [LEVEL] Get/set logging threshold for manager\n" + " log-target [TARGET] Get/set logging target for manager\n" " dump Output state serialization of service manager\n" " syscall-filter [NAME...] Print list of syscalls in seccomp filter\n" " verify FILE... Check unit files for correctness\n" " calendar SPEC... Validate repetitive calendar time events\n" + " service-watchdogs [BOOL] Get/set service watchdog state\n" , program_invocation_short_name); /* When updating this list, including descriptions, apply * changes to shell-completion/bash/systemd-analyze and * shell-completion/zsh/_systemd-analyze too. */ + + return 0; } static int parse_argv(int argc, char *argv[]) { @@ -1576,8 +1674,7 @@ static int parse_argv(int argc, char *argv[]) { switch (c) { case 'h': - help(); - return 0; + return help(0, NULL, NULL); case ARG_VERSION: return version(); @@ -1669,10 +1766,34 @@ static int parse_argv(int argc, char *argv[]) { } int main(int argc, char *argv[]) { + + static const Verb verbs[] = { + { "help", VERB_ANY, VERB_ANY, 0, help }, + { "time", VERB_ANY, 1, VERB_DEFAULT, analyze_time }, + { "blame", VERB_ANY, 1, 0, analyze_blame }, + { "critical-chain", VERB_ANY, VERB_ANY, 0, analyze_critical_chain }, + { "plot", VERB_ANY, 1, 0, analyze_plot }, + { "dot", VERB_ANY, VERB_ANY, 0, dot }, + { "log-level", VERB_ANY, 2, 0, get_or_set_log_level }, + { "log-target", VERB_ANY, 2, 0, get_or_set_log_target }, + /* The following four verbs are deprecated aliases */ + { "set-log-level", 2, 2, 0, set_log_level }, + { "get-log-level", VERB_ANY, 1, 0, get_log_level }, + { "set-log-target", 2, 2, 0, set_log_target }, + { "get-log-target", VERB_ANY, 1, 0, get_log_target }, + { "dump", VERB_ANY, 1, 0, dump }, + { "syscall-filter", VERB_ANY, VERB_ANY, 0, dump_syscall_filters }, + { "verify", 2, VERB_ANY, 0, do_verify }, + { "calendar", 2, VERB_ANY, 0, test_calendar }, + { "service-watchdogs", VERB_ANY, 2, 0, service_watchdogs }, + {} + }; + int r; setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); /* we want to format/parse floats in C style */ + log_parse_environment(); log_open(); @@ -1680,47 +1801,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - if (streq_ptr(argv[optind], "verify")) - r = verify_units(argv+optind+1, - arg_user ? UNIT_FILE_USER : UNIT_FILE_SYSTEM, - arg_man, - arg_generators); - else { - _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; - - r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus); - if (r < 0) { - log_error_errno(r, "Failed to create bus connection: %m"); - goto finish; - } - - if (!argv[optind] || streq(argv[optind], "time")) - r = analyze_time(bus); - else if (streq(argv[optind], "blame")) - r = analyze_blame(bus); - else if (streq(argv[optind], "critical-chain")) - r = analyze_critical_chain(bus, argv+optind+1); - else if (streq(argv[optind], "plot")) - r = analyze_plot(bus); - else if (streq(argv[optind], "dot")) - r = dot(bus, argv+optind+1); - else if (streq(argv[optind], "dump")) - r = dump(bus, argv+optind+1); - else if (streq(argv[optind], "set-log-level")) - r = set_log_level(bus, argv+optind+1); - else if (streq(argv[optind], "get-log-level")) - r = get_log_level(bus, argv+optind+1); - else if (streq(argv[optind], "set-log-target")) - r = set_log_target(bus, argv+optind+1); - else if (streq(argv[optind], "get-log-target")) - r = get_log_target(bus, argv+optind+1); - else if (streq(argv[optind], "syscall-filter")) - r = dump_syscall_filters(argv+optind+1); - else if (streq(argv[optind], "calendar")) - r = test_calendar(argv+optind+1); - else - log_error("Unknown operation '%s'.", argv[optind]); - } + r = dispatch_verb(argc, argv, verbs, NULL); finish: pager_close(); diff --git a/src/basic/af-list.h b/src/basic/af-list.h index 65656022cc..1684bc6a0f 100644 --- a/src/basic/af-list.h +++ b/src/basic/af-list.h @@ -20,6 +20,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <sys/socket.h> + #include "string-util.h" const char *af_to_name(int id); diff --git a/src/basic/async.c b/src/basic/async.c index d368b92522..b6c6d6a80b 100644 --- a/src/basic/async.c +++ b/src/basic/async.c @@ -27,49 +27,82 @@ #include "fd-util.h" #include "log.h" #include "macro.h" +#include "process-util.h" +#include "signal-util.h" #include "util.h" int asynchronous_job(void* (*func)(void *p), void *arg) { + sigset_t ss, saved_ss; pthread_attr_t a; pthread_t t; - int r; + int r, k; - /* It kinda sucks that we have to resort to threads to - * implement an asynchronous sync(), but well, such is - * life. - * - * Note that issuing this command right before exiting a - * process will cause the process to wait for the sync() to - * complete. This function hence is nicely asynchronous really - * only in long running processes. */ + /* It kinda sucks that we have to resort to threads to implement an asynchronous close(), but well, such is + * life. */ r = pthread_attr_init(&a); if (r > 0) return -r; r = pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED); - if (r > 0) + if (r > 0) { + r = -r; + goto finish; + } + + if (sigfillset(&ss) < 0) { + r = -errno; + goto finish; + } + + /* Block all signals before forking off the thread, so that the new thread is started with all signals + * blocked. This way the existence of the new thread won't affect signal handling in other threads. */ + + r = pthread_sigmask(SIG_BLOCK, &ss, &saved_ss); + if (r > 0) { + r = -r; goto finish; + } r = pthread_create(&t, &a, func, arg); + k = pthread_sigmask(SIG_SETMASK, &saved_ss, NULL); + + if (r > 0) + r = -r; + else if (k > 0) + r = -k; + else + r = 0; + finish: pthread_attr_destroy(&a); - return -r; + return r; } -static void *sync_thread(void *p) { - sync(); - return NULL; -} +int asynchronous_sync(pid_t *ret_pid) { + int r; -int asynchronous_sync(void) { - log_debug("Spawning new thread for sync"); + /* This forks off an invocation of fork() as a child process, in order to initiate synchronization to + * disk. Note that we implement this as helper process rather than thread as we don't want the sync() to hang our + * original process ever, and a thread would do that as the process can't exit with threads hanging in blocking + * syscalls. */ + + r = safe_fork("(sd-sync)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS, ret_pid); + if (r < 0) + return r; + if (r == 0) { + /* Child process */ + (void) sync(); + _exit(EXIT_SUCCESS); + } - return asynchronous_job(sync_thread, NULL); + return 0; } static void *close_thread(void *p) { + (void) pthread_setname_np(pthread_self(), "close"); + assert_se(close_nointr(PTR_TO_FD(p)) != -EBADF); return NULL; } diff --git a/src/basic/async.h b/src/basic/async.h index 7eac54d8b2..01c975bb30 100644 --- a/src/basic/async.h +++ b/src/basic/async.h @@ -22,5 +22,5 @@ int asynchronous_job(void* (*func)(void *p), void *arg); -int asynchronous_sync(void); +int asynchronous_sync(pid_t *ret_pid); int asynchronous_close(int fd); diff --git a/src/basic/blockdev-util.c b/src/basic/blockdev-util.c new file mode 100644 index 0000000000..3a8f8d1c27 --- /dev/null +++ b/src/basic/blockdev-util.c @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/stat.h> +#include <sys/statfs.h> + +#include "alloc-util.h" +#include "blockdev-util.h" +#include "btrfs-util.h" +#include "dirent-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "missing.h" +#include "stat-util.h" + +int block_get_whole_disk(dev_t d, dev_t *ret) { + char p[SYS_BLOCK_PATH_MAX("/partition")]; + _cleanup_free_ char *s = NULL; + unsigned n, m; + int r; + + assert(ret); + + /* If it has a queue this is good enough for us */ + xsprintf_sys_block_path(p, "/queue", d); + if (access(p, F_OK) >= 0) { + *ret = d; + return 0; + } + + /* If it is a partition find the originating device */ + xsprintf_sys_block_path(p, "/partition", d); + if (access(p, F_OK) < 0) + return -ENOENT; + + /* Get parent dev_t */ + xsprintf_sys_block_path(p, "/../dev", d); + r = read_one_line_file(p, &s); + if (r < 0) + return r; + + r = sscanf(s, "%u:%u", &m, &n); + if (r != 2) + return -EINVAL; + + /* Only return this if it is really good enough for us. */ + xsprintf_sys_block_path(p, "/queue", makedev(m, n)); + if (access(p, F_OK) < 0) + return -ENOENT; + + *ret = makedev(m, n); + return 0; +} + +int get_block_device(const char *path, dev_t *dev) { + struct stat st; + struct statfs sfs; + + assert(path); + assert(dev); + + /* Get's the block device directly backing a file system. If + * the block device is encrypted, returns the device mapper + * block device. */ + + if (lstat(path, &st)) + return -errno; + + if (major(st.st_dev) != 0) { + *dev = st.st_dev; + return 1; + } + + if (statfs(path, &sfs) < 0) + return -errno; + + if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) + return btrfs_get_block_device(path, dev); + + return 0; +} + +int get_block_device_harder(const char *path, dev_t *dev) { + _cleanup_closedir_ DIR *d = NULL; + _cleanup_free_ char *t = NULL; + char p[SYS_BLOCK_PATH_MAX("/slaves")]; + struct dirent *de, *found = NULL; + const char *q; + unsigned maj, min; + dev_t dt; + int r; + + assert(path); + assert(dev); + + /* Gets the backing block device for a file system, and + * handles LUKS encrypted file systems, looking for its + * immediate parent, if there is one. */ + + r = get_block_device(path, &dt); + if (r <= 0) + return r; + + xsprintf_sys_block_path(p, "/slaves", dt); + d = opendir(p); + if (!d) { + if (errno == ENOENT) + goto fallback; + + return -errno; + } + + FOREACH_DIRENT_ALL(de, d, return -errno) { + + if (dot_or_dot_dot(de->d_name)) + continue; + + if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN)) + continue; + + if (found) { + _cleanup_free_ char *u = NULL, *v = NULL, *a = NULL, *b = NULL; + + /* We found a device backed by multiple other devices. We don't really support automatic + * discovery on such setups, with the exception of dm-verity partitions. In this case there are + * two backing devices: the data partition and the hash partition. We are fine with such + * setups, however, only if both partitions are on the same physical device. Hence, let's + * verify this. */ + + u = strjoin(p, "/", de->d_name, "/../dev"); + if (!u) + return -ENOMEM; + + v = strjoin(p, "/", found->d_name, "/../dev"); + if (!v) + return -ENOMEM; + + r = read_one_line_file(u, &a); + if (r < 0) { + log_debug_errno(r, "Failed to read %s: %m", u); + goto fallback; + } + + r = read_one_line_file(v, &b); + if (r < 0) { + log_debug_errno(r, "Failed to read %s: %m", v); + goto fallback; + } + + /* Check if the parent device is the same. If not, then the two backing devices are on + * different physical devices, and we don't support that. */ + if (!streq(a, b)) + goto fallback; + } + + found = de; + } + + if (!found) + goto fallback; + + q = strjoina(p, "/", found->d_name, "/dev"); + + r = read_one_line_file(q, &t); + if (r == -ENOENT) + goto fallback; + if (r < 0) + return r; + + if (sscanf(t, "%u:%u", &maj, &min) != 2) + return -EINVAL; + + if (maj == 0) + goto fallback; + + *dev = makedev(maj, min); + return 1; + +fallback: + *dev = dt; + return 1; +} diff --git a/src/libsystemd/sd-bus/bus-bloom.h b/src/basic/blockdev-util.h index 2650762145..642b7ce522 100644 --- a/src/libsystemd/sd-bus/bus-bloom.h +++ b/src/basic/blockdev-util.h @@ -4,7 +4,7 @@ /*** This file is part of systemd. - Copyright 2013 Lennart Poettering + Copyright 2010 Lennart Poettering systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -20,25 +20,19 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> +#include <sys/types.h> -/* - * Our default bloom filter has the following parameters: - * - * m=512 (bits in the filter) - * k=8 (hash functions) - * - * We use SipHash24 as hash function with a number of (originally - * randomized) but fixed hash keys. - * - */ +#include "macro.h" +#include "stdio-util.h" +#include "string-util.h" -#define DEFAULT_BLOOM_SIZE (512/8) /* m: filter size */ -#define DEFAULT_BLOOM_N_HASH 8 /* k: number of hash functions */ +#define SYS_BLOCK_PATH_MAX(suffix) \ + (STRLEN("/sys/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t) + strlen_ptr(suffix)) +#define xsprintf_sys_block_path(buf, suffix, devno) \ + xsprintf(buf, "/sys/dev/block/%u:%u%s", major(devno), minor(devno), strempty(suffix)) -void bloom_add_pair(uint64_t filter[], size_t size, unsigned n_hash, const char *a, const char *b); -void bloom_add_prefixes(uint64_t filter[], size_t size, unsigned n_hash, const char *a, const char *b, char sep); +int block_get_whole_disk(dev_t d, dev_t *ret); -bool bloom_validate_parameters(size_t size, unsigned n_hash); +int get_block_device(const char *path, dev_t *dev); + +int get_block_device_harder(const char *path, dev_t *dev); diff --git a/src/basic/btrfs-ctree.h b/src/basic/btrfs-ctree.h index 66bdf9736e..c5a4244e37 100644 --- a/src/basic/btrfs-ctree.h +++ b/src/basic/btrfs-ctree.h @@ -1,6 +1,7 @@ #pragma once #include "macro.h" +#include "missing.h" #include "sparse-endian.h" /* Stolen from btrfs' ctree.h */ diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c index ac96e63531..19d385ab7c 100644 --- a/src/basic/btrfs-util.c +++ b/src/basic/btrfs-util.c @@ -38,6 +38,7 @@ #endif #include "alloc-util.h" +#include "blockdev-util.h" #include "btrfs-ctree.h" #include "btrfs-util.h" #include "chattr-util.h" @@ -50,7 +51,6 @@ #include "missing.h" #include "path-util.h" #include "rm-rf.h" -#include "selinux-util.h" #include "smack-util.h" #include "sparse-endian.h" #include "stat-util.h" @@ -174,24 +174,6 @@ int btrfs_subvol_make(const char *path) { return 0; } -int btrfs_subvol_make_label(const char *path) { - int r; - - assert(path); - - r = mac_selinux_create_file_prepare(path, S_IFDIR); - if (r < 0) - return r; - - r = btrfs_subvol_make(path); - mac_selinux_create_file_clear(); - - if (r < 0) - return r; - - return mac_smack_fix(path, false, false); -} - int btrfs_subvol_set_read_only_fd(int fd, bool b) { uint64_t flags, nflags; struct stat st; diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h index 2c78daa37b..952b3c26da 100644 --- a/src/basic/btrfs-util.h +++ b/src/basic/btrfs-util.h @@ -84,7 +84,6 @@ int btrfs_resize_loopback_fd(int fd, uint64_t size, bool grow_only); int btrfs_resize_loopback(const char *path, uint64_t size, bool grow_only); int btrfs_subvol_make(const char *path); -int btrfs_subvol_make_label(const char *path); int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlags flags); int btrfs_subvol_snapshot(const char *old_path, const char *new_path, BtrfsSnapshotFlags flags); diff --git a/src/basic/build.h b/src/basic/build.h index ab2a838ce9..0d078efe6f 100644 --- a/src/basic/build.h +++ b/src/basic/build.h @@ -140,6 +140,12 @@ #define _IDN_FEATURE_ "-IDN" #endif +#if HAVE_PCRE2 +#define _PCRE2_FEATURE_ "+PCRE2" +#else +#define _PCRE2_FEATURE_ "-PCRE2" +#endif + #define _CGROUP_HIEARCHY_ "default-hierarchy=" DEFAULT_HIERARCHY_NAME #define SYSTEMD_FEATURES \ @@ -163,4 +169,5 @@ _KMOD_FEATURE_ " " \ _IDN2_FEATURE_ " " \ _IDN_FEATURE_ " " \ + _PCRE2_FEATURE_ " " \ _CGROUP_HIEARCHY_ diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c index e6add0c383..fd78022773 100644 --- a/src/basic/calendarspec.c +++ b/src/basic/calendarspec.c @@ -35,6 +35,7 @@ #include "fileio.h" #include "macro.h" #include "parse-util.h" +#include "process-util.h" #include "string-util.h" #include "time-util.h" @@ -156,6 +157,11 @@ static void fix_year(CalendarComponent *c) { int calendar_spec_normalize(CalendarSpec *c) { assert(c); + if (streq_ptr(c->timezone, "UTC")) { + c->utc = true; + c->timezone = mfree(c->timezone); + } + if (c->weekdays_bits <= 0 || c->weekdays_bits >= BITS_WEEKDAYS) c->weekdays_bits = -1; @@ -1348,9 +1354,7 @@ typedef struct SpecNextResult { } SpecNextResult; int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next) { - pid_t pid; - SpecNextResult *shared; - SpecNextResult tmp; + SpecNextResult *shared, tmp; int r; if (isempty(spec->timezone)) @@ -1360,15 +1364,12 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next) if (shared == MAP_FAILED) return negative_errno(); - pid = fork(); - - if (pid == -1) { - int fork_errno = errno; + r = safe_fork("(sd-calendar)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT, NULL); + if (r < 0) { (void) munmap(shared, sizeof *shared); - return -fork_errno; + return r; } - - if (pid == 0) { + if (r == 0) { if (setenv("TZ", spec->timezone, 1) != 0) { shared->return_value = negative_errno(); _exit(EXIT_FAILURE); @@ -1381,14 +1382,8 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next) _exit(EXIT_SUCCESS); } - r = wait_for_terminate(pid, NULL); - if (r < 0) { - (void) munmap(shared, sizeof *shared); - return r; - } - tmp = *shared; - if (munmap(shared, sizeof *shared) != 0) + if (munmap(shared, sizeof *shared) < 0) return negative_errno(); if (tmp.return_value == 0) diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index f599d0f0f1..7c0ba92110 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -779,13 +779,11 @@ int cg_create(const char *controller, const char *path) { if (r < 0) return r; - if (mkdir(fs, 0755) < 0) { - - if (errno == EEXIST) - return 0; - - return -errno; - } + r = mkdir_errno_wrapper(fs, 0755); + if (r == -EEXIST) + return 0; + if (r < 0) + return r; r = cg_hybrid_unified(); if (r < 0) diff --git a/src/basic/def.h b/src/basic/def.h index 77ab735aed..43e7e17008 100644 --- a/src/basic/def.h +++ b/src/basic/def.h @@ -53,9 +53,10 @@ "/usr/lib/kbd/keymaps/\0" #endif -#define UNIX_SYSTEM_BUS_ADDRESS "unix:path=/var/run/dbus/system_bus_socket" -#define DEFAULT_SYSTEM_BUS_ADDRESS UNIX_SYSTEM_BUS_ADDRESS -#define UNIX_USER_BUS_ADDRESS_FMT "unix:path=%s/bus" +/* Note that we use the new /run prefix here (instead of /var/run) since we require them to be aliases and that way we + * become independent of /var being mounted */ +#define DEFAULT_SYSTEM_BUS_ADDRESS "unix:path=/run/dbus/system_bus_socket" +#define DEFAULT_USER_BUS_ADDRESS_FMT "unix:path=%s/bus" #define PLYMOUTH_SOCKET { \ .un.sun_family = AF_UNIX, \ diff --git a/src/basic/device-nodes.h b/src/basic/device-nodes.h index 7dd8a772a5..49f4ccc729 100644 --- a/src/basic/device-nodes.h +++ b/src/basic/device-nodes.h @@ -29,11 +29,6 @@ int encode_devnode_name(const char *str, char *str_enc, size_t len); int whitelisted_char_for_devnode(char c, const char *additional); -#define SYS_BLOCK_PATH_MAX(suffix) \ - (STRLEN("/sys/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t) + strlen_ptr(suffix)) -#define xsprintf_sys_block_path(buf, suffix, devno) \ - xsprintf(buf, "/sys/dev/block/%u:%u%s", major(devno), minor(devno), strempty(suffix)) - #define DEV_NUM_PATH_MAX \ (STRLEN("/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t)) #define xsprintf_dev_num_path(buf, type, devno) \ diff --git a/src/basic/errno-list.c b/src/basic/errno-list.c index d8eedfc0ad..7eb28b8fd1 100644 --- a/src/basic/errno-list.c +++ b/src/basic/errno-list.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <string.h> #include "errno-list.h" diff --git a/src/basic/errno-list.h b/src/basic/errno-list.h index 4e9b75a7ea..38beaf96dd 100644 --- a/src/basic/errno-list.h +++ b/src/basic/errno-list.h @@ -20,6 +20,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <stdbool.h> /* * MAX_ERRNO is defined as 4095 in linux/err.h * We use the same value here. @@ -28,3 +29,6 @@ const char *errno_to_name(int id); int errno_from_name(const char *name); +static inline bool errno_is_valid(int n) { + return n > 0 && n <= ERRNO_MAX; +} diff --git a/src/basic/ether-addr-util.c b/src/basic/ether-addr-util.c index bbe8bf0006..bfbd1a4931 100644 --- a/src/basic/ether-addr-util.c +++ b/src/basic/ether-addr-util.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <net/ethernet.h> #include <stdio.h> #include <sys/types.h> diff --git a/src/basic/exec-util.c b/src/basic/exec-util.c index 82ccbdf5ec..0829b3d836 100644 --- a/src/basic/exec-util.c +++ b/src/basic/exec-util.c @@ -48,27 +48,26 @@ assert_cc(EAGAIN == EWOULDBLOCK); static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid) { pid_t _pid; + int r; if (null_or_empty_path(path)) { log_debug("%s is empty (a mask).", path); return 0; } - _pid = fork(); - if (_pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - if (_pid == 0) { + r = safe_fork("(direxec)", FORK_DEATHSIG|FORK_LOG, &_pid); + if (r < 0) + return r; + if (r == 0) { char *_argv[2]; - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - if (stdout_fd >= 0) { /* If the fd happens to be in the right place, go along with that */ if (stdout_fd != STDOUT_FILENO && dup2(stdout_fd, STDOUT_FILENO) < 0) return -errno; - fd_cloexec(STDOUT_FILENO, false); + (void) fd_cloexec(STDOUT_FILENO, false); } if (!argv) { @@ -83,7 +82,6 @@ static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid) { _exit(EXIT_FAILURE); } - log_debug("Spawned %s as " PID_FMT ".", path, _pid); *pid = _pid; return 1; } @@ -107,11 +105,6 @@ static int do_execute( * If callbacks is nonnull, execution is serial. Otherwise, we default to parallel. */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - r = conf_files_list_strv(&paths, NULL, NULL, CONF_FILES_EXECUTABLE, (const char* const*) directories); if (r < 0) return r; @@ -153,7 +146,7 @@ static int do_execute( return log_oom(); t = NULL; } else { - r = wait_for_terminate_and_warn(t, pid, true); + r = wait_for_terminate_and_check(t, pid, WAIT_LOG); if (r < 0) continue; @@ -183,7 +176,7 @@ static int do_execute( t = hashmap_remove(pids, PID_TO_PTR(pid)); assert(t); - wait_for_terminate_and_warn(t, pid, true); + (void) wait_for_terminate_and_check(t, pid, WAIT_LOG); } return 0; @@ -196,10 +189,9 @@ int execute_directories( void* const callback_args[_STDOUT_CONSUME_MAX], char *argv[]) { - pid_t executor_pid; - char *name; char **dirs = (char**) directories; _cleanup_close_ int fd = -1; + char *name; int r; assert(!strv_isempty(dirs)); @@ -222,24 +214,14 @@ int execute_directories( * them to finish. Optionally a timeout is applied. If a file with the same name * exists in more than one directory, the earliest one wins. */ - executor_pid = fork(); - if (executor_pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - - if (executor_pid == 0) { + r = safe_fork("(sd-executor)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL); + if (r < 0) + return r; + if (r == 0) { r = do_execute(dirs, timeout, callbacks, callback_args, fd, argv); _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); } - r = wait_for_terminate_and_warn(name, executor_pid, true); - if (r < 0) - return log_error_errno(r, "Execution failed: %m"); - if (r > 0) { - /* non-zero return code from child */ - log_error("Forker process failed."); - return -EREMOTEIO; - } - if (!callbacks) return 0; diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index a4a5c6b3f6..404361e8c1 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -192,9 +192,9 @@ int fd_cloexec(int fd, bool cloexec) { } void stdio_unset_cloexec(void) { - fd_cloexec(STDIN_FILENO, false); - fd_cloexec(STDOUT_FILENO, false); - fd_cloexec(STDERR_FILENO, false); + (void) fd_cloexec(STDIN_FILENO, false); + (void) fd_cloexec(STDOUT_FILENO, false); + (void) fd_cloexec(STDERR_FILENO, false); } _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) { @@ -227,20 +227,21 @@ int close_all_fds(const int except[], unsigned n_except) { assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0); for (fd = 3; fd < (int) rl.rlim_max; fd ++) { + int q; if (fd_in_set(fd, except, n_except)) continue; - if (close_nointr(fd) < 0) - if (errno != EBADF && r == 0) - r = -errno; + q = close_nointr(fd); + if (q < 0 && q != -EBADF && r >= 0) + r = q; } return r; } FOREACH_DIRENT(de, d, return -errno) { - int fd = -1; + int fd = -1, q; if (safe_atoi(de->d_name, &fd) < 0) /* Let's better ignore this, just in case */ @@ -255,11 +256,9 @@ int close_all_fds(const int except[], unsigned n_except) { if (fd_in_set(fd, except, n_except)) continue; - if (close_nointr(fd) < 0) { - /* Valgrind has its own FD and doesn't want to have it closed */ - if (errno != EBADF && r == 0) - r = -errno; - } + q = close_nointr(fd); + if (q < 0 && q != -EBADF && r >= 0) /* Valgrind has its own FD and doesn't want to have it closed */ + r = q; } return r; diff --git a/src/basic/fileio.c b/src/basic/fileio.c index 4e02d5b344..26d6174664 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -62,12 +62,30 @@ int write_string_stream_ts( WriteStringFileFlags flags, struct timespec *ts) { + bool needs_nl; + assert(f); assert(line); - fputs(line, f); - if (!(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n")) - fputc('\n', f); + if (ferror(f)) + return -EIO; + + needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n"); + + if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) { + /* If STDIO buffering was disabled, then let's append the newline character to the string itself, so + * that the write goes out in one go, instead of two */ + + line = strjoina(line, "\n"); + needs_nl = false; + } + + if (fputs(line, f) == EOF) + return -errno; + + if (needs_nl) + if (fputc('\n', f) == EOF) + return -errno; if (ts) { struct timespec twice[2] = {*ts, *ts}; @@ -908,14 +926,16 @@ int write_env_file(const char *fname, char **l) { } int executable_is_script(const char *path, char **interpreter) { - int r; _cleanup_free_ char *line = NULL; - int len; + size_t len; char *ans; + int r; assert(path); r = read_one_line_file(path, &line); + if (r == -ENOBUFS) /* First line overly long? if so, then it's not a script */ + return 0; if (r < 0) return r; @@ -1205,8 +1225,7 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) { if (!filename_is_valid(fn)) return -EINVAL; - if (!extra) - extra = ""; + extra = strempty(extra); t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1); if (!t) @@ -1239,8 +1258,7 @@ int tempfn_random(const char *p, const char *extra, char **ret) { if (!filename_is_valid(fn)) return -EINVAL; - if (!extra) - extra = ""; + extra = strempty(extra); t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1); if (!t) @@ -1280,8 +1298,7 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { return r; } - if (!extra) - extra = ""; + extra = strempty(extra); t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1); if (!t) diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 4ca36faf09..a8e50d4c78 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -39,6 +39,7 @@ #include "mkdir.h" #include "parse-util.h" #include "path-util.h" +#include "process-util.h" #include "stat-util.h" #include "stdio-util.h" #include "string-util.h" @@ -315,43 +316,60 @@ int fd_warn_permissions(const char *path, int fd) { } int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) { - _cleanup_close_ int fd; - int r; + char fdpath[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + _cleanup_close_ int fd = -1; + int r, ret = 0; assert(path); - if (parents) - mkdir_parents(path, 0755); - - fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, - IN_SET(mode, 0, MODE_INVALID) ? 0644 : mode); - if (fd < 0) - return -errno; + /* Note that touch_file() does not follow symlinks: if invoked on an existing symlink, then it is the symlink + * itself which is updated, not its target + * + * Returns the first error we encounter, but tries to apply as much as possible. */ - if (mode != MODE_INVALID) { - r = fchmod(fd, mode); - if (r < 0) + if (parents) + (void) mkdir_parents(path, 0755); + + /* Initially, we try to open the node with O_PATH, so that we get a reference to the node. This is useful in + * case the path refers to an existing device or socket node, as we can open it successfully in all cases, and + * won't trigger any driver magic or so. */ + fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW); + if (fd < 0) { + if (errno != ENOENT) return -errno; - } - if (uid != UID_INVALID || gid != GID_INVALID) { - r = fchown(fd, uid, gid); - if (r < 0) + /* if the node doesn't exist yet, we create it, but with O_EXCL, so that we only create a regular file + * here, and nothing else */ + fd = open(path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, IN_SET(mode, 0, MODE_INVALID) ? 0644 : mode); + if (fd < 0) return -errno; } + /* Let's make a path from the fd, and operate on that. With this logic, we can adjust the access mode, + * ownership and time of the file node in all cases, even if the fd refers to an O_PATH object — which is + * something fchown(), fchmod(), futimensat() don't allow. */ + xsprintf(fdpath, "/proc/self/fd/%i", fd); + + if (mode != MODE_INVALID) + if (chmod(fdpath, mode) < 0) + ret = -errno; + + if (uid_is_valid(uid) || gid_is_valid(gid)) + if (chown(fdpath, uid, gid) < 0 && ret >= 0) + ret = -errno; + if (stamp != USEC_INFINITY) { struct timespec ts[2]; timespec_store(&ts[0], stamp); ts[1] = ts[0]; - r = futimens(fd, ts); + r = utimensat(AT_FDCWD, fdpath, ts, 0); } else - r = futimens(fd, NULL); - if (r < 0) + r = utimensat(AT_FDCWD, fdpath, NULL, 0); + if (r < 0 && ret >= 0) return -errno; - return 0; + return ret; } int touch(const char *path) { @@ -593,16 +611,35 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) { return r; } +static bool safe_transition(const struct stat *a, const struct stat *b) { + /* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to + * privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files + * making us believe we read something safe even though it isn't safe in the specific context we open it in. */ + + if (a->st_uid == 0) /* Transitioning from privileged to unprivileged is always fine */ + return true; + + return a->st_uid == b->st_uid; /* Otherwise we need to stay within the same UID */ +} + int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret) { _cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL; _cleanup_close_ int fd = -1; unsigned max_follow = 32; /* how many symlinks to follow before giving up and returning ELOOP */ + struct stat previous_stat; bool exists = true; char *todo; int r; assert(path); + /* Either the file may be missing, or we return an fd to the final object, but both make no sense */ + if ((flags & (CHASE_NONEXISTENT|CHASE_OPEN)) == (CHASE_NONEXISTENT|CHASE_OPEN)) + return -EINVAL; + + if (isempty(path)) + return -EINVAL; + /* This is a lot like canonicalize_file_name(), but takes an additional "root" parameter, that allows following * symlinks relative to a root directory, instead of the root of the host. * @@ -623,13 +660,23 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, * function what to do when encountering a symlink with an absolute path as directory: prefix it by the * specified path. */ + /* A root directory of "/" or "" is identical to none */ + if (isempty(original_root) || path_equal(original_root, "/")) + original_root = NULL; + if (original_root) { r = path_make_absolute_cwd(original_root, &root); if (r < 0) return r; - if (flags & CHASE_PREFIX_ROOT) + if (flags & CHASE_PREFIX_ROOT) { + + /* We don't support relative paths in combination with a root directory */ + if (!path_is_absolute(path)) + return -EINVAL; + path = prefix_roota(root, path); + } } r = path_make_absolute_cwd(path, &buffer); @@ -640,6 +687,11 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, if (fd < 0) return -errno; + if (flags & CHASE_SAFE) { + if (fstat(fd, &previous_stat) < 0) + return -errno; + } + todo = buffer; for (;;) { _cleanup_free_ char *first = NULL; @@ -678,7 +730,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, /* Two dots? Then chop off the last bit of what we already found out. */ if (path_equal(first, "/..")) { _cleanup_free_ char *parent = NULL; - int fd_parent = -1; + _cleanup_close_ int fd_parent = -1; /* If we already are at the top, then going up will not change anything. This is in-line with * how the kernel handles this. */ @@ -701,8 +753,19 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, if (fd_parent < 0) return -errno; + if (flags & CHASE_SAFE) { + if (fstat(fd_parent, &st) < 0) + return -errno; + + if (!safe_transition(&previous_stat, &st)) + return -EPERM; + + previous_stat = st; + } + safe_close(fd); fd = fd_parent; + fd_parent = -1; continue; } @@ -735,6 +798,12 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, if (fstat(child, &st) < 0) return -errno; + if ((flags & CHASE_SAFE) && + !safe_transition(&previous_stat, &st)) + return -EPERM; + + previous_stat = st; + if ((flags & CHASE_NO_AUTOFS) && fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0) return -EREMOTE; @@ -765,6 +834,16 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, if (fd < 0) return -errno; + if (flags & CHASE_SAFE) { + if (fstat(fd, &st) < 0) + return -errno; + + if (!safe_transition(&previous_stat, &st)) + return -EPERM; + + previous_stat = st; + } + free(done); /* Note that we do not revalidate the root, we take it as is. */ @@ -821,6 +900,19 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, done = NULL; } + if (flags & CHASE_OPEN) { + int q; + + /* Return the O_PATH fd we currently are looking to the caller. It can translate it to a proper fd by + * opening /proc/self/fd/xyz. */ + + assert(fd >= 0); + q = fd; + fd = -1; + + return q; + } + return exists; } diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index a7ba61625d..4dba1ea56a 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -29,6 +29,7 @@ #include <unistd.h> #include "time-util.h" +#include "util.h" int unlink_noerrno(const char *path); @@ -80,22 +81,25 @@ union inotify_event_buffer { int inotify_add_watch_fd(int fd, int what, uint32_t mask); enum { - CHASE_PREFIX_ROOT = 1, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */ - CHASE_NONEXISTENT = 2, /* If set, it's OK if the path doesn't actually exist. */ - CHASE_NO_AUTOFS = 4, /* If set, return -EREMOTE if autofs mount point found */ + CHASE_PREFIX_ROOT = 1U << 0, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */ + CHASE_NONEXISTENT = 1U << 1, /* If set, it's OK if the path doesn't actually exist. */ + CHASE_NO_AUTOFS = 1U << 2, /* If set, return -EREMOTE if autofs mount point found */ + CHASE_SAFE = 1U << 3, /* If set, return EPERM if we ever traverse from unprivileged to privileged files or directories */ + CHASE_OPEN = 1U << 4, /* If set, return an O_PATH object to the final component */ }; int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret); /* Useful for usage with _cleanup_(), removes a directory and frees the pointer */ static inline void rmdir_and_free(char *p) { + PROTECT_ERRNO; (void) rmdir(p); free(p); } DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free); static inline void unlink_and_free(char *p) { - (void) unlink(p); + (void) unlink_noerrno(p); free(p); } DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free); diff --git a/src/shared/gcrypt-util.c b/src/basic/gcrypt-util.c index 1bfb776725..1bfb776725 100644 --- a/src/shared/gcrypt-util.c +++ b/src/basic/gcrypt-util.c diff --git a/src/shared/gcrypt-util.h b/src/basic/gcrypt-util.h index 69faf08e56..69faf08e56 100644 --- a/src/shared/gcrypt-util.h +++ b/src/basic/gcrypt-util.h diff --git a/src/basic/generate-af-list.sh b/src/basic/generate-af-list.sh index 8d9cdd1836..fa74198e58 100755 --- a/src/basic/generate-af-list.sh +++ b/src/basic/generate-af-list.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu $1 -E -dM -include sys/socket.h - </dev/null | \ grep -Ev 'AF_UNSPEC|AF_MAX' | \ diff --git a/src/basic/generate-arphrd-list.sh b/src/basic/generate-arphrd-list.sh index ee207fb38e..e4e7271c4d 100755 --- a/src/basic/generate-arphrd-list.sh +++ b/src/basic/generate-arphrd-list.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu $1 -dM -include net/if_arp.h - </dev/null | \ awk '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \ diff --git a/src/basic/generate-cap-list.sh b/src/basic/generate-cap-list.sh index 1d4a562e7c..0628d2425f 100755 --- a/src/basic/generate-cap-list.sh +++ b/src/basic/generate-cap-list.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu $1 -dM -include linux/capability.h -include "$2" -include "$3" - </dev/null | \ awk '/^#define[ \t]+CAP_[A-Z_]+[ \t]+/ { print $2; }' | \ diff --git a/src/basic/generate-errno-list.sh b/src/basic/generate-errno-list.sh index e2bab8b320..953d5e37b8 100755 --- a/src/basic/generate-errno-list.sh +++ b/src/basic/generate-errno-list.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu $1 -dM -include errno.h - </dev/null | \ awk '/^#define[ \t]+E[^ _]+[ \t]+/ { print $2; }' diff --git a/src/basic/generate-socket-protocol-list.sh b/src/basic/generate-socket-protocol-list.sh new file mode 100755 index 0000000000..a9b1e0fb57 --- /dev/null +++ b/src/basic/generate-socket-protocol-list.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -eu + +$1 -dM -include netinet/in.h - </dev/null | \ + awk '/^#define[ \t]+IPPROTO_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \ + sed -e 's/IPPROTO_//' diff --git a/src/basic/gunicode.c b/src/basic/gunicode.c index e6ac0545a4..8aff4a0fc5 100644 --- a/src/basic/gunicode.c +++ b/src/basic/gunicode.c @@ -4,8 +4,6 @@ * Copyright 2000, 2005 Red Hat, Inc. */ -#include <stdlib.h> - #include "gunicode.h" #define unichar uint32_t diff --git a/src/basic/hash-funcs.c b/src/basic/hash-funcs.c index e69f81558d..5267758769 100644 --- a/src/basic/hash-funcs.c +++ b/src/basic/hash-funcs.c @@ -19,6 +19,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <string.h> + #include "hash-funcs.h" void string_hash_func(const void *p, struct siphash *state) { diff --git a/src/basic/hostname-util.h b/src/basic/hostname-util.h index d837d6f28c..edae52e3db 100644 --- a/src/basic/hostname-util.h +++ b/src/basic/hostname-util.h @@ -21,6 +21,7 @@ ***/ #include <stdbool.h> +#include <stdio.h> #include "macro.h" diff --git a/src/basic/io-util.c b/src/basic/io-util.c index 77c9bdc739..08ad42ed95 100644 --- a/src/basic/io-util.c +++ b/src/basic/io-util.c @@ -33,6 +33,7 @@ int flush_fd(int fd) { .fd = fd, .events = POLLIN, }; + int count = 0; /* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything * read. Note that some file descriptors (notable IP sockets) will trigger POLLIN even when no data can be read @@ -52,7 +53,7 @@ int flush_fd(int fd) { return -errno; } else if (r == 0) - return 0; + return count; l = read(fd, buf, sizeof(buf)); if (l < 0) { @@ -61,11 +62,13 @@ int flush_fd(int fd) { continue; if (errno == EAGAIN) - return 0; + return count; return -errno; } else if (l == 0) - return 0; + return count; + + count += (int) l; } } diff --git a/src/basic/journal-importer.c b/src/basic/journal-importer.c index 6942c370cb..11054589e3 100644 --- a/src/basic/journal-importer.c +++ b/src/basic/journal-importer.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <unistd.h> #include "alloc-util.h" diff --git a/src/basic/label.c b/src/basic/label.c index ce81d286ab..18c9a23fea 100644 --- a/src/basic/label.c +++ b/src/basic/label.c @@ -22,6 +22,7 @@ #include <sys/stat.h> #include <unistd.h> +#include "btrfs-util.h" #include "label.h" #include "macro.h" #include "selinux-util.h" @@ -41,16 +42,17 @@ int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { return 0; } -int mkdir_label(const char *path, mode_t mode) { +int symlink_label(const char *old_path, const char *new_path) { int r; - assert(path); + assert(old_path); + assert(new_path); - r = mac_selinux_create_file_prepare(path, S_IFDIR); + r = mac_selinux_create_file_prepare(new_path, S_IFLNK); if (r < 0) return r; - if (mkdir(path, mode) < 0) + if (symlink(old_path, new_path) < 0) r = -errno; mac_selinux_create_file_clear(); @@ -58,26 +60,23 @@ int mkdir_label(const char *path, mode_t mode) { if (r < 0) return r; - return mac_smack_fix(path, false, false); + return mac_smack_fix(new_path, false, false); } -int symlink_label(const char *old_path, const char *new_path) { +int btrfs_subvol_make_label(const char *path) { int r; - assert(old_path); - assert(new_path); + assert(path); - r = mac_selinux_create_file_prepare(new_path, S_IFLNK); + r = mac_selinux_create_file_prepare(path, S_IFDIR); if (r < 0) return r; - if (symlink(old_path, new_path) < 0) - r = -errno; - + r = btrfs_subvol_make(path); mac_selinux_create_file_clear(); if (r < 0) return r; - return mac_smack_fix(new_path, false, false); + return mac_smack_fix(path, false, false); } diff --git a/src/basic/label.h b/src/basic/label.h index 86447c2e98..d73dacec4f 100644 --- a/src/basic/label.h +++ b/src/basic/label.h @@ -27,3 +27,5 @@ int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs); int mkdir_label(const char *path, mode_t mode); int symlink_label(const char *old_path, const char *new_path); + +int btrfs_subvol_make_label(const char *path); diff --git a/src/basic/locale-util.h b/src/basic/locale-util.h index 60ce017a15..f75dcbc3d1 100644 --- a/src/basic/locale-util.h +++ b/src/basic/locale-util.h @@ -22,6 +22,7 @@ #include <libintl.h> #include <stdbool.h> +#include <locale.h> #include "macro.h" @@ -75,3 +76,10 @@ LocaleVariable locale_variable_from_string(const char *s) _pure_; int get_keymaps(char ***l); bool keymap_is_valid(const char *name); + +static inline void freelocalep(locale_t *p) { + if (*p == (locale_t) 0) + return; + + freelocale(*p); +} diff --git a/src/basic/log.c b/src/basic/log.c index 20d9588e2f..12ee65a5c3 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -54,6 +54,7 @@ #include "syslog-util.h" #include "terminal-util.h" #include "time-util.h" +#include "utf8.h" #include "util.h" #define SNDBUF_SIZE (8*1024*1024) @@ -76,40 +77,40 @@ static bool show_location = false; static bool upgrade_syslog_to_journal = false; static bool always_reopen_console = false; static bool open_when_needed = false; +static bool prohibit_ipc = false; /* Akin to glibc's __abort_msg; which is private and we hence cannot * use here. */ static char *log_abort_msg = NULL; -void log_close_console(void) { +static void log_close_console(void) { if (console_fd < 0) return; - if (getpid_cached() == 1) { - if (console_fd >= 3) - safe_close(console_fd); + if (console_fd >= 3) + safe_close(console_fd); - console_fd = -1; - } + console_fd = -1; } static int log_open_console(void) { - if (console_fd >= 0) + if (!always_reopen_console) { + console_fd = STDERR_FILENO; return 0; + } - if (always_reopen_console) { + if (console_fd < 3) { console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); if (console_fd < 0) return console_fd; - } else - console_fd = STDERR_FILENO; + } return 0; } -void log_close_kmsg(void) { +static void log_close_kmsg(void) { kmsg_fd = safe_close(kmsg_fd); } @@ -125,7 +126,7 @@ static int log_open_kmsg(void) { return 0; } -void log_close_syslog(void) { +static void log_close_syslog(void) { syslog_fd = safe_close(syslog_fd); } @@ -197,7 +198,7 @@ fail: return r; } -void log_close_journal(void) { +static void log_close_journal(void) { journal_fd = safe_close(journal_fd); } @@ -239,7 +240,8 @@ int log_open(void) { /* If we don't use the console we close it here, to not get * killed by SAK. If we don't use syslog we close it here so * that we are not confused by somebody deleting the socket in - * the fs. If we don't use /dev/kmsg we still keep it open, + * the fs, and to make sure we don't use it if prohibit_ipc is + * set. If we don't use /dev/kmsg we still keep it open, * because there is no reason to close it. */ if (log_target == LOG_TARGET_NULL) { @@ -249,11 +251,12 @@ int log_open(void) { return 0; } - if (!IN_SET(log_target, LOG_TARGET_AUTO, LOG_TARGET_SAFE) || + if (log_target != LOG_TARGET_AUTO || getpid_cached() == 1 || isatty(STDERR_FILENO) <= 0) { - if (IN_SET(log_target, LOG_TARGET_AUTO, + if (!prohibit_ipc && + IN_SET(log_target, LOG_TARGET_AUTO, LOG_TARGET_JOURNAL_OR_KMSG, LOG_TARGET_JOURNAL)) { r = log_open_journal(); @@ -264,7 +267,8 @@ int log_open(void) { } } - if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG, + if (!prohibit_ipc && + IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG, LOG_TARGET_SYSLOG)) { r = log_open_syslog(); if (r >= 0) { @@ -275,7 +279,6 @@ int log_open(void) { } if (IN_SET(log_target, LOG_TARGET_AUTO, - LOG_TARGET_SAFE, LOG_TARGET_JOURNAL_OR_KMSG, LOG_TARGET_SYSLOG_OR_KMSG, LOG_TARGET_KMSG)) { @@ -627,7 +630,6 @@ int log_dispatch_internal( if (k <= 0 && IN_SET(log_target, LOG_TARGET_AUTO, - LOG_TARGET_SAFE, LOG_TARGET_SYSLOG_OR_KMSG, LOG_TARGET_JOURNAL_OR_KMSG, LOG_TARGET_KMSG)) { @@ -1219,17 +1221,18 @@ static const char *const log_target_table[_LOG_TARGET_MAX] = { [LOG_TARGET_SYSLOG] = "syslog", [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg", [LOG_TARGET_AUTO] = "auto", - [LOG_TARGET_SAFE] = "safe", - [LOG_TARGET_NULL] = "null" + [LOG_TARGET_NULL] = "null", }; DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget); void log_received_signal(int level, const struct signalfd_siginfo *si) { - if (si->ssi_pid > 0) { + assert(si); + + if (pid_is_valid(si->ssi_pid)) { _cleanup_free_ char *p = NULL; - get_process_comm(si->ssi_pid, &p); + (void) get_process_comm(si->ssi_pid, &p); log_full(level, "Received SIG%s from PID %"PRIu32" (%s).", @@ -1239,7 +1242,6 @@ void log_received_signal(int level, const struct signalfd_siginfo *si) { log_full(level, "Received SIG%s.", signal_to_string(si->ssi_signo)); - } int log_syntax_internal( @@ -1289,8 +1291,37 @@ int log_syntax_internal( NULL); } +int log_syntax_invalid_utf8_internal( + const char *unit, + int level, + const char *config_file, + unsigned config_line, + const char *file, + int line, + const char *func, + const char *rvalue) { + + _cleanup_free_ char *p = NULL; + + if (rvalue) + p = utf8_escape_invalid(rvalue); + + log_syntax_internal(unit, level, config_file, config_line, 0, file, line, func, + "String is not UTF-8 clean, ignoring assignment: %s", strna(p)); + + return -EINVAL; +} + void log_set_upgrade_syslog_to_journal(bool b) { upgrade_syslog_to_journal = b; + + /* Make the change effective immediately */ + if (b) { + if (log_target == LOG_TARGET_SYSLOG) + log_target = LOG_TARGET_JOURNAL; + else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG) + log_target = LOG_TARGET_JOURNAL_OR_KMSG; + } } void log_set_always_reopen_console(bool b) { @@ -1300,3 +1331,14 @@ void log_set_always_reopen_console(bool b) { void log_set_open_when_needed(bool b) { open_when_needed = b; } + +void log_set_prohibit_ipc(bool b) { + prohibit_ipc = b; +} + +int log_emergency_level(void) { + /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only + * then the system of the whole system is obviously affected. */ + + return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR; +} diff --git a/src/basic/log.h b/src/basic/log.h index aa5976c3c0..5b5a25bd6d 100644 --- a/src/basic/log.h +++ b/src/basic/log.h @@ -20,18 +20,16 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <errno.h> #include <stdarg.h> #include <stdbool.h> #include <stdlib.h> -#include <sys/signalfd.h> -#include <sys/socket.h> #include <syslog.h> -#include "sd-id128.h" - #include "macro.h" -#include "process-util.h" + +/* Some structures we reference but don't want to pull in headers for */ +struct iovec; +struct signalfd_siginfo; typedef enum LogRealm { LOG_REALM_SYSTEMD, @@ -52,7 +50,6 @@ typedef enum LogTarget{ LOG_TARGET_SYSLOG, LOG_TARGET_SYSLOG_OR_KMSG, LOG_TARGET_AUTO, /* console if stderr is tty, JOURNAL_OR_KMSG otherwise */ - LOG_TARGET_SAFE, /* console if stderr is tty, KMSG otherwise */ LOG_TARGET_NULL, _LOG_TARGET_MAX, _LOG_TARGET_INVALID = -1 @@ -97,11 +94,6 @@ int log_open(void); void log_close(void); void log_forget_fds(void); -void log_close_syslog(void); -void log_close_journal(void); -void log_close_kmsg(void); -void log_close_console(void); - void log_parse_environment_realm(LogRealm realm); #define log_parse_environment() \ log_parse_environment_realm(LOG_REALM) @@ -194,7 +186,7 @@ int log_struct_iovec_internal( const char *file, int line, const char *func, - const struct iovec input_iovec[], + const struct iovec *input_iovec, size_t n_input_iovec); /* This modifies the buffer passed! */ @@ -240,9 +232,9 @@ void log_assert_failed_return_realm( /* Logging with level */ #define log_full_errno_realm(realm, level, error, ...) \ ({ \ - int _level = (level), _e = (error); \ - (log_get_max_level_realm((realm)) >= LOG_PRI(_level)) \ - ? log_internal_realm(LOG_REALM_PLUS_LEVEL((realm), _level), _e, \ + int _level = (level), _e = (error), _realm = (realm); \ + (log_get_max_level_realm(_realm) >= LOG_PRI(_level)) \ + ? log_internal_realm(LOG_REALM_PLUS_LEVEL(_realm, _level), _e, \ __FILE__, __LINE__, __func__, __VA_ARGS__) \ : -abs(_e); \ }) @@ -252,13 +244,15 @@ void log_assert_failed_return_realm( #define log_full(level, ...) log_full_errno((level), 0, __VA_ARGS__) +int log_emergency_level(void); + /* Normal logging */ #define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__) #define log_info(...) log_full(LOG_INFO, __VA_ARGS__) #define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__) #define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__) #define log_error(...) log_full(LOG_ERR, __VA_ARGS__) -#define log_emergency(...) log_full(getpid_cached() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__) +#define log_emergency(...) log_full(log_emergency_level(), __VA_ARGS__) /* Logging triggered by an errno-like error */ #define log_debug_errno(error, ...) log_full_errno(LOG_DEBUG, error, __VA_ARGS__) @@ -266,7 +260,7 @@ void log_assert_failed_return_realm( #define log_notice_errno(error, ...) log_full_errno(LOG_NOTICE, error, __VA_ARGS__) #define log_warning_errno(error, ...) log_full_errno(LOG_WARNING, error, __VA_ARGS__) #define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__) -#define log_emergency_errno(error, ...) log_full_errno(getpid_cached() == 1 ? LOG_EMERG : LOG_ERR, error, __VA_ARGS__) +#define log_emergency_errno(error, ...) log_full_errno(log_emergency_level(), error, __VA_ARGS__) #ifdef LOG_TRACE # define log_trace(...) log_debug(__VA_ARGS__) @@ -302,10 +296,20 @@ LogTarget log_target_from_string(const char *s) _pure_; void log_received_signal(int level, const struct signalfd_siginfo *si); +/* If turned on, any requests for a log target involving "syslog" will be implicitly upgraded to the equivalent journal target */ void log_set_upgrade_syslog_to_journal(bool b); + +/* If turned on, and log_open() is called, we'll not use STDERR_FILENO for logging ever, but rather open /dev/console */ void log_set_always_reopen_console(bool b); + +/* If turned on, we'll open the log stream implicitly if needed on each individual log call. This is normally not + * desired as we want to reuse our logging streams. It is useful however */ void log_set_open_when_needed(bool b); +/* If turned on, then we'll never use IPC-based logging, i.e. never log to syslog or the journal. We'll only log to + * stderr, the console or kmsg */ +void log_set_prohibit_ipc(bool b); + int log_syntax_internal( const char *unit, int level, @@ -317,6 +321,16 @@ int log_syntax_internal( const char *func, const char *format, ...) _printf_(9, 10); +int log_syntax_invalid_utf8_internal( + const char *unit, + int level, + const char *config_file, + unsigned config_line, + const char *file, + int line, + const char *func, + const char *rvalue); + #define log_syntax(unit, level, config_file, config_line, error, ...) \ ({ \ int _level = (level), _e = (error); \ @@ -328,10 +342,9 @@ int log_syntax_internal( #define log_syntax_invalid_utf8(unit, level, config_file, config_line, rvalue) \ ({ \ int _level = (level); \ - if (log_get_max_level() >= LOG_PRI(_level)) { \ - _cleanup_free_ char *_p = NULL; \ - _p = utf8_escape_invalid(rvalue); \ - log_syntax_internal(unit, _level, config_file, config_line, 0, __FILE__, __LINE__, __func__, \ - "String is not UTF-8 clean, ignoring assignment: %s", strna(_p)); \ - } \ + (log_get_max_level() >= LOG_PRI(_level)) \ + ? log_syntax_invalid_utf8_internal(unit, _level, config_file, config_line, __FILE__, __LINE__, __func__, rvalue) \ + : -EINVAL; \ }) + +#define DEBUG_LOGGING _unlikely_(log_get_max_level() >= LOG_DEBUG) diff --git a/src/basic/macro.h b/src/basic/macro.h index 02d22de833..89bdd852a9 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -139,11 +139,17 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL)); } +#ifndef __COVERITY__ +# define VOID_0 ((void)0) +#else +# define VOID_0 ((void*)0) +#endif + #define ELEMENTSOF(x) \ __extension__ (__builtin_choose_expr( \ !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \ sizeof(x)/sizeof((x)[0]), \ - (void)0)) + VOID_0)) /* * STRLEN - return the length of a string literal, minus the trailing NUL byte. @@ -181,7 +187,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { __builtin_constant_p(_B) && \ __builtin_types_compatible_p(typeof(_A), typeof(_B)), \ ((_A) > (_B)) ? (_A) : (_B), \ - (void)0)) + VOID_0)) /* takes two types and returns the size of the larger one */ #define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; })) diff --git a/src/basic/meson.build b/src/basic/meson.build index a37e279e57..44cd31ecbe 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -15,7 +15,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with systemd; If not, see <http://www.gnu.org/licenses/>. -basic_sources_plain = files(''' +basic_sources = files(''' MurmurHash2.c MurmurHash2.h af-list.c @@ -35,6 +35,8 @@ basic_sources_plain = files(''' bitmap.c bitmap.h blkid-util.h + blockdev-util.c + blockdev-util.h bpf-program.c bpf-program.h btrfs-ctree.h @@ -148,6 +150,8 @@ basic_sources_plain = files(''' proc-cmdline.h process-util.c process-util.h + procfs-util.c + procfs-util.h random-util.c random-util.h ratelimit.c @@ -176,6 +180,8 @@ basic_sources_plain = files(''' smack-util.c smack-util.h socket-label.c + socket-protocol-list.c + socket-protocol-list.h socket-util.c socket-util.h sparse-endian.h @@ -201,10 +207,10 @@ basic_sources_plain = files(''' time-util.h umask-util.h unaligned.h - unit-name.c - unit-name.h unit-def.c unit-def.h + unit-name.c + unit-name.h user-util.c user-util.h utf8.c @@ -255,11 +261,19 @@ errno_list_txt = custom_target( command : [generate_errno_list, cpp], capture : true) +generate_socket_protocol_list = find_program('generate-socket-protocol-list.sh') +socket_protocol_list_txt = custom_target( + 'socket-protocol-list.txt', + output : 'socket-protocol-list.txt', + command : [generate_socket_protocol_list, cpp], + capture : true) + generated_gperf_headers = [] foreach item : [['af', af_list_txt, 'af', ''], ['arphrd', arphrd_list_txt, 'arphrd', 'ARPHRD_'], ['cap', cap_list_txt, 'capability', ''], - ['errno', errno_list_txt, 'errno', '']] + ['errno', errno_list_txt, 'errno', ''], + ['socket-protocol', socket_protocol_list_txt, 'socket_protocol', 'IPPROTO_']] fname = '@0@-from-name.gperf'.format(item[0]) gperf_file = custom_target( @@ -294,7 +308,7 @@ foreach item : [['af', af_list_txt, 'af', ''], generated_gperf_headers += [target1, target2] endforeach -basic_sources = basic_sources_plain + [missing_h] + generated_gperf_headers +basic_sources += [missing_h] + generated_gperf_headers libbasic = static_library( 'basic', @@ -303,6 +317,16 @@ libbasic = static_library( dependencies : [threads, libcap, libblkid, - libselinux, - ], + libselinux], + c_args : ['-fvisibility=default'], install : false) + +# A convenience library that is separate from libbasic to avoid +# unnecessary linking to libgcrypt. +libbasic_gcrypt = static_library( + 'basic-gcrypt', + 'gcrypt-util.c', + 'gcrypt-util.h', + include_directories : includes, + dependencies : [libgcrypt], + c_args : ['-fvisibility=default']) diff --git a/src/basic/missing.h b/src/basic/missing.h index 790f9f55a5..1280e6c410 100644 --- a/src/basic/missing.h +++ b/src/basic/missing.h @@ -206,6 +206,32 @@ struct sockaddr_vm { #endif #if ! HAVE_LINUX_BTRFS_H +#define BTRFS_IOC_QGROUP_ASSIGN _IOW(BTRFS_IOCTL_MAGIC, 41, \ + struct btrfs_ioctl_qgroup_assign_args) +#define BTRFS_IOC_QGROUP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 42, \ + struct btrfs_ioctl_qgroup_create_args) +#define BTRFS_IOC_QUOTA_RESCAN _IOW(BTRFS_IOCTL_MAGIC, 44, \ + struct btrfs_ioctl_quota_rescan_args) +#define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \ + struct btrfs_ioctl_quota_rescan_args) + +struct btrfs_ioctl_quota_rescan_args { + __u64 flags; + __u64 progress; + __u64 reserved[6]; +}; + +struct btrfs_ioctl_qgroup_assign_args { + __u64 assign; + __u64 src; + __u64 dst; +}; + +struct btrfs_ioctl_qgroup_create_args { + __u64 create; + __u64 qgroupid; +}; + struct btrfs_ioctl_vol_args { int64_t fd; char name[BTRFS_PATH_NAME_MAX + 1]; @@ -543,6 +569,38 @@ struct btrfs_ioctl_quota_ctl_args { #define PR_SET_CHILD_SUBREAPER 36 #endif +#ifndef PR_SET_MM_ARG_START +#define PR_SET_MM_ARG_START 8 +#endif + +#ifndef PR_SET_MM_ARG_END +#define PR_SET_MM_ARG_END 9 +#endif + +#ifndef PR_SET_MM_ENV_START +#define PR_SET_MM_ENV_START 10 +#endif + +#ifndef PR_SET_MM_ENV_END +#define PR_SET_MM_ENV_END 11 +#endif + +#ifndef EFIVARFS_MAGIC +#define EFIVARFS_MAGIC 0xde5e81e4 +#endif + +#ifndef SMACK_MAGIC +#define SMACK_MAGIC 0x43415d53 +#endif + +#ifndef DM_DEFERRED_REMOVE +#define DM_DEFERRED_REMOVE (1 << 17) +#endif + +#ifndef MAX_HANDLE_SZ +#define MAX_HANDLE_SZ 128 +#endif + #if ! HAVE_SECURE_GETENV # if HAVE___SECURE_GETENV # define secure_getenv __secure_getenv @@ -563,6 +621,10 @@ struct btrfs_ioctl_quota_ctl_args { # define SO_REUSEPORT 15 #endif +#ifndef SO_PEERGROUPS +# define SO_PEERGROUPS 59 +#endif + #ifndef EVIOCREVOKE # define EVIOCREVOKE _IOW('E', 0x91, int) #endif @@ -653,18 +715,28 @@ struct input_mask { #define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1) #endif -#if !HAVE_IFLA_IPVLAN_MODE +#if !HAVE_IFLA_IPVLAN_FLAGS #define IFLA_IPVLAN_UNSPEC 0 #define IFLA_IPVLAN_MODE 1 -#define __IFLA_IPVLAN_MAX 2 +#define IFLA_IPVLAN_FLAGS 2 +#define __IFLA_IPVLAN_MAX 3 #define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1) #define IPVLAN_MODE_L2 0 #define IPVLAN_MODE_L3 1 +#define IPVLAN_MODE_L3S 2 #define IPVLAN_MAX 2 #endif +#if !HAVE_IPVLAN_F_PRIVATE +#define IPVLAN_F_PRIVATE 0x01 +#define IPVLAN_F_VEPA 0x02 +#define __IPVLAN_F_PRIVATE_MAX 3 + +#define HAVE_IPVLAN_F_PRIVATE_MAX (__HAVE_IPVLAN_F_PRIVATE_MAX - 1) +#endif + #if !HAVE_IFLA_VTI_REMOTE #define IFLA_VTI_UNSPEC 0 #define IFLA_VTI_LINK 1 diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h index fd82c11e94..c938d0d976 100644 --- a/src/basic/missing_syscall.h +++ b/src/basic/missing_syscall.h @@ -330,10 +330,14 @@ static inline ssize_t copy_file_range(int fd_in, loff_t *off_in, # define __NR_bpf 321 # elif defined __aarch64__ # define __NR_bpf 280 +# elif defined __arm__ +# define __NR_bpf 386 # elif defined __sparc__ # define __NR_bpf 349 # elif defined __s390__ # define __NR_bpf 351 +# elif defined __tilegx__ +# define __NR_bpf 280 # else # warning "__NR_bpf not defined for your architecture" # endif diff --git a/src/basic/mkdir-label.c b/src/basic/mkdir-label.c index 16eb7ce265..6f3a46f467 100644 --- a/src/basic/mkdir-label.c +++ b/src/basic/mkdir-label.c @@ -20,11 +20,32 @@ ***/ #include <stdio.h> +#include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include "label.h" +#include "macro.h" #include "mkdir.h" +#include "selinux-util.h" +#include "smack-util.h" + +int mkdir_label(const char *path, mode_t mode) { + int r; + + assert(path); + + r = mac_selinux_create_file_prepare(path, S_IFDIR); + if (r < 0) + return r; + + r = mkdir_errno_wrapper(path, mode); + mac_selinux_create_file_clear(); + if (r < 0) + return r; + + return mac_smack_fix(path, false, false); +} int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink) { return mkdir_safe_internal(path, mode, uid, gid, follow_symlink, mkdir_label); diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c index 4386b38c4a..de4746c867 100644 --- a/src/basic/mkdir.c +++ b/src/basic/mkdir.c @@ -35,6 +35,8 @@ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, boo struct stat st; int r; + assert(_mkdir != mkdir); + if (_mkdir(path, mode) >= 0) { r = chmod_and_chown(path, mode, uid, gid); if (r < 0) @@ -68,8 +70,14 @@ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, boo return 0; } +int mkdir_errno_wrapper(const char *pathname, mode_t mode) { + if (mkdir(pathname, mode) < 0) + return -errno; + return 0; +} + int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink) { - return mkdir_safe_internal(path, mode, uid, gid, follow_symlink, mkdir); + return mkdir_safe_internal(path, mode, uid, gid, follow_symlink, mkdir_errno_wrapper); } int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) { @@ -77,6 +85,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mk int r; assert(path); + assert(_mkdir != mkdir); if (prefix && !path_startswith(path, prefix)) return -ENOTDIR; @@ -104,8 +113,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mk e = p + strcspn(p, "/"); p = e + strspn(e, "/"); - /* Is this the last component? If so, then we're - * done */ + /* Is this the last component? If so, then we're done */ if (*p == 0) return 0; @@ -116,13 +124,13 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mk continue; r = _mkdir(t, mode); - if (r < 0 && errno != EEXIST) - return -errno; + if (r < 0 && r != -EEXIST) + return r; } } int mkdir_parents(const char *path, mode_t mode) { - return mkdir_parents_internal(NULL, path, mode, mkdir); + return mkdir_parents_internal(NULL, path, mode, mkdir_errno_wrapper); } int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) { @@ -130,17 +138,19 @@ int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_fu /* Like mkdir -p */ + assert(_mkdir != mkdir); + r = mkdir_parents_internal(prefix, path, mode, _mkdir); if (r < 0) return r; r = _mkdir(path, mode); - if (r < 0 && (errno != EEXIST || is_dir(path, true) <= 0)) - return -errno; + if (r < 0 && (r != -EEXIST || is_dir(path, true) <= 0)) + return r; return 0; } int mkdir_p(const char *path, mode_t mode) { - return mkdir_p_internal(NULL, path, mode, mkdir); + return mkdir_p_internal(NULL, path, mode, mkdir_errno_wrapper); } diff --git a/src/basic/mkdir.h b/src/basic/mkdir.h index 04a537f8a8..d6c2d579a3 100644 --- a/src/basic/mkdir.h +++ b/src/basic/mkdir.h @@ -23,6 +23,7 @@ #include <sys/types.h> +int mkdir_errno_wrapper(const char *pathname, mode_t mode); int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink); int mkdir_parents(const char *path, mode_t mode); int mkdir_p(const char *path, mode_t mode); diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index d03f60e01a..2c22753dea 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -28,6 +28,7 @@ #include "alloc-util.h" #include "errno-list.h" #include "extract-word.h" +#include "locale-util.h" #include "macro.h" #include "parse-util.h" #include "process-util.h" @@ -83,7 +84,7 @@ int parse_mode(const char *s, mode_t *ret) { l = strtol(s, &x, 8); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (l < 0 || l > 07777) return -ERANGE; @@ -283,7 +284,8 @@ int parse_errno(const char *t) { if (r < 0) return r; - if (e < 0 || e > ERRNO_MAX) + /* 0 is also allowed here */ + if (!errno_is_valid(e) && e != 0) return -ERANGE; return e; @@ -390,7 +392,7 @@ int safe_atou(const char *s, unsigned *ret_u) { l = strtoul(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (s[0] == '-') return -ERANGE; @@ -412,7 +414,7 @@ int safe_atoi(const char *s, int *ret_i) { l = strtol(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if ((long) (int) l != l) return -ERANGE; @@ -434,7 +436,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) { l = strtoull(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (*s == '-') return -ERANGE; @@ -454,7 +456,7 @@ int safe_atolli(const char *s, long long int *ret_lli) { l = strtoll(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; *ret_lli = l; @@ -474,7 +476,7 @@ int safe_atou8(const char *s, uint8_t *ret) { l = strtoul(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (s[0] == '-') return -ERANGE; @@ -498,7 +500,7 @@ int safe_atou16(const char *s, uint16_t *ret) { l = strtoul(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (s[0] == '-') return -ERANGE; @@ -520,7 +522,7 @@ int safe_atoi16(const char *s, int16_t *ret) { l = strtol(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if ((long) (int16_t) l != l) return -ERANGE; @@ -530,9 +532,9 @@ int safe_atoi16(const char *s, int16_t *ret) { } int safe_atod(const char *s, double *ret_d) { + _cleanup_(freelocalep) locale_t loc = (locale_t) 0; char *x = NULL; double d = 0; - locale_t loc; assert(s); assert(ret_d); @@ -543,16 +545,11 @@ int safe_atod(const char *s, double *ret_d) { errno = 0; d = strtod_l(s, &x, loc); - if (errno > 0) { - freelocale(loc); + if (errno > 0) return -errno; - } - if (!x || x == s || *x) { - freelocale(loc); + if (!x || x == s || *x != 0) return -EINVAL; - } - freelocale(loc); *ret_d = (double) d; return 0; } @@ -595,19 +592,20 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) { int parse_percent_unbounded(const char *p) { const char *pc, *n; - unsigned v; - int r; + int r, v; pc = endswith(p, "%"); if (!pc) return -EINVAL; n = strndupa(p, pc - p); - r = safe_atou(n, &v); + r = safe_atoi(n, &v); if (r < 0) return r; + if (v < 0) + return -ERANGE; - return (int) v; + return v; } int parse_percent(const char *p) { diff --git a/src/basic/path-util.c b/src/basic/path-util.c index ab4778d4ed..df94629385 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -81,14 +81,36 @@ char *path_make_absolute(const char *p, const char *prefix) { /* Makes every item in the list an absolute path by prepending * the prefix, if specified and necessary */ - if (path_is_absolute(p) || !prefix) + if (path_is_absolute(p) || isempty(prefix)) return strdup(p); - return strjoin(prefix, "/", p); + if (endswith(prefix, "/")) + return strjoin(prefix, p); + else + return strjoin(prefix, "/", p); +} + +int safe_getcwd(char **ret) { + char *cwd; + + cwd = get_current_dir_name(); + if (!cwd) + return negative_errno(); + + /* Let's make sure the directory is really absolute, to protect us from the logic behind + * CVE-2018-1000001 */ + if (cwd[0] != '/') { + free(cwd); + return -ENOMEDIUM; + } + + *ret = cwd; + return 0; } int path_make_absolute_cwd(const char *p, char **ret) { char *c; + int r; assert(p); assert(ret); @@ -101,11 +123,14 @@ int path_make_absolute_cwd(const char *p, char **ret) { else { _cleanup_free_ char *cwd = NULL; - cwd = get_current_dir_name(); - if (!cwd) - return negative_errno(); + r = safe_getcwd(&cwd); + if (r < 0) + return r; - c = strjoin(cwd, "/", p); + if (endswith(cwd, "/")) + c = strjoin(cwd, p); + else + c = strjoin(cwd, "/", p); } if (!c) return -ENOMEM; diff --git a/src/basic/path-util.h b/src/basic/path-util.h index f79cdf928e..89c285e076 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -41,6 +41,7 @@ bool is_path(const char *p) _pure_; int path_split_and_make_absolute(const char *p, char ***ret); bool path_is_absolute(const char *p) _pure_; char* path_make_absolute(const char *p, const char *prefix); +int safe_getcwd(char **ret); int path_make_absolute_cwd(const char *p, char **ret); int path_make_relative(const char *from_dir, const char *to_path, char **_r); char* path_kill_slashes(char *path); diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 17c94f44a0..dc7c9ef9ef 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -56,6 +56,7 @@ #include "stat-util.h" #include "string-table.h" #include "string-util.h" +#include "terminal-util.h" #include "user-util.h" #include "util.h" @@ -296,10 +297,17 @@ int rename_process(const char name[]) { if (isempty(name)) return -EINVAL; /* let's not confuse users unnecessarily with an empty name */ + if (!is_main_thread()) + return -EPERM; /* Let's not allow setting the process name from other threads than the main one, as we + * cache things without locking, and we make assumptions that PR_SET_NAME sets the + * process name that isn't correct on any other threads */ + l = strlen(name); - /* First step, change the comm field. */ - (void) prctl(PR_SET_NAME, name); + /* First step, change the comm field. The main thread's comm is identical to the process comm. This means we + * can use PR_SET_NAME, which sets the thread name for the calling thread. */ + if (prctl(PR_SET_NAME, name) < 0) + log_debug_errno(errno, "PR_SET_NAME failed: %m"); if (l > 15) /* Linux process names can be 15 chars at max */ truncated = true; @@ -679,32 +687,43 @@ int wait_for_terminate(pid_t pid, siginfo_t *status) { * A warning is emitted if the process terminates abnormally, * and also if it returns non-zero unless check_exit_code is true. */ -int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code) { - int r; +int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) { + _cleanup_free_ char *buffer = NULL; siginfo_t status; + int r, prio; - assert(name); assert(pid > 1); + if (!name) { + r = get_process_comm(pid, &buffer); + if (r < 0) + log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pid); + else + name = buffer; + } + + prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG; + r = wait_for_terminate(pid, &status); if (r < 0) - return log_warning_errno(r, "Failed to wait for %s: %m", name); + return log_full_errno(prio, r, "Failed to wait for %s: %m", strna(name)); if (status.si_code == CLD_EXITED) { - if (status.si_status != 0) - log_full(check_exit_code ? LOG_WARNING : LOG_DEBUG, - "%s failed with error code %i.", name, status.si_status); + if (status.si_status != EXIT_SUCCESS) + log_full(flags & WAIT_LOG_NON_ZERO_EXIT_STATUS ? LOG_ERR : LOG_DEBUG, + "%s failed with exit status %i.", strna(name), status.si_status); else log_debug("%s succeeded.", name); return status.si_status; + } else if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED)) { - log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status)); + log_full(prio, "%s terminated by signal %s.", strna(name), signal_to_string(status.si_status)); return -EPROTO; } - log_warning("%s failed due to unknown reason.", name); + log_full(prio, "%s failed due to unknown reason.", strna(name)); return -EPROTO; } @@ -777,6 +796,8 @@ void sigkill_wait(pid_t pid) { } void sigkill_waitp(pid_t *pid) { + PROTECT_ERRNO; + if (!pid) return; if (*pid <= 1) @@ -928,6 +949,17 @@ noreturn void freeze(void) { sync(); + /* Let's not freeze right away, but keep reaping zombies. */ + for (;;) { + int r; + siginfo_t si = {}; + + r = waitid(P_ALL, 0, &si, WEXITED); + if (r < 0 && errno != EINTR) + break; + } + + /* waitid() failed with an unexpected error, things are really borked. Freeze now! */ for (;;) pause(); } @@ -1075,7 +1107,7 @@ int ioprio_parse_priority(const char *s, int *ret) { static pid_t cached_pid = CACHED_PID_UNSET; -static void reset_cached_pid(void) { +void reset_cached_pid(void) { /* Invoked in the child after a fork(), i.e. at the first moment the PID changed */ cached_pid = CACHED_PID_UNSET; } @@ -1134,6 +1166,244 @@ int must_be_root(void) { return -EPERM; } +int safe_fork_full( + const char *name, + const int except_fds[], + size_t n_except_fds, + ForkFlags flags, + pid_t *ret_pid) { + + pid_t original_pid, pid; + sigset_t saved_ss, ss; + bool block_signals = false; + int prio, r; + + /* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always + * returns the child's PID in *ret_pid. Returns == 0 in the child, and > 0 in the parent. */ + + prio = flags & FORK_LOG ? LOG_ERR : LOG_DEBUG; + + original_pid = getpid_cached(); + + if (flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG)) { + + /* We temporarily block all signals, so that the new child has them blocked initially. This way, we can + * be sure that SIGTERMs are not lost we might send to the child. */ + + if (sigfillset(&ss) < 0) + return log_full_errno(prio, errno, "Failed to reset signal set: %m"); + + block_signals = true; + + } else if (flags & FORK_WAIT) { + + /* Let's block SIGCHLD at least, so that we can safely watch for the child process */ + + if (sigemptyset(&ss) < 0) + return log_full_errno(prio, errno, "Failed to clear signal set: %m"); + + if (sigaddset(&ss, SIGCHLD) < 0) + return log_full_errno(prio, errno, "Failed to add SIGCHLD to signal set: %m"); + + block_signals = true; + } + + if (block_signals) + if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0) + return log_full_errno(prio, errno, "Failed to set signal mask: %m"); + + if (flags & FORK_NEW_MOUNTNS) + pid = raw_clone(SIGCHLD|CLONE_NEWNS); + else + pid = fork(); + if (pid < 0) { + r = -errno; + + if (block_signals) /* undo what we did above */ + (void) sigprocmask(SIG_SETMASK, &saved_ss, NULL); + + return log_full_errno(prio, r, "Failed to fork: %m"); + } + if (pid > 0) { + /* We are in the parent process */ + + log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid); + + if (flags & FORK_WAIT) { + r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0)); + if (r < 0) + return r; + if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */ + return -EPROTO; + } + + if (block_signals) /* undo what we did above */ + (void) sigprocmask(SIG_SETMASK, &saved_ss, NULL); + + if (ret_pid) + *ret_pid = pid; + + return 1; + } + + /* We are in the child process */ + + if (flags & FORK_REOPEN_LOG) { + /* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */ + log_close(); + log_set_open_when_needed(true); + } + + if (name) { + r = rename_process(name); + if (r < 0) + log_full_errno(flags & FORK_LOG ? LOG_WARNING : LOG_DEBUG, + r, "Failed to rename process, ignoring: %m"); + } + + if (flags & FORK_DEATHSIG) + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) { + log_full_errno(prio, errno, "Failed to set death signal: %m"); + _exit(EXIT_FAILURE); + } + + if (flags & FORK_RESET_SIGNALS) { + r = reset_all_signal_handlers(); + if (r < 0) { + log_full_errno(prio, r, "Failed to reset signal handlers: %m"); + _exit(EXIT_FAILURE); + } + + /* This implicitly undoes the signal mask stuff we did before the fork()ing above */ + r = reset_signal_mask(); + if (r < 0) { + log_full_errno(prio, r, "Failed to reset signal mask: %m"); + _exit(EXIT_FAILURE); + } + } else if (block_signals) { /* undo what we did above */ + if (sigprocmask(SIG_SETMASK, &saved_ss, NULL) < 0) { + log_full_errno(prio, errno, "Failed to restore signal mask: %m"); + _exit(EXIT_FAILURE); + } + } + + if (flags & FORK_DEATHSIG) { + pid_t ppid; + /* Let's see if the parent PID is still the one we started from? If not, then the parent + * already died by the time we set PR_SET_PDEATHSIG, hence let's emulate the effect */ + + ppid = getppid(); + if (ppid == 0) + /* Parent is in a differn't PID namespace. */; + else if (ppid != original_pid) { + log_debug("Parent died early, raising SIGTERM."); + (void) raise(SIGTERM); + _exit(EXIT_FAILURE); + } + } + + if (flags & FORK_CLOSE_ALL_FDS) { + /* Close the logs here in case it got reopened above, as close_all_fds() would close them for us */ + log_close(); + + r = close_all_fds(except_fds, n_except_fds); + if (r < 0) { + log_full_errno(prio, r, "Failed to close all file descriptors: %m"); + _exit(EXIT_FAILURE); + } + } + + /* When we were asked to reopen the logs, do so again now */ + if (flags & FORK_REOPEN_LOG) { + log_open(); + log_set_open_when_needed(false); + } + + if (flags & FORK_NULL_STDIO) { + r = make_null_stdio(); + if (r < 0) { + log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m"); + _exit(EXIT_FAILURE); + } + } + + if (ret_pid) + *ret_pid = getpid_cached(); + + return 0; +} + +int fork_agent(const char *name, const int except[], unsigned n_except, pid_t *ret_pid, const char *path, ...) { + bool stdout_is_tty, stderr_is_tty; + unsigned n, i; + va_list ap; + char **l; + int r; + + assert(path); + + /* Spawns a temporary TTY agent, making sure it goes away when we go away */ + + r = safe_fork_full(name, except, n_except, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS, ret_pid); + if (r < 0) + return r; + if (r > 0) + return 0; + + /* In the child: */ + + stdout_is_tty = isatty(STDOUT_FILENO); + stderr_is_tty = isatty(STDERR_FILENO); + + if (!stdout_is_tty || !stderr_is_tty) { + int fd; + + /* Detach from stdout/stderr. and reopen + * /dev/tty for them. This is important to + * ensure that when systemctl is started via + * popen() or a similar call that expects to + * read EOF we actually do generate EOF and + * not delay this indefinitely by because we + * keep an unused copy of stdin around. */ + fd = open("/dev/tty", O_WRONLY); + if (fd < 0) { + log_error_errno(errno, "Failed to open /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) { + log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) { + log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + if (fd > STDERR_FILENO) + close(fd); + } + + /* Count arguments */ + va_start(ap, path); + for (n = 0; va_arg(ap, char*); n++) + ; + va_end(ap); + + /* Allocate strv */ + l = alloca(sizeof(char *) * (n + 1)); + + /* Fill in arguments */ + va_start(ap, path); + for (i = 0; i <= n; i++) + l[i] = va_arg(ap, char*); + va_end(ap); + + execv(path, l); + _exit(EXIT_FAILURE); +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 1b7e692060..9fabe4a5be 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -21,6 +21,7 @@ ***/ #include <alloca.h> +#include <errno.h> #include <sched.h> #include <signal.h> #include <stdbool.h> @@ -61,7 +62,16 @@ int get_process_environ(pid_t pid, char **environ); int get_process_ppid(pid_t pid, pid_t *ppid); int wait_for_terminate(pid_t pid, siginfo_t *status); -int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code); + +typedef enum WaitFlags { + WAIT_LOG_ABNORMAL = 1U << 0, + WAIT_LOG_NON_ZERO_EXIT_STATUS = 1U << 1, + + /* A shortcut for requesting the most complete logging */ + WAIT_LOG = WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS, +} WaitFlags; + +int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags); int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout); void sigkill_wait(pid_t pid); @@ -106,8 +116,13 @@ int sigchld_code_from_string(const char *s) _pure_; int sched_policy_to_string_alloc(int i, char **s); int sched_policy_from_string(const char *s); -#define PTR_TO_PID(p) ((pid_t) ((uintptr_t) p)) -#define PID_TO_PTR(p) ((void*) ((uintptr_t) p)) +static inline pid_t PTR_TO_PID(const void *p) { + return (pid_t) ((uintptr_t) p); +} + +static inline void* PID_TO_PTR(pid_t pid) { + return (void*) ((uintptr_t) pid); +} void valgrind_summary_hack(void); @@ -137,8 +152,54 @@ static inline bool pid_is_valid(pid_t p) { return p > 0; } +static inline int sched_policy_to_string_alloc_with_check(int n, char **s) { + if (!sched_policy_is_valid(n)) + return -EINVAL; + + return sched_policy_to_string_alloc(n, s); +} + int ioprio_parse_priority(const char *s, int *ret); pid_t getpid_cached(void); +void reset_cached_pid(void); int must_be_root(void); + +typedef enum ForkFlags { + FORK_RESET_SIGNALS = 1U << 0, + FORK_CLOSE_ALL_FDS = 1U << 1, + FORK_DEATHSIG = 1U << 2, + FORK_NULL_STDIO = 1U << 3, + FORK_REOPEN_LOG = 1U << 4, + FORK_LOG = 1U << 5, + FORK_WAIT = 1U << 6, + FORK_NEW_MOUNTNS = 1U << 7, +} ForkFlags; + +int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid); + +static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) { + return safe_fork_full(name, NULL, 0, flags, ret_pid); +} + +int fork_agent(const char *name, const int except[], unsigned n_except, pid_t *pid, const char *path, ...); + +#if SIZEOF_PID_T == 4 +/* The highest possibly (theoretic) pid_t value on this architecture. */ +#define PID_T_MAX ((pid_t) INT32_MAX) +/* The maximum number of concurrent processes Linux allows on this architecture, as well as the highest valid PID value + * the kernel will potentially assign. This reflects a value compiled into the kernel (PID_MAX_LIMIT), and sets the + * upper boundary on what may be written to the /proc/sys/kernel/pid_max sysctl (but do note that the sysctl is off by + * 1, since PID 0 can never exist and there can hence only be one process less than the limit would suggest). Since + * these values are documented in proc(5) we feel quite confident that they are stable enough for the near future at + * least to define them here too. */ +#define TASKS_MAX 4194303U +#elif SIZEOF_PID_T == 2 +#define PID_T_MAX ((pid_t) INT16_MAX) +#define TASKS_MAX 32767U +#else +#error "Unknown pid_t size" +#endif + +assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX) diff --git a/src/basic/procfs-util.c b/src/basic/procfs-util.c new file mode 100644 index 0000000000..9bb42cc7ba --- /dev/null +++ b/src/basic/procfs-util.c @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include <errno.h> + +#include "alloc-util.h" +#include "fileio.h" +#include "parse-util.h" +#include "process-util.h" +#include "procfs-util.h" +#include "stdio-util.h" +#include "string-util.h" + +int procfs_tasks_get_limit(uint64_t *ret) { + _cleanup_free_ char *value = NULL; + uint64_t pid_max, threads_max; + int r; + + assert(ret); + + /* So there are two sysctl files that control the system limit of processes: + * + * 1. kernel.threads-max: this is probably the sysctl that makes more sense, as it directly puts a limit on + * concurrent tasks. + * + * 2. kernel.pid_max: this limits the numeric range PIDs can take, and thus indirectly also limits the number + * of concurrent threads. AFAICS it's primarily a compatibility concept: some crappy old code used a signed + * 16bit type for PIDs, hence the kernel provides a way to ensure the PIDs never go beyond INT16_MAX by + * default. + * + * By default #2 is set to much lower values than #1, hence the limit people come into contact with first, as + * it's the lowest boundary they need to bump when they want higher number of processes. + * + * Also note the weird definition of #2: PIDs assigned will be kept below this value, which means the number of + * tasks that can be created is one lower, as PID 0 is not a valid process ID. */ + + r = read_one_line_file("/proc/sys/kernel/pid_max", &value); + if (r < 0) + return r; + + r = safe_atou64(value, &pid_max); + if (r < 0) + return r; + + value = mfree(value); + r = read_one_line_file("/proc/sys/kernel/threads-max", &value); + if (r < 0) + return r; + + r = safe_atou64(value, &threads_max); + if (r < 0) + return r; + + /* Subtract one from pid_max, since PID 0 is not a valid PID */ + *ret = MIN(pid_max-1, threads_max); + return 0; +} + +int procfs_tasks_set_limit(uint64_t limit) { + char buffer[DECIMAL_STR_MAX(uint64_t)+1]; + _cleanup_free_ char *value = NULL; + uint64_t pid_max; + int r; + + if (limit == 0) /* This makes no sense, we are userspace and hence count as tasks too, and we want to live, + * hence the limit conceptually has to be above 0. Also, most likely if anyone asks for a zero + * limit he/she probably means "no limit", hence let's better refuse this to avoid + * confusion. */ + return -EINVAL; + + /* The Linux kernel doesn't allow this value to go below 20, hence don't allow this either, higher values than + * TASKS_MAX are not accepted by the pid_max sysctl. We'll treat anything this high as "unbounded" and hence + * set it to the maximum. */ + limit = CLAMP(limit, 20U, TASKS_MAX); + + r = read_one_line_file("/proc/sys/kernel/pid_max", &value); + if (r < 0) + return r; + r = safe_atou64(value, &pid_max); + if (r < 0) + return r; + + /* As pid_max is about the numeric pid_t range we'll bump it if necessary, but only ever increase it, never + * decrease it, as threads-max is the much more relevant sysctl. */ + if (limit > pid_max-1) { + sprintf(buffer, "%" PRIu64, limit+1); /* Add one, since PID 0 is not a valid PID */ + r = write_string_file("/proc/sys/kernel/pid_max", buffer, WRITE_STRING_FILE_DISABLE_BUFFER); + if (r < 0) + return r; + } + + sprintf(buffer, "%" PRIu64, limit); + r = write_string_file("/proc/sys/kernel/threads-max", buffer, WRITE_STRING_FILE_DISABLE_BUFFER); + if (r < 0) { + uint64_t threads_max; + + /* Hmm, we couldn't write this? If so, maybe it was already set properly? In that case let's not + * generate an error */ + + value = mfree(value); + if (read_one_line_file("/proc/sys/kernel/threads-max", &value) < 0) + return r; /* return original error */ + + if (safe_atou64(value, &threads_max) < 0) + return r; /* return original error */ + + if (MIN(pid_max-1, threads_max) != limit) + return r; /* return original error */ + + /* Yay! Value set already matches what we were trying to set, hence consider this a success. */ + } + + return 0; +} + +int procfs_tasks_get_current(uint64_t *ret) { + _cleanup_free_ char *value = NULL; + const char *p, *nr; + size_t n; + int r; + + assert(ret); + + r = read_one_line_file("/proc/loadavg", &value); + if (r < 0) + return r; + + /* Look for the second part of the fourth field, which is separated by a slash from the first part. None of the + * earlier fields use a slash, hence let's use this to find the right spot. */ + p = strchr(value, '/'); + if (!p) + return -EINVAL; + + p++; + n = strspn(p, DIGITS); + nr = strndupa(p, n); + + return safe_atou64(nr, ret); +} diff --git a/src/basic/procfs-util.h b/src/basic/procfs-util.h new file mode 100644 index 0000000000..7466acd7f3 --- /dev/null +++ b/src/basic/procfs-util.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include <inttypes.h> + +int procfs_tasks_get_limit(uint64_t *ret); +int procfs_tasks_set_limit(uint64_t limit); +int procfs_tasks_get_current(uint64_t *ret); diff --git a/src/basic/random-util.c b/src/basic/random-util.c index 1bc8000896..7457815fa2 100644 --- a/src/basic/random-util.c +++ b/src/basic/random-util.c @@ -21,11 +21,12 @@ #include <elf.h> #include <errno.h> #include <fcntl.h> +#include <linux/random.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> +#include <string.h> #include <sys/time.h> -#include <linux/random.h> -#include <stdint.h> #if HAVE_SYS_AUXV_H # include <sys/auxv.h> diff --git a/src/basic/raw-clone.h b/src/basic/raw-clone.h index f01b73a8fe..8c95380305 100644 --- a/src/basic/raw-clone.h +++ b/src/basic/raw-clone.h @@ -30,28 +30,27 @@ * raw_clone() - uses clone to create a new process with clone flags * @flags: Flags to pass to the clone system call * - * Uses the clone system call to create a new process with the cloning - * flags and termination signal passed in the flags parameter. Opposed - * to glibc's clone funtion, using this function does not set up a - * separate stack for the child, but relies on copy-on-write semantics - * on the one stack at a common virtual address, just as fork does. + * Uses the clone system call to create a new process with the cloning flags and termination signal passed in the flags + * parameter. Opposed to glibc's clone funtion, using this function does not set up a separate stack for the child, but + * relies on copy-on-write semantics on the one stack at a common virtual address, just as fork does. * - * To obtain copy-on-write semantics, flags must not contain CLONE_VM, - * and thus CLONE_THREAD and CLONE_SIGHAND (which require CLONE_VM) are - * not usabale. - * Additionally, as this function does not pass the ptid, newtls and ctid - * parameters to the kernel, flags must not contain CLONE_PARENT_SETTID, - * CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID or CLONE_SETTLS. + * To obtain copy-on-write semantics, flags must not contain CLONE_VM, and thus CLONE_THREAD and CLONE_SIGHAND (which + * require CLONE_VM) are not usable. + * + * Additionally, as this function does not pass the ptid, newtls and ctid parameters to the kernel, flags must not + * contain CLONE_PARENT_SETTID, CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID or CLONE_SETTLS. * * Returns: 0 in the child process and the child process id in the parent. */ -static inline int raw_clone(unsigned long flags) { +static inline pid_t raw_clone(unsigned long flags) { + pid_t ret; + assert((flags & (CLONE_VM|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID| CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0); #if defined(__s390x__) || defined(__s390__) || defined(__CRIS__) /* On s390/s390x and cris the order of the first and second arguments * of the raw clone() system call is reversed. */ - return (int) syscall(__NR_clone, NULL, flags); + ret = (pid_t) syscall(__NR_clone, NULL, flags); #elif defined(__sparc__) && defined(__arch64__) { /** @@ -60,8 +59,8 @@ static inline int raw_clone(unsigned long flags) { * %o1. Inline assembly is needed to get the flag returned * in %o1. */ - int in_child; - int child_pid; + int in_child, child_pid; + asm volatile("mov %2, %%g1\n\t" "mov %3, %%o0\n\t" "mov 0 , %%o1\n\t" @@ -71,12 +70,15 @@ static inline int raw_clone(unsigned long flags) { "=r"(in_child), "=r"(child_pid) : "i"(__NR_clone), "r"(flags) : "%o1", "%o0", "%g1" ); - if (in_child) - return 0; - else - return child_pid; + + ret = in_child ? 0 : child_pid; } #else - return (int) syscall(__NR_clone, flags, NULL); + ret = (pid_t) syscall(__NR_clone, flags, NULL); #endif + + if (ret == 0) + reset_cached_pid(); + + return ret; } diff --git a/src/basic/rm-rf.h b/src/basic/rm-rf.h index 1127e326b2..ad63e9be40 100644 --- a/src/basic/rm-rf.h +++ b/src/basic/rm-rf.h @@ -22,6 +22,8 @@ #include <sys/stat.h> +#include "util.h" + typedef enum RemoveFlags { REMOVE_ONLY_DIRECTORIES = 1, REMOVE_ROOT = 2, @@ -34,6 +36,7 @@ int rm_rf(const char *path, RemoveFlags flags); /* Useful for usage with _cleanup_(), destroys a directory and frees the pointer */ static inline void rm_rf_physical_and_free(char *p) { + PROTECT_ERRNO; (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL); free(p); } diff --git a/src/basic/securebits-util.c b/src/basic/securebits-util.c index b5f6418a6c..441d386f9e 100644 --- a/src/basic/securebits-util.c +++ b/src/basic/securebits-util.c @@ -19,6 +19,7 @@ ***/ #include <errno.h> +#include <stdio.h> #include "alloc-util.h" #include "extract-word.h" diff --git a/src/basic/securebits-util.h b/src/basic/securebits-util.h index aaa192f0a5..069d215488 100644 --- a/src/basic/securebits-util.h +++ b/src/basic/securebits-util.h @@ -24,6 +24,14 @@ int secure_bits_to_string_alloc(int i, char **s); int secure_bits_from_string(const char *s); + static inline bool secure_bits_is_valid(int i) { return ((SECURE_ALL_BITS | SECURE_ALL_LOCKS) & i) == i; } + +static inline int secure_bits_to_string_alloc_with_check(int n, char **s) { + if (!secure_bits_is_valid(n)) + return -EINVAL; + + return secure_bits_to_string_alloc(n, s); +} diff --git a/src/basic/signal-util.h b/src/basic/signal-util.h index 76b239b1fc..f6c3396ebe 100644 --- a/src/basic/signal-util.h +++ b/src/basic/signal-util.h @@ -55,3 +55,10 @@ static inline void block_signals_reset(sigset_t *ss) { static inline bool SIGNAL_VALID(int signo) { return signo > 0 && signo < _NSIG; } + +static inline const char* signal_to_string_with_check(int n) { + if (!SIGNAL_VALID(n)) + return NULL; + + return signal_to_string(n); +} diff --git a/src/basic/smack-util.c b/src/basic/smack-util.c index e0f1c9f1c7..f0018f013f 100644 --- a/src/basic/smack-util.c +++ b/src/basic/smack-util.c @@ -136,7 +136,7 @@ int mac_smack_apply_pid(pid_t pid, const char *label) { int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { struct stat st; - int r = 0; + int r; assert(path); diff --git a/src/basic/socket-label.c b/src/basic/socket-label.c index 20be406371..97f3ebe2af 100644 --- a/src/basic/socket-label.c +++ b/src/basic/socket-label.c @@ -29,6 +29,7 @@ #include "alloc-util.h" #include "fd-util.h" +#include "fs-util.h" #include "log.h" #include "macro.h" #include "missing.h" @@ -51,6 +52,7 @@ int socket_address_listen( const char *label) { _cleanup_close_ int fd = -1; + const char *p; int r, one; assert(a); @@ -112,19 +114,23 @@ int socket_address_listen( if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) return -errno; - if (socket_address_family(a) == AF_UNIX && a->sockaddr.un.sun_path[0] != 0) { + p = socket_address_get_path(a); + if (p) { /* Create parents */ - (void) mkdir_parents_label(a->sockaddr.un.sun_path, directory_mode); + (void) mkdir_parents_label(p, directory_mode); /* Enforce the right access mode for the socket */ RUN_WITH_UMASK(~socket_mode) { r = mac_selinux_bind(fd, &a->sockaddr.sa, a->size); if (r == -EADDRINUSE) { /* Unlink and try again */ - unlink(a->sockaddr.un.sun_path); - if (bind(fd, &a->sockaddr.sa, a->size) < 0) - return -errno; - } else if (r < 0) + + if (unlink(p) < 0) + return r; /* didn't work, return original error */ + + r = mac_selinux_bind(fd, &a->sockaddr.sa, a->size); + } + if (r < 0) return r; } } else { @@ -136,6 +142,11 @@ int socket_address_listen( if (listen(fd, backlog) < 0) return -errno; + /* Let's trigger an inotify event on the socket node, so that anyone waiting for this socket to be connectable + * gets notified */ + if (p) + (void) touch(p); + r = fd; fd = -1; diff --git a/src/basic/socket-protocol-list.c b/src/basic/socket-protocol-list.c new file mode 100644 index 0000000000..9ab93d1c7e --- /dev/null +++ b/src/basic/socket-protocol-list.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + This file is part of systemd. + + Copyright 2014 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <netinet/in.h> +#include <string.h> + +#include "socket-protocol-list.h" +#include "macro.h" + +static const struct socket_protocol_name* lookup_socket_protocol(register const char *str, register GPERF_LEN_TYPE len); + +#include "socket-protocol-from-name.h" +#include "socket-protocol-to-name.h" + +const char *socket_protocol_to_name(int id) { + + if (id < 0) + return NULL; + + if (id >= (int) ELEMENTSOF(socket_protocol_names)) + return NULL; + + return socket_protocol_names[id]; +} + +int socket_protocol_from_name(const char *name) { + const struct socket_protocol_name *sc; + + assert(name); + + sc = lookup_socket_protocol(name, strlen(name)); + if (!sc) + return 0; + + return sc->id; +} + +int socket_protocol_max(void) { + return ELEMENTSOF(socket_protocol_names); +} diff --git a/src/basic/socket-protocol-list.h b/src/basic/socket-protocol-list.h new file mode 100644 index 0000000000..12fd053382 --- /dev/null +++ b/src/basic/socket-protocol-list.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2014 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +const char *socket_protocol_to_name(int id); +int socket_protocol_from_name(const char *name); + +int socket_protocol_max(void); diff --git a/src/basic/socket-protocol-to-name.awk b/src/basic/socket-protocol-to-name.awk new file mode 100644 index 0000000000..4848a7631a --- /dev/null +++ b/src/basic/socket-protocol-to-name.awk @@ -0,0 +1,9 @@ +BEGIN{ + print "static const char* const socket_protocol_names[] = { " +} +!/HOPOPTS/ { + printf " [IPPROTO_%s] = \"%s\",\n", $1, tolower($1) +} +END{ + print "};" +} diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index a458fc2902..2c70cade14 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -41,6 +41,7 @@ #include "missing.h" #include "parse-util.h" #include "path-util.h" +#include "process-util.h" #include "socket-util.h" #include "string-table.h" #include "string-util.h" @@ -55,9 +56,19 @@ # define IDN_FLAGS 0 #endif +static const char* const socket_address_type_table[] = { + [SOCK_STREAM] = "Stream", + [SOCK_DGRAM] = "Datagram", + [SOCK_RAW] = "Raw", + [SOCK_RDM] = "ReliableDatagram", + [SOCK_SEQPACKET] = "SequentialPacket", + [SOCK_DCCP] = "DatagramCongestionControl", +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int); + int socket_address_parse(SocketAddress *a, const char *s) { char *e, *n; - unsigned u; int r; assert(a); @@ -67,6 +78,8 @@ int socket_address_parse(SocketAddress *a, const char *s) { a->type = SOCK_STREAM; if (*s == '[') { + uint16_t port; + /* IPv6 in [x:.....:z]:p notation */ e = strchr(s+1, ']'); @@ -84,15 +97,12 @@ int socket_address_parse(SocketAddress *a, const char *s) { return -EINVAL; e++; - r = safe_atou(e, &u); + r = parse_ip_port(e, &port); if (r < 0) return r; - if (u <= 0 || u > 0xFFFF) - return -EINVAL; - a->sockaddr.in6.sin6_family = AF_INET6; - a->sockaddr.in6.sin6_port = htobe16((uint16_t)u); + a->sockaddr.in6.sin6_port = htobe16(port); a->size = sizeof(struct sockaddr_in6); } else if (*s == '/') { @@ -123,12 +133,13 @@ int socket_address_parse(SocketAddress *a, const char *s) { } else if (startswith(s, "vsock:")) { /* AF_VSOCK socket in vsock:cid:port notation */ const char *cid_start = s + STRLEN("vsock:"); + unsigned port; e = strchr(cid_start, ':'); if (!e) return -EINVAL; - r = safe_atou(e+1, &u); + r = safe_atou(e+1, &port); if (r < 0) return r; @@ -141,19 +152,18 @@ int socket_address_parse(SocketAddress *a, const char *s) { a->sockaddr.vm.svm_cid = VMADDR_CID_ANY; a->sockaddr.vm.svm_family = AF_VSOCK; - a->sockaddr.vm.svm_port = u; + a->sockaddr.vm.svm_port = port; a->size = sizeof(struct sockaddr_vm); } else { + uint16_t port; + e = strchr(s, ':'); if (e) { - r = safe_atou(e+1, &u); + r = parse_ip_port(e + 1, &port); if (r < 0) return r; - if (u <= 0 || u > 0xFFFF) - return -EINVAL; - n = strndupa(s, e-s); /* IPv4 in w.x.y.z:p notation? */ @@ -164,7 +174,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { if (r > 0) { /* Gotcha, it's a traditional IPv4 address */ a->sockaddr.in.sin_family = AF_INET; - a->sockaddr.in.sin_port = htobe16((uint16_t)u); + a->sockaddr.in.sin_port = htobe16(port); a->size = sizeof(struct sockaddr_in); } else { unsigned idx; @@ -178,7 +188,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { return -EINVAL; a->sockaddr.in6.sin6_family = AF_INET6; - a->sockaddr.in6.sin6_port = htobe16((uint16_t)u); + a->sockaddr.in6.sin6_port = htobe16(port); a->sockaddr.in6.sin6_scope_id = idx; a->sockaddr.in6.sin6_addr = in6addr_any; a->size = sizeof(struct sockaddr_in6); @@ -186,21 +196,18 @@ int socket_address_parse(SocketAddress *a, const char *s) { } else { /* Just a port */ - r = safe_atou(s, &u); + r = parse_ip_port(s, &port); if (r < 0) return r; - if (u <= 0 || u > 0xFFFF) - return -EINVAL; - if (socket_ipv6_is_supported()) { a->sockaddr.in6.sin6_family = AF_INET6; - a->sockaddr.in6.sin6_port = htobe16((uint16_t)u); + a->sockaddr.in6.sin6_port = htobe16(port); a->sockaddr.in6.sin6_addr = in6addr_any; a->size = sizeof(struct sockaddr_in6); } else { a->sockaddr.in.sin_family = AF_INET; - a->sockaddr.in.sin_port = htobe16((uint16_t)u); + a->sockaddr.in.sin_port = htobe16(port); a->sockaddr.in.sin_addr.s_addr = INADDR_ANY; a->size = sizeof(struct sockaddr_in); } @@ -528,22 +535,25 @@ bool socket_address_matches_fd(const SocketAddress *a, int fd) { return socket_address_equal(a, &b); } -int sockaddr_port(const struct sockaddr *_sa, unsigned *port) { +int sockaddr_port(const struct sockaddr *_sa, unsigned *ret_port) { union sockaddr_union *sa = (union sockaddr_union*) _sa; + /* Note, this returns the port as 'unsigned' rather than 'uint16_t', as AF_VSOCK knows larger ports */ + assert(sa); switch (sa->sa.sa_family) { + case AF_INET: - *port = be16toh(sa->in.sin_port); + *ret_port = be16toh(sa->in.sin_port); return 0; case AF_INET6: - *port = be16toh(sa->in6.sin6_port); + *ret_port = be16toh(sa->in6.sin6_port); return 0; case AF_VSOCK: - *port = sa->vm.svm_port; + *ret_port = sa->vm.svm_port; return 0; default: @@ -807,6 +817,18 @@ static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIN DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); +SocketAddressBindIPv6Only parse_socket_address_bind_ipv6_only_or_bool(const char *n) { + int r; + + r = parse_boolean(n); + if (r > 0) + return SOCKET_ADDRESS_IPV6_ONLY; + if (r == 0) + return SOCKET_ADDRESS_BOTH; + + return socket_address_bind_ipv6_only_from_string(n); +} + bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) { assert(a); assert(b); @@ -941,58 +963,80 @@ int getpeercred(int fd, struct ucred *ucred) { if (n != sizeof(struct ucred)) return -EIO; - /* Check if the data is actually useful and not suppressed due - * to namespacing issues */ - if (u.pid <= 0) - return -ENODATA; - if (u.uid == UID_INVALID) - return -ENODATA; - if (u.gid == GID_INVALID) + /* Check if the data is actually useful and not suppressed due to namespacing issues */ + if (!pid_is_valid(u.pid)) return -ENODATA; + /* Note that we don't check UID/GID here, as namespace translation works differently there: instead of + * receiving in "invalid" user/group we get the overflow UID/GID. */ + *ucred = u; return 0; } int getpeersec(int fd, char **ret) { + _cleanup_free_ char *s = NULL; socklen_t n = 64; - char *s; - int r; assert(fd >= 0); assert(ret); - s = new0(char, n); - if (!s) - return -ENOMEM; + for (;;) { + s = new0(char, n+1); + if (!s) + return -ENOMEM; - r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n); - if (r < 0) { - free(s); + if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n) >= 0) + break; if (errno != ERANGE) return -errno; - s = new0(char, n); - if (!s) - return -ENOMEM; - - r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n); - if (r < 0) { - free(s); - return -errno; - } + s = mfree(s); } - if (isempty(s)) { - free(s); + if (isempty(s)) return -EOPNOTSUPP; - } *ret = s; + s = NULL; + return 0; } +int getpeergroups(int fd, gid_t **ret) { + socklen_t n = sizeof(gid_t) * 64; + _cleanup_free_ gid_t *d = NULL; + + assert(fd); + assert(ret); + + for (;;) { + d = malloc(n); + if (!d) + return -ENOMEM; + + if (getsockopt(fd, SOL_SOCKET, SO_PEERGROUPS, d, &n) >= 0) + break; + + if (errno != ERANGE) + return -errno; + + d = mfree(d); + } + + assert_se(n % sizeof(gid_t) == 0); + n /= sizeof(gid_t); + + if ((socklen_t) (int) n != n) + return -E2BIG; + + *ret = d; + d = NULL; + + return (int) n; +} + int send_one_fd_sa( int transport_fd, int fd, diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 272e74b0cc..49c937aef5 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -36,16 +36,26 @@ #include "util.h" union sockaddr_union { + /* The minimal, abstract version */ struct sockaddr sa; + + /* The libc provided version that allocates "enough room" for every protocol */ + struct sockaddr_storage storage; + + /* Protoctol-specific implementations */ struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_un un; struct sockaddr_nl nl; - struct sockaddr_storage storage; struct sockaddr_ll ll; struct sockaddr_vm vm; + /* Ensure there is enough space to store Infiniband addresses */ uint8_t ll_buffer[offsetof(struct sockaddr_ll, sll_addr) + CONST_MAX(ETH_ALEN, INFINIBAND_ALEN)]; + + /* Ensure there is enough space after the AF_UNIX sun_path for one more NUL byte, just to be sure that the path + * component is always followed by at least one NUL byte. */ + uint8_t un_buffer[sizeof(struct sockaddr_un) + 1]; }; typedef struct SocketAddress { @@ -72,6 +82,9 @@ typedef enum SocketAddressBindIPv6Only { #define socket_address_family(a) ((a)->sockaddr.sa.sa_family) +const char* socket_address_type_to_string(int t) _const_; +int socket_address_type_from_string(const char *s) _pure_; + int socket_address_parse(SocketAddress *a, const char *s); int socket_address_parse_and_warn(SocketAddress *a, const char *s); int socket_address_parse_netlink(SocketAddress *a, const char *s); @@ -117,6 +130,7 @@ int getnameinfo_pretty(int fd, char **ret); const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_; SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_; +SocketAddressBindIPv6Only parse_socket_address_bind_ipv6_only_or_bool(const char *s); int netlink_family_to_string_alloc(int b, char **s); int netlink_family_from_string(const char *s) _pure_; @@ -134,6 +148,7 @@ bool address_label_valid(const char *p); int getpeercred(int fd, struct ucred *ucred); int getpeersec(int fd, char **ret); +int getpeergroups(int fd, gid_t **ret); int send_one_fd_sa(int transport_fd, int fd, diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c index 96fc8b3787..3a54103f1b 100644 --- a/src/basic/stat-util.c +++ b/src/basic/stat-util.c @@ -21,10 +21,11 @@ #include <dirent.h> #include <errno.h> #include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> #include <linux/magic.h> +#include <sched.h> +#include <sys/stat.h> #include <sys/statvfs.h> +#include <sys/types.h> #include <unistd.h> #include "dirent-util.h" diff --git a/src/basic/string-util.c b/src/basic/string-util.c index 7e2f596edc..9f2c01d864 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -30,6 +30,7 @@ #include "gunicode.h" #include "macro.h" #include "string-util.h" +#include "terminal-util.h" #include "utf8.h" #include "util.h" @@ -648,7 +649,17 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin return ret; } -char *strip_tab_ansi(char **ibuf, size_t *_isz) { +static void advance_offsets(ssize_t diff, size_t offsets[2], size_t shift[2], size_t size) { + if (!offsets) + return; + + if ((size_t) diff < offsets[0]) + shift[0] += size; + if ((size_t) diff < offsets[1]) + shift[1] += size; +} + +char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { const char *i, *begin = NULL; enum { STATE_OTHER, @@ -656,7 +667,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) { STATE_BRACKET } state = STATE_OTHER; char *obuf = NULL; - size_t osz = 0, isz; + size_t osz = 0, isz, shift[2] = {}; FILE *f; assert(ibuf); @@ -684,15 +695,18 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) { break; else if (*i == '\x1B') state = STATE_ESCAPE; - else if (*i == '\t') + else if (*i == '\t') { fputs(" ", f); - else + advance_offsets(i - *ibuf, highlight, shift, 7); + } else fputc(*i, f); + break; case STATE_ESCAPE: if (i >= *ibuf + isz) { /* EOT */ fputc('\x1B', f); + advance_offsets(i - *ibuf, highlight, shift, 1); break; } else if (*i == '[') { state = STATE_BRACKET; @@ -700,6 +714,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) { } else { fputc('\x1B', f); fputc(*i, f); + advance_offsets(i - *ibuf, highlight, shift, 1); state = STATE_OTHER; } @@ -711,6 +726,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) { (!(*i >= '0' && *i <= '9') && !IN_SET(*i, ';', 'm'))) { fputc('\x1B', f); fputc('[', f); + advance_offsets(i - *ibuf, highlight, shift, 2); state = STATE_OTHER; i = begin-1; } else if (*i == 'm') @@ -732,6 +748,11 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) { if (_isz) *_isz = osz; + if (highlight) { + highlight[0] += shift[0]; + highlight[1] += shift[1]; + } + return obuf; } diff --git a/src/basic/string-util.h b/src/basic/string-util.h index 09a737ad37..08eda4fce0 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -52,15 +52,15 @@ static inline bool streq_ptr(const char *a, const char *b) { } static inline const char* strempty(const char *s) { - return s ? s : ""; + return s ?: ""; } static inline const char* strnull(const char *s) { - return s ? s : "(null)"; + return s ?: "(null)"; } static inline const char *strna(const char *s) { - return s ? s : "n/a"; + return s ?: "n/a"; } static inline bool isempty(const char *p) { @@ -177,7 +177,7 @@ char* strshorten(char *s, size_t l); char *strreplace(const char *text, const char *old_string, const char *new_string); -char *strip_tab_ansi(char **p, size_t *l); +char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]); char *strextend_with_separator(char **x, const char *separator, ...) _sentinel_; diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 48ee799ad4..42336e8fdf 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -875,31 +875,30 @@ bool on_tty(void) { } int make_stdio(int fd) { - int r, s, t; + int r = 0; assert(fd >= 0); - r = dup2(fd, STDIN_FILENO); - s = dup2(fd, STDOUT_FILENO); - t = dup2(fd, STDERR_FILENO); + if (dup2(fd, STDIN_FILENO) < 0 && r >= 0) + r = -errno; + if (dup2(fd, STDOUT_FILENO) < 0 && r >= 0) + r = -errno; + if (dup2(fd, STDERR_FILENO) < 0 && r >= 0) + r = -errno; if (fd >= 3) safe_close(fd); - if (r < 0 || s < 0 || t < 0) - return -errno; - - /* Explicitly unset O_CLOEXEC, since if fd was < 3, then - * dup2() was a NOP and the bit hence possibly set. */ + /* Explicitly unset O_CLOEXEC, since if fd was < 3, then dup2() was a NOP and the bit hence possibly set. */ stdio_unset_cloexec(); - return 0; + return r; } int make_null_stdio(void) { int null_fd; - null_fd = open("/dev/null", O_RDWR|O_NOCTTY); + null_fd = open("/dev/null", O_RDWR|O_NOCTTY|O_CLOEXEC); if (null_fd < 0) return -errno; @@ -1094,7 +1093,6 @@ int ptsname_namespace(int pty, char **ret) { int openpt_in_namespace(pid_t pid, int flags) { _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1; _cleanup_close_pair_ int pair[2] = { -1, -1 }; - siginfo_t si; pid_t child; int r; @@ -1107,11 +1105,10 @@ int openpt_in_namespace(pid_t pid, int flags) { if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0) return -errno; - child = fork(); - if (child < 0) - return -errno; - - if (child == 0) { + r = safe_fork("(sd-openpt)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child); + if (r < 0) + return r; + if (r == 0) { int master; pair[0] = safe_close(pair[0]); @@ -1135,10 +1132,10 @@ int openpt_in_namespace(pid_t pid, int flags) { pair[1] = safe_close(pair[1]); - r = wait_for_terminate(child, &si); + r = wait_for_terminate_and_check("(sd-openpt)", child, 0); if (r < 0) return r; - if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) + if (r != EXIT_SUCCESS) return -EIO; return receive_one_fd(pair[0], 0); @@ -1147,7 +1144,6 @@ int openpt_in_namespace(pid_t pid, int flags) { int open_terminal_in_namespace(pid_t pid, const char *name, int mode) { _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1; _cleanup_close_pair_ int pair[2] = { -1, -1 }; - siginfo_t si; pid_t child; int r; @@ -1158,11 +1154,10 @@ int open_terminal_in_namespace(pid_t pid, const char *name, int mode) { if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0) return -errno; - child = fork(); - if (child < 0) - return -errno; - - if (child == 0) { + r = safe_fork("(sd-terminal)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child); + if (r < 0) + return r; + if (r == 0) { int master; pair[0] = safe_close(pair[0]); @@ -1183,10 +1178,10 @@ int open_terminal_in_namespace(pid_t pid, const char *name, int mode) { pair[1] = safe_close(pair[1]); - r = wait_for_terminate(child, &si); + r = wait_for_terminate_and_check("(sd-terminal)", child, 0); if (r < 0) return r; - if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) + if (r != EXIT_SUCCESS) return -EIO; return receive_one_fd(pair[0], 0); diff --git a/src/basic/time-util.c b/src/basic/time-util.c index d56576ddbe..4a341e208f 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -38,6 +38,7 @@ #include "macro.h" #include "parse-util.h" #include "path-util.h" +#include "process-util.h" #include "string-util.h" #include "strv.h" #include "time-util.h" @@ -887,7 +888,6 @@ int parse_timestamp(const char *t, usec_t *usec) { char *last_space, *tz = NULL; ParseTimestampResult *shared, tmp; int r; - pid_t pid; last_space = strrchr(t, ' '); if (last_space != NULL && timezone_is_valid(last_space + 1)) @@ -900,15 +900,12 @@ int parse_timestamp(const char *t, usec_t *usec) { if (shared == MAP_FAILED) return negative_errno(); - pid = fork(); - - if (pid == -1) { - int fork_errno = errno; + r = safe_fork("(sd-timestamp)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT, NULL); + if (r < 0) { (void) munmap(shared, sizeof *shared); - return -fork_errno; + return r; } - - if (pid == 0) { + if (r == 0) { bool with_tz = true; if (setenv("TZ", tz, 1) != 0) { @@ -931,12 +928,6 @@ int parse_timestamp(const char *t, usec_t *usec) { _exit(EXIT_SUCCESS); } - r = wait_for_terminate(pid, NULL); - if (r < 0) { - (void) munmap(shared, sizeof *shared); - return r; - } - tmp = *shared; if (munmap(shared, sizeof *shared) != 0) return negative_errno(); diff --git a/src/basic/unaligned.h b/src/basic/unaligned.h index 201b3d227e..73302b4239 100644 --- a/src/basic/unaligned.h +++ b/src/basic/unaligned.h @@ -26,89 +26,77 @@ /* BE */ static inline uint16_t unaligned_read_be16(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u; - return (((uint16_t) u[0]) << 8) | - ((uint16_t) u[1]); + return be16toh(u->x); } static inline uint32_t unaligned_read_be32(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u; - return (((uint32_t) unaligned_read_be16(u)) << 16) | - ((uint32_t) unaligned_read_be16(u + 2)); + return be32toh(u->x); } static inline uint64_t unaligned_read_be64(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u; - return (((uint64_t) unaligned_read_be32(u)) << 32) | - ((uint64_t) unaligned_read_be32(u + 4)); + return be64toh(u->x); } static inline void unaligned_write_be16(void *_u, uint16_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u; - u[0] = (uint8_t) (a >> 8); - u[1] = (uint8_t) a; + u->x = be16toh(a); } static inline void unaligned_write_be32(void *_u, uint32_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u; - unaligned_write_be16(u, (uint16_t) (a >> 16)); - unaligned_write_be16(u + 2, (uint16_t) a); + u->x = be32toh(a); } static inline void unaligned_write_be64(void *_u, uint64_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u; - unaligned_write_be32(u, (uint32_t) (a >> 32)); - unaligned_write_be32(u + 4, (uint32_t) a); + u->x = be64toh(a); } /* LE */ static inline uint16_t unaligned_read_le16(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u; - return (((uint16_t) u[1]) << 8) | - ((uint16_t) u[0]); + return le16toh(u->x); } static inline uint32_t unaligned_read_le32(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u; - return (((uint32_t) unaligned_read_le16(u + 2)) << 16) | - ((uint32_t) unaligned_read_le16(u)); + return le32toh(u->x); } static inline uint64_t unaligned_read_le64(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u; - return (((uint64_t) unaligned_read_le32(u + 4)) << 32) | - ((uint64_t) unaligned_read_le32(u)); + return le64toh(u->x); } static inline void unaligned_write_le16(void *_u, uint16_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u; - u[0] = (uint8_t) a; - u[1] = (uint8_t) (a >> 8); + u->x = le16toh(a); } static inline void unaligned_write_le32(void *_u, uint32_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u; - unaligned_write_le16(u, (uint16_t) a); - unaligned_write_le16(u + 2, (uint16_t) (a >> 16)); + u->x = le32toh(a); } static inline void unaligned_write_le64(void *_u, uint64_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u; - unaligned_write_le32(u, (uint32_t) a); - unaligned_write_le32(u + 4, (uint32_t) (a >> 32)); + u->x = le64toh(a); } #if __BYTE_ORDER == __BIG_ENDIAN diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c index 403f288b57..0fa0472ee1 100644 --- a/src/basic/unit-name.c +++ b/src/basic/unit-name.c @@ -28,6 +28,7 @@ #include "glob-util.h" #include "hexdecoct.h" #include "path-util.h" +#include "special.h" #include "string-util.h" #include "strv.h" #include "unit-name.h" @@ -673,7 +674,7 @@ int slice_build_parent_slice(const char *slice, char **ret) { if (!slice_name_is_valid(slice)) return -EINVAL; - if (streq(slice, "-.slice")) { + if (streq(slice, SPECIAL_ROOT_SLICE)) { *ret = NULL; return 0; } @@ -686,7 +687,7 @@ int slice_build_parent_slice(const char *slice, char **ret) { if (dash) strcpy(dash, ".slice"); else { - r = free_and_strdup(&s, "-.slice"); + r = free_and_strdup(&s, SPECIAL_ROOT_SLICE); if (r < 0) { free(s); return r; @@ -710,7 +711,7 @@ int slice_build_subslice(const char *slice, const char*name, char **ret) { if (!unit_prefix_is_valid(name)) return -EINVAL; - if (streq(slice, "-.slice")) + if (streq(slice, SPECIAL_ROOT_SLICE)) subslice = strappend(name, ".slice"); else { char *e; @@ -735,7 +736,7 @@ bool slice_name_is_valid(const char *name) { if (!unit_name_is_valid(name, UNIT_NAME_PLAIN)) return false; - if (streq(name, "-.slice")) + if (streq(name, SPECIAL_ROOT_SLICE)) return true; e = endswith(name, ".slice"); diff --git a/src/basic/user-util.c b/src/basic/user-util.c index abb0b76866..17a9b5a8f1 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -137,7 +137,8 @@ int get_user_creds( return 0; } - if (STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) { + if (synthesize_nobody() && + STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) { *username = NOBODY_USER_NAME; if (uid) @@ -243,7 +244,8 @@ int get_group_creds(const char **groupname, gid_t *gid) { return 0; } - if (STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) { + if (synthesize_nobody() && + STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) { *groupname = NOBODY_GROUP_NAME; if (gid) @@ -283,7 +285,8 @@ char* uid_to_name(uid_t uid) { /* Shortcut things to avoid NSS lookups */ if (uid == 0) return strdup("root"); - if (uid == UID_NOBODY) + if (synthesize_nobody() && + uid == UID_NOBODY) return strdup(NOBODY_USER_NAME); if (uid_is_valid(uid)) { @@ -323,7 +326,8 @@ char* gid_to_name(gid_t gid) { if (gid == 0) return strdup("root"); - if (gid == GID_NOBODY) + if (synthesize_nobody() && + gid == GID_NOBODY) return strdup(NOBODY_GROUP_NAME); if (gid_is_valid(gid)) { @@ -358,8 +362,9 @@ char* gid_to_name(gid_t gid) { } int in_gid(gid_t gid) { + long ngroups_max; gid_t *gids; - int ngroups_max, r, i; + int r, i; if (getgid() == gid) return 1; @@ -373,7 +378,7 @@ int in_gid(gid_t gid) { ngroups_max = sysconf(_SC_NGROUPS_MAX); assert(ngroups_max > 0); - gids = alloca(sizeof(gid_t) * ngroups_max); + gids = newa(gid_t, ngroups_max); r = getgroups(ngroups_max, gids); if (r < 0) @@ -426,7 +431,8 @@ int get_home_dir(char **_h) { *_h = h; return 0; } - if (u == UID_NOBODY) { + if (synthesize_nobody() && + u == UID_NOBODY) { h = strdup("/"); if (!h) return -ENOMEM; @@ -481,7 +487,8 @@ int get_shell(char **_s) { *_s = s; return 0; } - if (u == UID_NOBODY) { + if (synthesize_nobody() && + u == UID_NOBODY) { s = strdup("/sbin/nologin"); if (!s) return -ENOMEM; @@ -689,3 +696,24 @@ int maybe_setgroups(size_t size, const gid_t *list) { return 0; } + +bool synthesize_nobody(void) { + +#ifdef NOLEGACY + return true; +#else + /* Returns true when we shall synthesize the "nobody" user (which we do by default). This can be turned off by + * touching /etc/systemd/dont-synthesize-nobody in order to provide upgrade compatibility with legacy systems + * that used the "nobody" user name and group name for other UIDs/GIDs than 65534. + * + * Note that we do not employ any kind of synchronization on the following caching variable. If the variable is + * accessed in multi-threaded programs in the worst case it might happen that we initialize twice, but that + * shouldn't matter as each initialization should come to the same result. */ + static int cache = -1; + + if (cache < 0) + cache = access("/etc/systemd/dont-synthesize-nobody", F_OK) < 0; + + return cache; +#endif +} diff --git a/src/basic/user-util.h b/src/basic/user-util.h index 79adf91ee9..5f0391f2b8 100644 --- a/src/basic/user-util.h +++ b/src/basic/user-util.h @@ -97,3 +97,5 @@ bool valid_gecos(const char *d); bool valid_home(const char *p); int maybe_setgroups(size_t size, const gid_t *list); + +bool synthesize_nobody(void); diff --git a/src/basic/util.c b/src/basic/util.c index 8f9f2b902b..c7f1513f3e 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -52,6 +52,7 @@ #include "parse-util.h" #include "path-util.h" #include "process-util.h" +#include "procfs-util.h" #include "set.h" #include "signal-util.h" #include "stat-util.h" @@ -61,6 +62,7 @@ #include "umask-util.h" #include "user-util.h" #include "util.h" +#include "virt.h" int saved_argc = 0; char **saved_argv = NULL; @@ -118,45 +120,6 @@ int socket_from_display(const char *display, char **path) { return 0; } -int block_get_whole_disk(dev_t d, dev_t *ret) { - char p[SYS_BLOCK_PATH_MAX("/partition")]; - _cleanup_free_ char *s = NULL; - int r; - unsigned n, m; - - assert(ret); - - /* If it has a queue this is good enough for us */ - xsprintf_sys_block_path(p, "/queue", d); - if (access(p, F_OK) >= 0) { - *ret = d; - return 0; - } - - /* If it is a partition find the originating device */ - xsprintf_sys_block_path(p, "/partition", d); - if (access(p, F_OK) < 0) - return -ENOENT; - - /* Get parent dev_t */ - xsprintf_sys_block_path(p, "/../dev", d); - r = read_one_line_file(p, &s); - if (r < 0) - return r; - - r = sscanf(s, "%u:%u", &m, &n); - if (r != 2) - return -EINVAL; - - /* Only return this if it is really good enough for us. */ - xsprintf_sys_block_path(p, "/queue", makedev(m, n)); - if (access(p, F_OK) < 0) - return -ENOENT; - - *ret = makedev(m, n); - return 0; -} - bool kexec_loaded(void) { _cleanup_free_ char *s = NULL; @@ -184,112 +147,6 @@ int prot_from_flags(int flags) { } } -int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) { - bool stdout_is_tty, stderr_is_tty; - pid_t parent_pid, agent_pid; - sigset_t ss, saved_ss; - unsigned n, i; - va_list ap; - char **l; - - assert(pid); - assert(path); - - /* Spawns a temporary TTY agent, making sure it goes away when - * we go away */ - - parent_pid = getpid_cached(); - - /* First we temporarily block all signals, so that the new - * child has them blocked initially. This way, we can be sure - * that SIGTERMs are not lost we might send to the agent. */ - assert_se(sigfillset(&ss) >= 0); - assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0); - - agent_pid = fork(); - if (agent_pid < 0) { - assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0); - return -errno; - } - - if (agent_pid != 0) { - assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0); - *pid = agent_pid; - return 0; - } - - /* In the child: - * - * Make sure the agent goes away when the parent dies */ - if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) - _exit(EXIT_FAILURE); - - /* Make sure we actually can kill the agent, if we need to, in - * case somebody invoked us from a shell script that trapped - * SIGTERM or so... */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - - /* Check whether our parent died before we were able - * to set the death signal and unblock the signals */ - if (getppid() != parent_pid) - _exit(EXIT_SUCCESS); - - /* Don't leak fds to the agent */ - close_all_fds(except, n_except); - - stdout_is_tty = isatty(STDOUT_FILENO); - stderr_is_tty = isatty(STDERR_FILENO); - - if (!stdout_is_tty || !stderr_is_tty) { - int fd; - - /* Detach from stdout/stderr. and reopen - * /dev/tty for them. This is important to - * ensure that when systemctl is started via - * popen() or a similar call that expects to - * read EOF we actually do generate EOF and - * not delay this indefinitely by because we - * keep an unused copy of stdin around. */ - fd = open("/dev/tty", O_WRONLY); - if (fd < 0) { - log_error_errno(errno, "Failed to open /dev/tty: %m"); - _exit(EXIT_FAILURE); - } - - if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) { - log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); - _exit(EXIT_FAILURE); - } - - if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) { - log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); - _exit(EXIT_FAILURE); - } - - if (fd > STDERR_FILENO) - close(fd); - } - - /* Count arguments */ - va_start(ap, path); - for (n = 0; va_arg(ap, char*); n++) - ; - va_end(ap); - - /* Allocate strv */ - l = alloca(sizeof(char *) * (n + 1)); - - /* Fill in arguments */ - va_start(ap, path); - for (i = 0; i <= n; i++) - l[i] = va_arg(ap, char*); - va_end(ap); - - execv(path, l); - _exit(EXIT_FAILURE); -} - bool in_initrd(void) { struct statfs s; @@ -617,31 +474,22 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max) { uint64_t system_tasks_max(void) { -#if SIZEOF_PID_T == 4 -#define TASKS_MAX ((uint64_t) (INT32_MAX-1)) -#elif SIZEOF_PID_T == 2 -#define TASKS_MAX ((uint64_t) (INT16_MAX-1)) -#else -#error "Unknown pid_t size" -#endif - - _cleanup_free_ char *value = NULL, *root = NULL; uint64_t a = TASKS_MAX, b = TASKS_MAX; + _cleanup_free_ char *root = NULL; /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this * limit: * - * a) the maximum value for the pid_t type + * a) the maximum tasks value the kernel allows on this architecture * b) the cgroups pids_max attribute for the system - * c) the kernel's configure maximum PID value + * c) the kernel's configured maximum PID value * * And then pick the smallest of the three */ - if (read_one_line_file("/proc/sys/kernel/pid_max", &value) >= 0) - (void) safe_atou64(value, &a); + (void) procfs_tasks_get_limit(&a); if (cg_get_root_path(&root) >= 0) { - value = mfree(value); + _cleanup_free_ char *value = NULL; if (cg_get_attribute("pids", root, "pids.max", &value) >= 0) (void) safe_atou64(value, &b); @@ -699,131 +547,76 @@ int version(void) { return 0; } -int get_block_device(const char *path, dev_t *dev) { - struct stat st; - struct statfs sfs; - - assert(path); - assert(dev); - - /* Get's the block device directly backing a file system. If - * the block device is encrypted, returns the device mapper - * block device. */ - - if (lstat(path, &st)) - return -errno; - - if (major(st.st_dev) != 0) { - *dev = st.st_dev; - return 1; - } - - if (statfs(path, &sfs) < 0) - return -errno; - - if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) - return btrfs_get_block_device(path, dev); - - return 0; +/* This is a direct translation of str_verscmp from boot.c */ +static bool is_digit(int c) { + return c >= '0' && c <= '9'; } -int get_block_device_harder(const char *path, dev_t *dev) { - _cleanup_closedir_ DIR *d = NULL; - _cleanup_free_ char *t = NULL; - char p[SYS_BLOCK_PATH_MAX("/slaves")]; - struct dirent *de, *found = NULL; - const char *q; - unsigned maj, min; - dev_t dt; - int r; - - assert(path); - assert(dev); +static int c_order(int c) { + if (c == 0 || is_digit(c)) + return 0; - /* Gets the backing block device for a file system, and - * handles LUKS encrypted file systems, looking for its - * immediate parent, if there is one. */ + if ((c >= 'a') && (c <= 'z')) + return c; - r = get_block_device(path, &dt); - if (r <= 0) - return r; + return c + 0x10000; +} - xsprintf_sys_block_path(p, "/slaves", dt); - d = opendir(p); - if (!d) { - if (errno == ENOENT) - goto fallback; +int str_verscmp(const char *s1, const char *s2) { + const char *os1, *os2; - return -errno; - } + assert(s1); + assert(s2); - FOREACH_DIRENT_ALL(de, d, return -errno) { + os1 = s1; + os2 = s2; - if (dot_or_dot_dot(de->d_name)) - continue; + while (*s1 || *s2) { + int first; - if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN)) - continue; + while ((*s1 && !is_digit(*s1)) || (*s2 && !is_digit(*s2))) { + int order; - if (found) { - _cleanup_free_ char *u = NULL, *v = NULL, *a = NULL, *b = NULL; - - /* We found a device backed by multiple other devices. We don't really support automatic - * discovery on such setups, with the exception of dm-verity partitions. In this case there are - * two backing devices: the data partition and the hash partition. We are fine with such - * setups, however, only if both partitions are on the same physical device. Hence, let's - * verify this. */ - - u = strjoin(p, "/", de->d_name, "/../dev"); - if (!u) - return -ENOMEM; - - v = strjoin(p, "/", found->d_name, "/../dev"); - if (!v) - return -ENOMEM; - - r = read_one_line_file(u, &a); - if (r < 0) { - log_debug_errno(r, "Failed to read %s: %m", u); - goto fallback; - } - - r = read_one_line_file(v, &b); - if (r < 0) { - log_debug_errno(r, "Failed to read %s: %m", v); - goto fallback; - } - - /* Check if the parent device is the same. If not, then the two backing devices are on - * different physical devices, and we don't support that. */ - if (!streq(a, b)) - goto fallback; + order = c_order(*s1) - c_order(*s2); + if (order != 0) + return order; + s1++; + s2++; } - found = de; - } - - if (!found) - goto fallback; + while (*s1 == '0') + s1++; + while (*s2 == '0') + s2++; + + first = 0; + while (is_digit(*s1) && is_digit(*s2)) { + if (first == 0) + first = *s1 - *s2; + s1++; + s2++; + } - q = strjoina(p, "/", found->d_name, "/dev"); + if (is_digit(*s1)) + return 1; + if (is_digit(*s2)) + return -1; - r = read_one_line_file(q, &t); - if (r == -ENOENT) - goto fallback; - if (r < 0) - return r; + if (first != 0) + return first; + } - if (sscanf(t, "%u:%u", &maj, &min) != 2) - return -EINVAL; + return strcmp(os1, os2); +} - if (maj == 0) - goto fallback; +/* Turn off core dumps but only if we're running outside of a container. */ +void disable_coredumps(void) { + int r; - *dev = makedev(maj, min); - return 1; + if (detect_container() > 0) + return; -fallback: - *dev = dt; - return 1; + r = write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0); + if (r < 0) + log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m"); } diff --git a/src/basic/util.h b/src/basic/util.h index a79907de3e..9d1b10756b 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -71,8 +71,6 @@ bool plymouth_running(void); bool display_is_local(const char *display) _pure_; int socket_from_display(const char *display, char **path); -int block_get_whole_disk(dev_t d, dev_t *ret); - #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) @@ -86,8 +84,6 @@ bool kexec_loaded(void); int prot_from_flags(int flags) _const_; -int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...); - bool in_initrd(void); void in_initrd_force(bool value); @@ -194,5 +190,6 @@ int update_reboot_parameter_and_warn(const char *param); int version(void); -int get_block_device(const char *path, dev_t *dev); -int get_block_device_harder(const char *path, dev_t *dev); +int str_verscmp(const char *s1, const char *s2); + +void disable_coredumps(void); diff --git a/src/basic/verbs.c b/src/basic/verbs.c index cb42e6dd08..47644670da 100644 --- a/src/basic/verbs.c +++ b/src/basic/verbs.c @@ -22,13 +22,48 @@ #include <getopt.h> #include <stdbool.h> #include <stddef.h> +#include <string.h> +#include "env-util.h" #include "log.h" #include "macro.h" +#include "process-util.h" #include "string-util.h" #include "verbs.h" #include "virt.h" +/* Wraps running_in_chroot() which is used in various places, but also adds an environment variable check so external + * processes can reliably force this on. + */ +bool running_in_chroot_or_offline(void) { + int r; + + /* Added to support use cases like rpm-ostree, where from %post scripts we only want to execute "preset", but + * not "start"/"restart" for example. + * + * See ENVIRONMENT.md for docs. + */ + r = getenv_bool("SYSTEMD_OFFLINE"); + if (r < 0 && r != -ENXIO) + log_debug_errno(r, "Failed to parse $SYSTEMD_OFFLINE: %m"); + else if (r >= 0) + return r > 0; + + /* We've had this condition check for a long time which basically checks for legacy chroot case like Fedora's + * "mock", which is used for package builds. We don't want to try to start systemd services there, since + * without --new-chroot we don't even have systemd running, and even if we did, adding a concept of background + * daemons to builds would be an enormous change, requiring considering things like how the journal output is + * handled, etc. And there's really not a use case today for a build talking to a service. + * + * Note this call itself also looks for a different variable SYSTEMD_IGNORE_CHROOT=1. + */ + r = running_in_chroot(); + if (r < 0) + log_debug_errno(r, "running_in_chroot(): %m"); + + return r > 0; +} + int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) { const Verb *verb; const char *name; @@ -84,12 +119,15 @@ int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) { return -EINVAL; } - if ((verb->flags & VERB_NOCHROOT) && running_in_chroot() > 0) { - log_info("Running in chroot, ignoring request."); + if ((verb->flags & VERB_ONLINE_ONLY) && running_in_chroot_or_offline()) { + if (name) + log_info("Running in chroot, ignoring request: %s", name); + else + log_info("Running in chroot, ignoring request."); return 0; } - if (verb->flags & VERB_MUSTBEROOT) { + if (verb->flags & VERB_MUST_BE_ROOT) { r = must_be_root(); if (r < 0) return r; diff --git a/src/basic/verbs.h b/src/basic/verbs.h index 5f44a18f8e..d9259fc45f 100644 --- a/src/basic/verbs.h +++ b/src/basic/verbs.h @@ -23,9 +23,9 @@ #define VERB_ANY ((unsigned) -1) typedef enum VerbFlags { - VERB_DEFAULT = 1 << 0, - VERB_NOCHROOT = 1 << 1, - VERB_MUSTBEROOT = 1 << 2, + VERB_DEFAULT = 1 << 0, + VERB_ONLINE_ONLY = 1 << 1, + VERB_MUST_BE_ROOT = 1 << 2, } VerbFlags; typedef struct { @@ -35,4 +35,6 @@ typedef struct { int (* const dispatch)(int argc, char *argv[], void *userdata); } Verb; +bool running_in_chroot_or_offline(void); + int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata); diff --git a/src/basic/virt.c b/src/basic/virt.c index b0db28add6..f4796b53bc 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -18,6 +18,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#if defined(__i386__) || defined(__x86_64__) +#include <cpuid.h> +#endif #include <errno.h> #include <stdint.h> #include <stdlib.h> @@ -56,30 +59,14 @@ static int detect_vm_cpuid(void) { { "bhyve bhyve ", VIRTUALIZATION_BHYVE }, }; - uint32_t eax, ecx; + uint32_t eax, ebx, ecx, edx; bool hypervisor; /* http://lwn.net/Articles/301888/ */ -#if defined (__i386__) -#define REG_a "eax" -#define REG_b "ebx" -#elif defined (__amd64__) -#define REG_a "rax" -#define REG_b "rbx" -#endif - /* First detect whether there is a hypervisor */ - eax = 1; - __asm__ __volatile__ ( - /* ebx/rbx is being used for PIC! */ - " push %%"REG_b" \n\t" - " cpuid \n\t" - " pop %%"REG_b" \n\t" - - : "=a" (eax), "=c" (ecx) - : "0" (eax) - ); + if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0) + return VIRTUALIZATION_NONE; hypervisor = !!(ecx & 0x80000000U); @@ -91,17 +78,11 @@ static int detect_vm_cpuid(void) { unsigned j; /* There is a hypervisor, see what it is */ - eax = 0x40000000U; - __asm__ __volatile__ ( - /* ebx/rbx is being used for PIC! */ - " push %%"REG_b" \n\t" - " cpuid \n\t" - " mov %%ebx, %1 \n\t" - " pop %%"REG_b" \n\t" - - : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2]) - : "0" (eax) - ); + __cpuid(0x40000000U, eax, ebx, ecx, edx); + + sig.sig32[0] = ebx; + sig.sig32[1] = ecx; + sig.sig32[2] = edx; log_debug("Virtualization found, CPUID=%s", sig.text); @@ -241,8 +222,10 @@ static int detect_vm_xen_dom0(void) { if (r == 0) { unsigned long features; - r = safe_atolu(domcap, &features); - if (r == 0) { + /* Here, we need to use sscanf() instead of safe_atoul() + * as the string lacks the leading "0x". */ + r = sscanf(domcap, "%lx", &features); + if (r == 1) { r = !!(features & (1U << XENFEAT_dom0)); log_debug("Virtualization XEN, found %s with value %08lx, " "XENFEAT_dom0 (indicating the 'hardware domain') is%s set.", diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 59c1af73de..ae034f5cdb 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -36,6 +36,8 @@ #include <sys/statfs.h> #include <unistd.h> +#include "sd-id128.h" + #include "alloc-util.h" #include "blkid-util.h" #include "bootspec.h" @@ -294,7 +296,7 @@ static int status_entries(const char *esp_path, sd_id128_t partition) { esp_path); if (config.default_entry < 0) - printf("%zu entries, no entry suitable as default", config.n_entries); + printf("%zu entries, no entry suitable as default\n", config.n_entries); else { const BootEntry *e = &config.entries[config.default_entry]; @@ -948,12 +950,13 @@ static int verb_status(int argc, char *argv[], void *userdata) { * can show */ if (is_efi_boot()) { - _cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL; + _cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL; sd_id128_t loader_part_uuid = SD_ID128_NULL; read_loader_efi_var("LoaderFirmwareType", &fw_type); read_loader_efi_var("LoaderFirmwareInfo", &fw_info); read_loader_efi_var("LoaderInfo", &loader); + read_loader_efi_var("StubInfo", &stub); read_loader_efi_var("LoaderImageIdentifier", &loader_path); if (loader_path) @@ -981,6 +984,8 @@ static int verb_status(int argc, char *argv[], void *userdata) { printf("Current Loader:\n"); printf(" Product: %s\n", strna(loader)); + if (stub) + printf(" Stub: %s\n", stub); if (!sd_id128_is_null(loader_part_uuid)) printf(" ESP: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", SD_ID128_FORMAT_VAL(loader_part_uuid)); @@ -1043,7 +1048,7 @@ static int verb_list(int argc, char *argv[], void *userdata) { boot_entry_title(e), ansi_normal(), ansi_highlight_green(), - n == config.default_entry ? " (default)" : "", + n == (unsigned) config.default_entry ? " (default)" : "", ansi_normal()); if (e->version) printf(" version: %s\n", e->version); @@ -1139,12 +1144,12 @@ static int verb_remove(int argc, char *argv[], void *userdata) { static int bootctl_main(int argc, char *argv[]) { static const Verb verbs[] = { - { "help", VERB_ANY, VERB_ANY, 0, help }, - { "status", VERB_ANY, 1, VERB_DEFAULT, verb_status }, - { "list", VERB_ANY, 1, 0, verb_list }, - { "install", VERB_ANY, 1, VERB_MUSTBEROOT, verb_install }, - { "update", VERB_ANY, 1, VERB_MUSTBEROOT, verb_install }, - { "remove", VERB_ANY, 1, VERB_MUSTBEROOT, verb_remove }, + { "help", VERB_ANY, VERB_ANY, 0, help }, + { "status", VERB_ANY, 1, VERB_DEFAULT, verb_status }, + { "list", VERB_ANY, 1, 0, verb_list }, + { "install", VERB_ANY, 1, VERB_MUST_BE_ROOT, verb_install }, + { "update", VERB_ANY, 1, VERB_MUST_BE_ROOT, verb_install }, + { "remove", VERB_ANY, 1, VERB_MUST_BE_ROOT, verb_remove }, {} }; diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index ea9f39a7e7..06331da2d4 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -166,7 +166,7 @@ static BOOLEAN line_edit(CHAR16 *line_in, CHAR16 **line_out, UINTN x_max, UINTN case KEYPRESS(EFI_ALT_PRESSED, 0, 'f'): case KEYPRESS(EFI_CONTROL_PRESSED, SCAN_RIGHT, 0): /* forward-word */ - while (line[first + cursor] && line[first + cursor] == ' ') + while (line[first + cursor] == ' ') cursor_right(&cursor, &first, x_max, len); while (line[first + cursor] && line[first + cursor] != ' ') cursor_right(&cursor, &first, x_max, len); diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c index be4fea84a2..5aaffe8fa5 100644 --- a/src/boot/efi/measure.c +++ b/src/boot/efi/measure.c @@ -232,8 +232,11 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 p */ static EFI_STATUS trigger_tcg2_final_events_table(const EFI_TCG2 *tcg, EFI_TCG2_EVENT_LOG_FORMAT log_fmt) { + EFI_PHYSICAL_ADDRESS loc; + EFI_PHYSICAL_ADDRESS last_loc; + BOOLEAN truncated; return uefi_call_wrapper(tcg->GetEventLog, 5, (EFI_TCG2 *) tcg, - log_fmt, 0, 0, 0); + log_fmt, &loc, &last_loc, &truncated); } static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer, diff --git a/src/boot/efi/no-undefined-symbols.sh b/src/boot/efi/no-undefined-symbols.sh index 08b266c455..8572ceedfa 100755 --- a/src/boot/efi/no-undefined-symbols.sh +++ b/src/boot/efi/no-undefined-symbols.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu if nm -D -u "$1" | grep ' U '; then echo "Undefined symbols detected!" diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index e917019c0c..ff45cebd45 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -104,6 +104,30 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS) efivar_set(L"LoaderDevicePartUUID", uuid, FALSE); + /* if LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from UEFI */ + if (efivar_get_raw(&global_guid, L"LoaderImageIdentifier", &b, &size) != EFI_SUCCESS) { + CHAR16 *loaded_image_path = DevicePathToStr(loaded_image->FilePath); + efivar_set(L"LoaderImageIdentifier", loaded_image_path, FALSE); + FreePool(loaded_image_path); + } + + /* if LoaderFirmwareInfo is not set, let's set it */ + if (efivar_get_raw(&global_guid, L"LoaderFirmwareInfo", &b, &size) != EFI_SUCCESS) { + CHAR16 *loader_firmware_info = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); + efivar_set(L"LoaderFirmwareInfo", loader_firmware_info, FALSE); + FreePool(loader_firmware_info); + } + /* ditto for LoaderFirmwareType */ + if (efivar_get_raw(&global_guid, L"LoaderFirmwareType", &b, &size) != EFI_SUCCESS) { + CHAR16 *loader_firmware_type = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); + efivar_set(L"LoaderFirmwareType", loader_firmware_type, FALSE); + FreePool(loader_firmware_type); + } + + /* add StubInfo */ + if (efivar_get_raw(&global_guid, L"StubInfo", &b, &size) != EFI_SUCCESS) + efivar_set(L"StubInfo", L"systemd-stub " PACKAGE_VERSION, FALSE); + if (szs[3] > 0) graphics_splash((UINT8 *)((UINTN)loaded_image->ImageBase + addrs[3]), szs[3], NULL); diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 7a8d6ba5ac..f8c43b5079 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -62,6 +62,7 @@ static bool arg_expect_reply = true; static bool arg_auto_start = true; static bool arg_allow_interactive_authorization = true; static bool arg_augment_creds = true; +static bool arg_watch_bind = false; static usec_t arg_timeout = 0; #define NAME_IS_ACQUIRED INT_TO_PTR(1) @@ -1735,7 +1736,9 @@ static int help(void) { " --allow-interactive-authorization=BOOL\n" " Allow interactive authorization for operation\n" " --timeout=SECS Maximum time to wait for method call completion\n" - " --augment-creds=BOOL Extend credential data with data read from /proc/$PID\n\n" + " --augment-creds=BOOL Extend credential data with data read from /proc/$PID\n" + " --watch-bind=BOOL Wait for bus AF_UNIX socket to be bound in the file\n" + " system\n\n" "Commands:\n" " list List bus names\n" " status [SERVICE] Show bus service, process or bus owner credentials\n" @@ -1777,6 +1780,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_ALLOW_INTERACTIVE_AUTHORIZATION, ARG_TIMEOUT, ARG_AUGMENT_CREDS, + ARG_WATCH_BIND, }; static const struct option options[] = { @@ -1803,6 +1807,7 @@ static int parse_argv(int argc, char *argv[]) { { "allow-interactive-authorization", required_argument, NULL, ARG_ALLOW_INTERACTIVE_AUTHORIZATION }, { "timeout", required_argument, NULL, ARG_TIMEOUT }, { "augment-creds",required_argument, NULL, ARG_AUGMENT_CREDS}, + { "watch-bind", required_argument, NULL, ARG_WATCH_BIND }, {}, }; @@ -1953,6 +1958,16 @@ static int parse_argv(int argc, char *argv[]) { arg_augment_creds = !!r; break; + case ARG_WATCH_BIND: + r = parse_boolean(optarg); + if (r < 0) { + log_error("Failed to parse --watch-bind= parameter."); + return r; + } + + arg_watch_bind = !!r; + break; + case '?': return -EINVAL; @@ -2002,7 +2017,7 @@ static int busctl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char *argv[]) { - _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + sd_bus *bus = NULL; int r; log_parse_environment(); @@ -2051,6 +2066,12 @@ int main(int argc, char *argv[]) { goto finish; } + r = sd_bus_set_watch_bind(bus, arg_watch_bind); + if (r < 0) { + log_error_errno(r, "Failed to set watch-bind setting to '%s': %m", yes_no(arg_watch_bind)); + goto finish; + } + if (arg_address) r = sd_bus_set_address(bus, arg_address); else { @@ -2092,6 +2113,9 @@ int main(int argc, char *argv[]) { r = busctl_main(bus, argc, argv); finish: + /* make sure we terminate the bus connection first, and then close the + * pager, see issue #3543 for the details. */ + sd_bus_flush_close_unref(bus); pager_close(); strv_free(arg_matches); diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index fb44b9f669..bd8c6a0059 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -277,9 +277,9 @@ int main(int argc, char *argv[]) { if (!arg_machine) { _cleanup_free_ char *cwd = NULL; - cwd = get_current_dir_name(); - if (!cwd) { - r = log_error_errno(errno, "Cannot determine current working directory: %m"); + r = safe_getcwd(&cwd); + if (r < 0) { + log_error_errno(r, "Cannot determine current working directory: %m"); goto finish; } diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index fe339eb493..1a73fb099d 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -40,7 +40,9 @@ #include "parse-util.h" #include "path-util.h" #include "process-util.h" +#include "procfs-util.h" #include "stdio-util.h" +#include "strv.h" #include "terminal-util.h" #include "unit-name.h" #include "util.h" @@ -193,26 +195,33 @@ static int process( g->n_tasks_valid = true; } else if (streq(controller, "pids") && arg_count == COUNT_PIDS) { - _cleanup_free_ char *p = NULL, *v = NULL; - r = cg_get_path(controller, path, "pids.current", &p); - if (r < 0) - return r; + if (isempty(path) || path_equal(path, "/")) { + r = procfs_tasks_get_current(&g->n_tasks); + if (r < 0) + return r; + } else { + _cleanup_free_ char *p = NULL, *v = NULL; - r = read_one_line_file(p, &v); - if (r == -ENOENT) - return 0; - if (r < 0) - return r; + r = cg_get_path(controller, path, "pids.current", &p); + if (r < 0) + return r; - r = safe_atou64(v, &g->n_tasks); - if (r < 0) - return r; + r = read_one_line_file(p, &v); + if (r == -ENOENT) + return 0; + if (r < 0) + return r; + + r = safe_atou64(v, &g->n_tasks); + if (r < 0) + return r; + } if (g->n_tasks > 0) g->n_tasks_valid = true; - } else if (streq(controller, "cpu") || streq(controller, "cpuacct")) { + } else if (STR_IN_SET(controller, "cpu", "cpuacct")) { _cleanup_free_ char *p = NULL, *v = NULL; uint64_t new_usage; nsec_t timestamp; diff --git a/src/core/automount.c b/src/core/automount.c index 28d5cc3917..c191336c0e 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -578,7 +578,7 @@ static void automount_enter_waiting(Automount *a) { set_clear(a->tokens); - r = unit_fail_if_symlink(UNIT(a), a->where); + r = unit_fail_if_noncanonical(UNIT(a), a->where); if (r < 0) goto fail; diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 78ef885b06..97b3756567 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -22,6 +22,7 @@ #include <fnmatch.h> #include "alloc-util.h" +#include "blockdev-util.h" #include "bpf-firewall.h" #include "cgroup-util.h" #include "cgroup.h" @@ -31,6 +32,7 @@ #include "parse-util.h" #include "path-util.h" #include "process-util.h" +#include "procfs-util.h" #include "special.h" #include "stdio-util.h" #include "string-table.h" @@ -38,6 +40,18 @@ #define CGROUP_CPU_QUOTA_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC) +bool unit_has_root_cgroup(Unit *u) { + assert(u); + + /* Returns whether this unit manages the root cgroup. Note that this is different from being named "-.slice", + * as inside of containers the root slice won't be identical to the root cgroup. */ + + if (!u->cgroup_path) + return false; + + return isempty(u->cgroup_path) || path_equal(u->cgroup_path, "/"); +} + static void cgroup_compat_warn(void) { static bool cgroup_compat_warned = false; @@ -307,7 +321,7 @@ static int lookup_block_device(const char *p, dev_t *dev) { /* If this is a partition, try to get the originating * block device */ - block_get_whole_disk(*dev, dev); + (void) block_get_whole_disk(*dev, dev); } else { log_warning("%s is not a block device and file system block device cannot be determined or is not local.", p); return -ENODEV; @@ -707,21 +721,17 @@ static void cgroup_context_apply( assert(u); - c = unit_get_cgroup_context(u); - path = u->cgroup_path; - - assert(c); - assert(path); - /* Nothing to do? Exit early! */ if (apply_mask == 0 && !apply_bpf) return; - /* Some cgroup attributes are not supported on the root cgroup, - * hence silently ignore */ - is_root = isempty(path) || path_equal(path, "/"); - if (is_root) - /* Make sure we don't try to display messages with an empty path. */ + /* Some cgroup attributes are not supported on the root cgroup, hence silently ignore */ + is_root = unit_has_root_cgroup(u); + + assert_se(c = unit_get_cgroup_context(u)); + assert_se(path = u->cgroup_path); + + if (is_root) /* Make sure we don't try to display messages with an empty path. */ path = "/"; /* We generally ignore errors caused by read-only mounted @@ -977,7 +987,7 @@ static void cgroup_context_apply( "/dev/random\0" "rwm\0" "/dev/urandom\0" "rwm\0" "/dev/tty\0" "rwm\0" - "/dev/pts/ptmx\0" "rw\0" /* /dev/pts/ptmx may not be duplicated, but accessed */ + "/dev/ptmx\0" "rwm\0" /* Allow /run/systemd/inaccessible/{chr,blk} devices for mapping InaccessiblePaths */ "-/run/systemd/inaccessible/chr\0" "rwm\0" "-/run/systemd/inaccessible/blk\0" "rwm\0"; @@ -987,6 +997,7 @@ static void cgroup_context_apply( NULSTR_FOREACH_PAIR(x, y, auto_devices) whitelist_device(path, x, y); + /* PTS (/dev/pts) devices may not be duplicated, but accessed */ whitelist_major(path, "pts", 'c', "rw"); } @@ -1017,19 +1028,46 @@ static void cgroup_context_apply( } } - if ((apply_mask & CGROUP_MASK_PIDS) && !is_root) { + if (apply_mask & CGROUP_MASK_PIDS) { + + if (is_root) { + /* So, the "pids" controller does not expose anything on the root cgroup, in order not to + * replicate knobs exposed elsewhere needlessly. We abstract this away here however, and when + * the knobs of the root cgroup are modified propagate this to the relevant sysctls. There's a + * non-obvious asymmetry however: unlike the cgroup properties we don't really want to take + * exclusive ownership of the sysctls, but we still want to honour things if the user sets + * limits. Hence we employ sort of a one-way strategy: when the user sets a bounded limit + * through us it counts. When the user afterwards unsets it again (i.e. sets it to unbounded) + * it also counts. But if the user never set a limit through us (i.e. we are the default of + * "unbounded") we leave things unmodified. For this we manage a global boolean that we turn on + * the first time we set a limit. Note that this boolean is flushed out on manager reload, + * which is desirable so that there's an offical way to release control of the sysctl from + * systemd: set the limit to unbounded and reload. */ + + if (c->tasks_max != CGROUP_LIMIT_MAX) { + u->manager->sysctl_pid_max_changed = true; + r = procfs_tasks_set_limit(c->tasks_max); + } else if (u->manager->sysctl_pid_max_changed) + r = procfs_tasks_set_limit(TASKS_MAX); + else + r = 0; - if (c->tasks_max != CGROUP_LIMIT_MAX) { - char buf[DECIMAL_STR_MAX(uint64_t) + 2]; + if (r < 0) + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to write to tasks limit sysctls: %m"); - sprintf(buf, "%" PRIu64 "\n", c->tasks_max); - r = cg_set_attribute("pids", path, "pids.max", buf); - } else - r = cg_set_attribute("pids", path, "pids.max", "max"); + } else { + if (c->tasks_max != CGROUP_LIMIT_MAX) { + char buf[DECIMAL_STR_MAX(uint64_t) + 2]; - if (r < 0) - log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, - "Failed to set pids.max: %m"); + sprintf(buf, "%" PRIu64 "\n", c->tasks_max); + r = cg_set_attribute("pids", path, "pids.max", buf); + } else + r = cg_set_attribute("pids", path, "pids.max", "max"); + if (r < 0) + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to set pids.max: %m"); + } } if (apply_bpf) @@ -1060,7 +1098,7 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c) { mask |= CGROUP_MASK_DEVICES; if (c->tasks_accounting || - c->tasks_max != (uint64_t) -1) + c->tasks_max != CGROUP_LIMIT_MAX) mask |= CGROUP_MASK_PIDS; return mask; @@ -1825,6 +1863,31 @@ static int unit_watch_pids_in_path(Unit *u, const char *path) { return ret; } +int unit_synthesize_cgroup_empty_event(Unit *u) { + int r; + + assert(u); + + /* Enqueue a synthetic cgroup empty event if this unit doesn't watch any PIDs anymore. This is compatibility + * support for non-unified systems where notifications aren't reliable, and hence need to take whatever we can + * get as notification source as soon as we stopped having any useful PIDs to watch for. */ + + if (!u->cgroup_path) + return -ENOENT; + + r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER); + if (r < 0) + return r; + if (r > 0) /* On unified we have reliable notifications, and don't need this */ + return 0; + + if (!set_isempty(u->pids)) + return 0; + + unit_add_to_cgroup_empty_queue(u); + return 0; +} + int unit_watch_all_pids(Unit *u) { int r; @@ -2159,40 +2222,46 @@ Unit* manager_get_unit_by_cgroup(Manager *m, const char *cgroup) { Unit *manager_get_unit_by_pid_cgroup(Manager *m, pid_t pid) { _cleanup_free_ char *cgroup = NULL; - int r; assert(m); - if (pid <= 0) + if (!pid_is_valid(pid)) return NULL; - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup); - if (r < 0) + if (cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup) < 0) return NULL; return manager_get_unit_by_cgroup(m, cgroup); } Unit *manager_get_unit_by_pid(Manager *m, pid_t pid) { - Unit *u; + Unit *u, **array; assert(m); - if (pid <= 0) + /* Note that a process might be owned by multiple units, we return only one here, which is good enough for most + * cases, though not strictly correct. We prefer the one reported by cgroup membership, as that's the most + * relevant one as children of the process will be assigned to that one, too, before all else. */ + + if (!pid_is_valid(pid)) return NULL; - if (pid == 1) + if (pid == getpid_cached()) return hashmap_get(m->units, SPECIAL_INIT_SCOPE); - u = hashmap_get(m->watch_pids1, PID_TO_PTR(pid)); + u = manager_get_unit_by_pid_cgroup(m, pid); if (u) return u; - u = hashmap_get(m->watch_pids2, PID_TO_PTR(pid)); + u = hashmap_get(m->watch_pids, PID_TO_PTR(pid)); if (u) return u; - return manager_get_unit_by_pid_cgroup(m, pid); + array = hashmap_get(m->watch_pids, PID_TO_PTR(-pid)); + if (array) + return array[0]; + + return NULL; } int manager_notify_cgroup_empty(Manager *m, const char *cgroup) { @@ -2261,6 +2330,10 @@ int unit_get_tasks_current(Unit *u, uint64_t *ret) { if ((u->cgroup_realized_mask & CGROUP_MASK_PIDS) == 0) return -ENODATA; + /* The root cgroup doesn't expose this information, let's get it from /proc instead */ + if (unit_has_root_cgroup(u)) + return procfs_tasks_get_current(ret); + r = cg_get_attribute("pids", u->cgroup_path, "pids.current", &v); if (r == -ENOENT) return -ENODATA; diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 0c5bb4a2c8..1f50441412 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -192,6 +192,8 @@ Unit* manager_get_unit_by_pid(Manager *m, pid_t pid); int unit_search_main_pid(Unit *u, pid_t *ret); int unit_watch_all_pids(Unit *u); +int unit_synthesize_cgroup_empty_event(Unit *u); + int unit_get_memory_current(Unit *u, uint64_t *ret); int unit_get_tasks_current(Unit *u, uint64_t *ret); int unit_get_cpu_usage(Unit *u, nsec_t *ret); @@ -206,6 +208,8 @@ int unit_reset_ip_accounting(Unit *u); cc ? cc->name : false; \ }) +bool unit_has_root_cgroup(Unit *u); + int manager_notify_cgroup_empty(Manager *m, const char *group); void unit_invalidate_cgroup(Unit *u, CGroupMask m); diff --git a/src/core/dbus-automount.c b/src/core/dbus-automount.c index 4b1b86f7b9..113d352a43 100644 --- a/src/core/dbus-automount.c +++ b/src/core/dbus-automount.c @@ -21,6 +21,7 @@ #include "automount.h" #include "bus-util.h" #include "dbus-automount.h" +#include "dbus-util.h" #include "string-util.h" static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, automount_result, AutomountResult); @@ -41,7 +42,7 @@ static int bus_automount_set_transient_property( UnitWriteFlags flags, sd_bus_error *error) { - int r; + Unit *u = UNIT(a); assert(a); assert(name); @@ -49,24 +50,16 @@ static int bus_automount_set_transient_property( flags |= UNIT_PRIVATE; - if (streq(name, "TimeoutIdleUSec")) { - usec_t timeout_idle_usec; + if (streq(name, "Where")) + return bus_set_transient_path(u, name, &a->where, message, flags, error); - r = sd_bus_message_read(message, "t", &timeout_idle_usec); - if (r < 0) - return r; + if (streq(name, "TimeoutIdleUSec")) + return bus_set_transient_usec_fix_0(u, name, &a->timeout_idle_usec, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - char time[FORMAT_TIMESPAN_MAX]; + if (streq(name, "DirectoryMode")) + return bus_set_transient_mode_t(u, name, &a->directory_mode, message, flags, error); - a->timeout_idle_usec = timeout_idle_usec; - unit_write_settingf(UNIT(a), flags, name, "TimeoutIdleSec=%s\n", - format_timespan(time, sizeof(time), timeout_idle_usec, USEC_PER_MSEC)); - } - } else - return 0; - - return 1; + return 0; } int bus_automount_set_property( diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index abca4e112d..f8d90d4b3a 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -28,6 +28,7 @@ #include "cgroup-util.h" #include "cgroup.h" #include "dbus-cgroup.h" +#include "dbus-util.h" #include "fd-util.h" #include "fileio.h" #include "path-util.h" @@ -413,6 +414,41 @@ static int bus_cgroup_set_transient_property( return 0; } +static int bus_cgroup_set_boolean( + Unit *u, + const char *name, + bool *p, + CGroupMask mask, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + int b, r; + + assert(p); + + r = sd_bus_message_read(message, "b", &b); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + *p = b; + unit_invalidate_cgroup(u, mask); + unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b)); + } + + return 1; +} + +static BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight, CGROUP_MASK_CPU, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID,); +static BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_OK, CGROUP_CPU_SHARES_INVALID,); +static BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID,); +static BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEIGHT_IS_OK, CGROUP_BLKIO_WEIGHT_INVALID,); +static BUS_DEFINE_SET_CGROUP_WEIGHT(memory, CGROUP_MASK_MEMORY, , CGROUP_LIMIT_MAX, "infinity"); +static BUS_DEFINE_SET_CGROUP_WEIGHT(tasks_max, CGROUP_MASK_PIDS, , (uint64_t) -1, "infinity"); +static BUS_DEFINE_SET_CGROUP_SCALE(memory, CGROUP_MASK_MEMORY, physical_memory_scale); +static BUS_DEFINE_SET_CGROUP_SCALE(tasks_max, CGROUP_MASK_PIDS, system_tasks_max_scale); + int bus_cgroup_set_property( Unit *u, CGroupContext *c, @@ -431,110 +467,82 @@ int bus_cgroup_set_property( flags |= UNIT_PRIVATE; - if (streq(name, "CPUAccounting")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->cpu_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU); - unit_write_settingf(u, flags, name, "CPUAccounting=%s", yes_no(b)); - } + if (streq(name, "CPUAccounting")) + return bus_cgroup_set_boolean(u, name, &c->cpu_accounting, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU, message, flags, error); - return 1; + if (streq(name, "CPUWeight")) + return bus_cgroup_set_cpu_weight(u, name, &c->cpu_weight, message, flags, error); - } else if (streq(name, "CPUWeight")) { - uint64_t weight; - - r = sd_bus_message_read(message, "t", &weight); - if (r < 0) - return r; + if (streq(name, "StartupCPUWeight")) + return bus_cgroup_set_cpu_weight(u, name, &c->startup_cpu_weight, message, flags, error); - if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "CPUWeight= value out of range"); + if (streq(name, "CPUShares")) + return bus_cgroup_set_cpu_shares(u, name, &c->cpu_shares, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->cpu_weight = weight; - unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + if (streq(name, "StartupCPUShares")) + return bus_cgroup_set_cpu_shares(u, name, &c->startup_cpu_shares, message, flags, error); - if (weight == CGROUP_WEIGHT_INVALID) - unit_write_setting(u, flags, name, "CPUWeight="); - else - unit_write_settingf(u, flags, name, "CPUWeight=%" PRIu64, weight); - } + if (streq(name, "IOAccounting")) + return bus_cgroup_set_boolean(u, name, &c->io_accounting, CGROUP_MASK_IO, message, flags, error); - return 1; + if (streq(name, "IOWeight")) + return bus_cgroup_set_io_weight(u, name, &c->io_weight, message, flags, error); - } else if (streq(name, "StartupCPUWeight")) { - uint64_t weight; + if (streq(name, "StartupIOWeight")) + return bus_cgroup_set_io_weight(u, name, &c->startup_io_weight, message, flags, error); - r = sd_bus_message_read(message, "t", &weight); - if (r < 0) - return r; + if (streq(name, "BlockIOAccounting")) + return bus_cgroup_set_boolean(u, name, &c->blockio_accounting, CGROUP_MASK_BLKIO, message, flags, error); - if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupCPUWeight= value out of range"); + if (streq(name, "BlockIOWeight")) + return bus_cgroup_set_blockio_weight(u, name, &c->blockio_weight, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->startup_cpu_weight = weight; - unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + if (streq(name, "StartupBlockIOWeight")) + return bus_cgroup_set_blockio_weight(u, name, &c->startup_blockio_weight, message, flags, error); - if (weight == CGROUP_CPU_SHARES_INVALID) - unit_write_setting(u, flags, name, "StartupCPUWeight="); - else - unit_write_settingf(u, flags, name, "StartupCPUWeight=%" PRIu64, weight); - } + if (streq(name, "MemoryAccounting")) + return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error); - return 1; + if (streq(name, "MemoryLow")) + return bus_cgroup_set_memory(u, name, &c->memory_low, message, flags, error); - } else if (streq(name, "CPUShares")) { - uint64_t shares; + if (streq(name, "MemoryHigh")) + return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error); - r = sd_bus_message_read(message, "t", &shares); - if (r < 0) - return r; + if (streq(name, "MemorySwapMax")) + return bus_cgroup_set_memory(u, name, &c->memory_swap_max, message, flags, error); - if (!CGROUP_CPU_SHARES_IS_OK(shares)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "CPUShares= value out of range"); + if (streq(name, "MemoryMax")) + return bus_cgroup_set_memory(u, name, &c->memory_max, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->cpu_shares = shares; - unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + if (streq(name, "MemoryLimit")) + return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error); - if (shares == CGROUP_CPU_SHARES_INVALID) - unit_write_setting(u, flags, name, "CPUShares="); - else - unit_write_settingf(u, flags, name, "CPUShares=%" PRIu64, shares); - } + if (streq(name, "MemoryLowScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_low, message, flags, error); - return 1; + if (streq(name, "MemoryHighScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error); - } else if (streq(name, "StartupCPUShares")) { - uint64_t shares; + if (streq(name, "MemorySwapMaxScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_swap_max, message, flags, error); - r = sd_bus_message_read(message, "t", &shares); - if (r < 0) - return r; + if (streq(name, "MemoryMaxScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_max, message, flags, error); - if (!CGROUP_CPU_SHARES_IS_OK(shares)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupCPUShares= value out of range"); + if (streq(name, "MemoryLimitScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_limit, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->startup_cpu_shares = shares; - unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + if (streq(name, "TasksAccounting")) + return bus_cgroup_set_boolean(u, name, &c->tasks_accounting, CGROUP_MASK_PIDS, message, flags, error); - if (shares == CGROUP_CPU_SHARES_INVALID) - unit_write_setting(u, flags, name, "StartupCPUShares="); - else - unit_write_settingf(u, flags, name, "StartupCPUShares=%" PRIu64, shares); - } + if (streq(name, "TasksMax")) + return bus_cgroup_set_tasks_max(u, name, &c->tasks_max, message, flags, error); - return 1; + if (streq(name, "TasksMaxScale")) + return bus_cgroup_set_tasks_max_scale(u, name, &c->tasks_max, message, flags, error); - } else if (streq(name, "CPUQuotaPerSecUSec")) { + if (streq(name, "CPUQuotaPerSecUSec")) { uint64_t u64; r = sd_bus_message_read(message, "t", &u64); @@ -560,65 +568,6 @@ int bus_cgroup_set_property( return 1; - } else if (streq(name, "IOAccounting")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->io_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_IO); - unit_write_settingf(u, flags, name, "IOAccounting=%s", yes_no(b)); - } - - return 1; - - } else if (streq(name, "IOWeight")) { - uint64_t weight; - - r = sd_bus_message_read(message, "t", &weight); - if (r < 0) - return r; - - if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IOWeight= value out of range"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->io_weight = weight; - unit_invalidate_cgroup(u, CGROUP_MASK_IO); - - if (weight == CGROUP_WEIGHT_INVALID) - unit_write_setting(u, flags, name, "IOWeight="); - else - unit_write_settingf(u, flags, name, "IOWeight=%" PRIu64, weight); - } - - return 1; - - } else if (streq(name, "StartupIOWeight")) { - uint64_t weight; - - r = sd_bus_message_read(message, "t", &weight); - if (r < 0) - return r; - - if (CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupIOWeight= value out of range"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->startup_io_weight = weight; - unit_invalidate_cgroup(u, CGROUP_MASK_IO); - - if (weight == CGROUP_WEIGHT_INVALID) - unit_write_setting(u, flags, name, "StartupIOWeight="); - else - unit_write_settingf(u, flags, name, "StartupIOWeight=%" PRIu64, weight); - } - - return 1; - } else if ((iol_type = cgroup_io_limit_type_from_string(name)) >= 0) { const char *path; unsigned n = 0; @@ -630,6 +579,10 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) { + if (!path_startswith(path, "/dev") && + !path_startswith(path, "/run/systemd/inaccessible/")) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s specified in %s= is not a device file in /dev", name, path); + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupIODeviceLimit *a = NULL, *b; @@ -714,6 +667,10 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) { + if (!path_startswith(path, "/dev") && + !path_startswith(path, "/run/systemd/inaccessible/")) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s specified in %s= is not a device file in /dev", name, path); + if (!CGROUP_WEIGHT_IS_OK(weight) || weight == CGROUP_WEIGHT_INVALID) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IODeviceWeight= value out of range"); @@ -737,7 +694,7 @@ int bus_cgroup_set_property( free(a); return -ENOMEM; } - LIST_PREPEND(device_weights,c->io_device_weights, a); + LIST_PREPEND(device_weights, c->io_device_weights, a); } a->weight = weight; @@ -781,65 +738,6 @@ int bus_cgroup_set_property( return 1; - } else if (streq(name, "BlockIOAccounting")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->blockio_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); - unit_write_settingf(u, flags, name, "BlockIOAccounting=%s", yes_no(b)); - } - - return 1; - - } else if (streq(name, "BlockIOWeight")) { - uint64_t weight; - - r = sd_bus_message_read(message, "t", &weight); - if (r < 0) - return r; - - if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "BlockIOWeight= value out of range"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->blockio_weight = weight; - unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); - - if (weight == CGROUP_BLKIO_WEIGHT_INVALID) - unit_write_setting(u, flags, name, "BlockIOWeight="); - else - unit_write_settingf(u, flags, name, "BlockIOWeight=%" PRIu64, weight); - } - - return 1; - - } else if (streq(name, "StartupBlockIOWeight")) { - uint64_t weight; - - r = sd_bus_message_read(message, "t", &weight); - if (r < 0) - return r; - - if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupBlockIOWeight= value out of range"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->startup_blockio_weight = weight; - unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); - - if (weight == CGROUP_BLKIO_WEIGHT_INVALID) - unit_write_setting(u, flags, name, "StartupBlockIOWeight="); - else - unit_write_settingf(u, flags, name, "StartupBlockIOWeight=%" PRIu64, weight); - } - - return 1; - } else if (STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) { const char *path; bool read = true; @@ -855,6 +753,10 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) { + if (!path_startswith(path, "/dev") && + !path_startswith(path, "/run/systemd/inaccessible/")) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s specified in %s= is not a device file in /dev", name, path); + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupBlockIODeviceBandwidth *a = NULL, *b; @@ -951,6 +853,10 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) { + if (!path_startswith(path, "/dev") && + !path_startswith(path, "/run/systemd/inaccessible/")) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s specified in %s= is not a device file in /dev", name, path); + if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight) || weight == CGROUP_BLKIO_WEIGHT_INVALID) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "BlockIODeviceWeight= out of range"); @@ -974,7 +880,7 @@ int bus_cgroup_set_property( free(a); return -ENOMEM; } - LIST_PREPEND(device_weights,c->blockio_device_weights, a); + LIST_PREPEND(device_weights, c->blockio_device_weights, a); } a->weight = weight; @@ -1019,127 +925,6 @@ int bus_cgroup_set_property( return 1; - } else if (streq(name, "MemoryAccounting")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->memory_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_settingf(u, flags, name, "MemoryAccounting=%s", yes_no(b)); - } - - return 1; - - } else if (STR_IN_SET(name, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax")) { - uint64_t v; - - r = sd_bus_message_read(message, "t", &v); - if (r < 0) - return r; - if (v <= 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (streq(name, "MemoryLow")) - c->memory_low = v; - else if (streq(name, "MemoryHigh")) - c->memory_high = v; - else if (streq(name, "MemorySwapMax")) - c->memory_swap_max = v; - else - c->memory_max = v; - - unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - - if (v == CGROUP_LIMIT_MAX) - unit_write_settingf(u, flags, name, "%s=infinity", name); - else - unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, v); - } - - return 1; - - } else if (STR_IN_SET(name, "MemoryLowScale", "MemoryHighScale", "MemoryMaxScale", "MemorySwapMaxScale")) { - uint32_t raw; - uint64_t v; - - r = sd_bus_message_read(message, "u", &raw); - if (r < 0) - return r; - - v = physical_memory_scale(raw, UINT32_MAX); - if (v <= 0 || v == UINT64_MAX) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - const char *e; - - /* Chop off suffix */ - assert_se(e = endswith(name, "Scale")); - name = strndupa(name, e - name); - - if (streq(name, "MemoryLow")) - c->memory_low = v; - else if (streq(name, "MemoryHigh")) - c->memory_high = v; - else if (streq(name, "MemorySwapMaxScale")) - c->memory_swap_max = v; - else /* MemoryMax */ - c->memory_max = v; - - unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); - } - - return 1; - - } else if (streq(name, "MemoryLimit")) { - uint64_t limit; - - r = sd_bus_message_read(message, "t", &limit); - if (r < 0) - return r; - if (limit <= 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->memory_limit = limit; - unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - - if (limit == CGROUP_LIMIT_MAX) - unit_write_setting(u, flags, name, "MemoryLimit=infinity"); - else - unit_write_settingf(u, flags, name, "MemoryLimit=%" PRIu64, limit); - } - - return 1; - - } else if (streq(name, "MemoryLimitScale")) { - uint64_t limit; - uint32_t raw; - - r = sd_bus_message_read(message, "u", &raw); - if (r < 0) - return r; - - limit = physical_memory_scale(raw, UINT32_MAX); - if (limit <= 0 || limit == UINT64_MAX) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->memory_limit = limit; - unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_settingf(u, flags, "MemoryLimit", "MemoryLimit=%" PRIu32 "%%", - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); - } - - return 1; - } else if (streq(name, "DevicePolicy")) { const char *policy; CGroupDevicePolicy p; @@ -1170,10 +955,8 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(ss)", &path, &rwm)) > 0) { - if ((!path_startswith(path, "/dev/") && - !path_startswith(path, "/run/systemd/inaccessible/") && - !startswith(path, "block-") && - !startswith(path, "char-")) || + if ((!is_deviceallow_pattern(path) && + !path_startswith(path, "/run/systemd/inaccessible/")) || strpbrk(path, WHITESPACE)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node"); @@ -1252,63 +1035,6 @@ int bus_cgroup_set_property( return 1; - } else if (streq(name, "TasksAccounting")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->tasks_accounting = b; - unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - unit_write_settingf(u, flags, name, "TasksAccounting=%s", yes_no(b)); - } - - return 1; - - } else if (streq(name, "TasksMax")) { - uint64_t limit; - - r = sd_bus_message_read(message, "t", &limit); - if (r < 0) - return r; - if (limit <= 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->tasks_max = limit; - unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - - if (limit == (uint64_t) -1) - unit_write_setting(u, flags, name, "TasksMax=infinity"); - else - unit_write_settingf(u, flags, name, "TasksMax=%" PRIu64, limit); - } - - return 1; - - } else if (streq(name, "TasksMaxScale")) { - uint64_t limit; - uint32_t raw; - - r = sd_bus_message_read(message, "u", &raw); - if (r < 0) - return r; - - limit = system_tasks_max_scale(raw, UINT32_MAX); - if (limit <= 0 || limit >= UINT64_MAX) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->tasks_max = limit; - unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - unit_write_settingf(u, flags, name, "TasksMax=%" PRIu32 "%%", - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); - } - - return 1; - } else if (streq(name, "IPAccounting")) { int b; @@ -1450,12 +1176,8 @@ int bus_cgroup_set_property( return 1; } - if (u->transient && u->load_state == UNIT_STUB) { - r = bus_cgroup_set_transient_property(u, c, name, message, flags, error); - if (r != 0) - return r; - - } + if (u->transient && u->load_state == UNIT_STUB) + return bus_cgroup_set_transient_property(u, c, name, message, flags, error); return 0; } diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index be25b6e987..628fdcd1e5 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -32,6 +32,7 @@ #include "capability-util.h" #include "cpu-set-util.h" #include "dbus-execute.h" +#include "dbus-util.h" #include "env-util.h" #include "errno-list.h" #include "escape.h" @@ -1036,6 +1037,162 @@ int bus_property_get_exec_command_list( return sd_bus_message_close_container(reply); } +int bus_set_transient_exec_command( + Unit *u, + const char *name, + ExecCommand **exec_command, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + unsigned n = 0; + int r; + + r = sd_bus_message_enter_container(message, 'a', "(sasb)"); + if (r < 0) + return r; + + while ((r = sd_bus_message_enter_container(message, 'r', "sasb")) > 0) { + _cleanup_strv_free_ char **argv = NULL; + const char *path; + int b; + + r = sd_bus_message_read(message, "s", &path); + if (r < 0) + return r; + + if (!path_is_absolute(path)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path); + + r = sd_bus_message_read_strv(message, &argv); + if (r < 0) + return r; + + r = sd_bus_message_read(message, "b", &b); + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + ExecCommand *c; + + c = new0(ExecCommand, 1); + if (!c) + return -ENOMEM; + + c->path = strdup(path); + if (!c->path) { + free(c); + return -ENOMEM; + } + + c->argv = argv; + argv = NULL; + + c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0; + + path_kill_slashes(c->path); + exec_command_append_list(exec_command, c); + } + + n++; + } + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_free_ char *buf = NULL; + _cleanup_fclose_ FILE *f = NULL; + ExecCommand *c; + size_t size = 0; + + if (n == 0) + *exec_command = exec_command_free_list(*exec_command); + + f = open_memstream(&buf, &size); + if (!f) + return -ENOMEM; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + fputs("ExecStart=\n", f); + + LIST_FOREACH(command, c, *exec_command) { + _cleanup_free_ char *a = NULL, *t = NULL; + const char *p; + + p = unit_escape_setting(c->path, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS, &t); + if (!p) + return -ENOMEM; + + a = unit_concat_strv(c->argv, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS); + if (!a) + return -ENOMEM; + + fprintf(f, "%s=%s@%s %s\n", + name, + c->flags & EXEC_COMMAND_IGNORE_FAILURE ? "-" : "", + p, + a); + } + + r = fflush_and_check(f); + if (r < 0) + return r; + + unit_write_setting(u, flags, name, buf); + } + + return 1; +} + +static int parse_personality(const char *s, unsigned long *p) { + unsigned long v; + + assert(p); + + v = personality_from_string(s); + if (v == PERSONALITY_INVALID) + return -EINVAL; + + *p = v; + return 0; +} + +static const char* mount_propagation_flags_to_string_with_check(unsigned long n) { + if (!IN_SET(n, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE)) + return NULL; + + return mount_propagation_flags_to_string(n); +} + +static BUS_DEFINE_SET_TRANSIENT(nsec, "t", uint64_t, nsec_t, NSEC_FMT); +static BUS_DEFINE_SET_TRANSIENT_IS_VALID(log_level, "i", int32_t, int, "%" PRIi32, log_level_is_valid); +#if HAVE_SECCOMP +static BUS_DEFINE_SET_TRANSIENT_IS_VALID(errno, "i", int32_t, int, "%" PRIi32, errno_is_valid); +#endif +static BUS_DEFINE_SET_TRANSIENT_IS_VALID(sched_priority, "i", int32_t, int, "%" PRIi32, sched_priority_is_valid); +static BUS_DEFINE_SET_TRANSIENT_IS_VALID(nice, "i", int32_t, int, "%" PRIi32, nice_is_valid); +static BUS_DEFINE_SET_TRANSIENT_PARSE(std_input, ExecInput, exec_input_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE(std_output, ExecOutput, exec_output_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE(utmp_mode, ExecUtmpMode, exec_utmp_mode_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, parse_protect_system_or_bool); +static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, parse_protect_home_or_bool); +static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE(preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string_alloc); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(sched_policy, "i", int32_t, int, "%" PRIi32, sched_policy_to_string_alloc_with_check); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flag_to_string_many_with_check); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_flags, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flags_to_string_with_check); + int bus_exec_context_set_transient_property( Unit *u, ExecContext *c, @@ -1054,49 +1211,172 @@ int bus_exec_context_set_transient_property( flags |= UNIT_PRIVATE; - if (streq(name, "User")) { - const char *uu; + if (streq(name, "User")) + return bus_set_transient_user(u, name, &c->user, message, flags, error); - r = sd_bus_message_read(message, "s", &uu); - if (r < 0) - return r; + if (streq(name, "Group")) + return bus_set_transient_user(u, name, &c->group, message, flags, error); - if (!isempty(uu) && !valid_user_group_name_or_id(uu)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user name: %s", uu); + if (streq(name, "TTYPath")) + return bus_set_transient_path(u, name, &c->tty_path, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "RootImage")) + return bus_set_transient_path(u, name, &c->root_image, message, flags, error); - r = free_and_strdup(&c->user, empty_to_null(uu)); - if (r < 0) - return r; + if (streq(name, "RootDirectory")) + return bus_set_transient_path(u, name, &c->root_directory, message, flags, error); - unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "User=%s", uu); - } + if (streq(name, "SyslogIdentifier")) + return bus_set_transient_string(u, name, &c->syslog_identifier, message, flags, error); - return 1; + if (streq(name, "LogLevelMax")) + return bus_set_transient_log_level(u, name, &c->log_level_max, message, flags, error); - } else if (streq(name, "Group")) { - const char *gg; + if (streq(name, "CPUSchedulingPriority")) + return bus_set_transient_sched_priority(u, name, &c->cpu_sched_priority, message, flags, error); - r = sd_bus_message_read(message, "s", &gg); - if (r < 0) - return r; + if (streq(name, "Personality")) + return bus_set_transient_personality(u, name, &c->personality, message, flags, error); - if (!isempty(gg) && !valid_user_group_name_or_id(gg)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group name: %s", gg); + if (streq(name, "Nice")) + return bus_set_transient_nice(u, name, &c->nice, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "StandardInput")) + return bus_set_transient_std_input(u, name, &c->std_input, message, flags, error); - r = free_and_strdup(&c->group, empty_to_null(gg)); - if (r < 0) - return r; + if (streq(name, "StandardOutput")) + return bus_set_transient_std_output(u, name, &c->std_output, message, flags, error); - unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Group=%s", gg); - } + if (streq(name, "StandardError")) + return bus_set_transient_std_output(u, name, &c->std_error, message, flags, error); - return 1; + if (streq(name, "IgnoreSIGPIPE")) + return bus_set_transient_bool(u, name, &c->ignore_sigpipe, message, flags, error); + + if (streq(name, "TTYVHangup")) + return bus_set_transient_bool(u, name, &c->tty_vhangup, message, flags, error); + + if (streq(name, "TTYReset")) + return bus_set_transient_bool(u, name, &c->tty_reset, message, flags, error); + + if (streq(name, "TTYVTDisallocate")) + return bus_set_transient_bool(u, name, &c->tty_vt_disallocate, message, flags, error); + + if (streq(name, "PrivateTmp")) + return bus_set_transient_bool(u, name, &c->private_tmp, message, flags, error); + + if (streq(name, "PrivateDevices")) + return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error); + + if (streq(name, "PrivateNetwork")) + return bus_set_transient_bool(u, name, &c->private_network, message, flags, error); + + if (streq(name, "PrivateUsers")) + return bus_set_transient_bool(u, name, &c->private_users, message, flags, error); + + if (streq(name, "NoNewPrivileges")) + return bus_set_transient_bool(u, name, &c->no_new_privileges, message, flags, error); + + if (streq(name, "SyslogLevelPrefix")) + return bus_set_transient_bool(u, name, &c->syslog_level_prefix, message, flags, error); + + if (streq(name, "MemoryDenyWriteExecute")) + return bus_set_transient_bool(u, name, &c->memory_deny_write_execute, message, flags, error); + + if (streq(name, "RestrictRealtime")) + return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error); + + if (streq(name, "DynamicUser")) + return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error); + + if (streq(name, "RemoveIPC")) + return bus_set_transient_bool(u, name, &c->remove_ipc, message, flags, error); + + if (streq(name, "ProtectKernelTunables")) + return bus_set_transient_bool(u, name, &c->protect_kernel_tunables, message, flags, error); + + if (streq(name, "ProtectKernelModules")) + return bus_set_transient_bool(u, name, &c->protect_kernel_modules, message, flags, error); + + if (streq(name, "ProtectControlGroups")) + return bus_set_transient_bool(u, name, &c->protect_control_groups, message, flags, error); + + if (streq(name, "MountAPIVFS")) + return bus_set_transient_bool(u, name, &c->mount_apivfs, message, flags, error); + + if (streq(name, "CPUSchedulingResetOnFork")) + return bus_set_transient_bool(u, name, &c->cpu_sched_reset_on_fork, message, flags, error); + + if (streq(name, "NonBlocking")) + return bus_set_transient_bool(u, name, &c->non_blocking, message, flags, error); + + if (streq(name, "LockPersonality")) + return bus_set_transient_bool(u, name, &c->lock_personality, message, flags, error); + + if (streq(name, "UtmpIdentifier")) + return bus_set_transient_string(u, name, &c->utmp_id, message, flags, error); + + if (streq(name, "UtmpMode")) + return bus_set_transient_utmp_mode(u, name, &c->utmp_mode, message, flags, error); + + if (streq(name, "PAMName")) + return bus_set_transient_string(u, name, &c->pam_name, message, flags, error); + + if (streq(name, "TimerSlackNSec")) + return bus_set_transient_nsec(u, name, &c->timer_slack_nsec, message, flags, error); + + if (streq(name, "ProtectSystem")) + return bus_set_transient_protect_system(u, name, &c->protect_system, message, flags, error); + + if (streq(name, "ProtectHome")) + return bus_set_transient_protect_home(u, name, &c->protect_home, message, flags, error); + + if (streq(name, "KeyringMode")) + return bus_set_transient_keyring_mode(u, name, &c->keyring_mode, message, flags, error); + + if (streq(name, "RuntimeDirectoryPreserve")) + return bus_set_transient_preserve_mode(u, name, &c->runtime_directory_preserve_mode, message, flags, error); + + if (streq(name, "UMask")) + return bus_set_transient_mode_t(u, name, &c->umask, message, flags, error); + + if (streq(name, "RuntimeDirectoryMode")) + return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_RUNTIME].mode, message, flags, error); - } else if (streq(name, "SupplementaryGroups")) { + if (streq(name, "StateDirectoryMode")) + return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_STATE].mode, message, flags, error); + + if (streq(name, "CacheDirectoryMode")) + return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CACHE].mode, message, flags, error); + + if (streq(name, "LogsDirectoryMode")) + return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_LOGS].mode, message, flags, error); + + if (streq(name, "ConfigurationDirectoryMode")) + return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CONFIGURATION].mode, message, flags, error); + + if (streq(name, "SELinuxContext")) + return bus_set_transient_string(u, name, &c->selinux_context, message, flags, error); + + if (streq(name, "SecureBits")) + return bus_set_transient_secure_bits(u, name, &c->secure_bits, message, flags, error); + + if (streq(name, "CapabilityBoundingSet")) + return bus_set_transient_capability(u, name, &c->capability_bounding_set, message, flags, error); + + if (streq(name, "AmbientCapabilities")) + return bus_set_transient_capability(u, name, &c->capability_ambient_set, message, flags, error); + + if (streq(name, "CPUSchedulingPolicy")) + return bus_set_transient_sched_policy(u, name, &c->cpu_sched_policy, message, flags, error); + + if (streq(name, "RestrictNamespaces")) + return bus_set_transient_namespace_flag(u, name, &c->restrict_namespaces, message, flags, error); + + if (streq(name, "MountFlags")) + return bus_set_transient_mount_flags(u, name, &c->mount_flags, message, flags, error); + + if (streq(name, "SupplementaryGroups")) { _cleanup_strv_free_ char **l = NULL; char **p; @@ -1130,24 +1410,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (streq(name, "SyslogIdentifier")) { - const char *id; - - r = sd_bus_message_read(message, "s", &id); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - - if (isempty(id)) - c->syslog_identifier = mfree(c->syslog_identifier); - else if (free_and_strdup(&c->syslog_identifier, id) < 0) - return -ENOMEM; - - unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "SyslogIdentifier=%s", id); - } - - return 1; } else if (streq(name, "SyslogLevel")) { int32_t level; @@ -1164,6 +1426,7 @@ int bus_exec_context_set_transient_property( } return 1; + } else if (streq(name, "SyslogFacility")) { int32_t facility; @@ -1181,23 +1444,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (streq(name, "LogLevelMax")) { - int32_t level; - - r = sd_bus_message_read(message, "i", &level); - if (r < 0) - return r; - - if (!log_level_is_valid(level)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Maximum log level value out of range"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->log_level_max = level; - unit_write_settingf(u, flags, name, "LogLevelMax=%i", level); - } - - return 1; - } else if (streq(name, "LogExtraFields")) { size_t n = 0; @@ -1271,75 +1517,14 @@ int bus_exec_context_set_transient_property( } return 1; - - } else if (streq(name, "SecureBits")) { - int n; - - r = sd_bus_message_read(message, "i", &n); - if (r < 0) - return r; - - if (!secure_bits_is_valid(n)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid secure bits"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - _cleanup_free_ char *str = NULL; - - c->secure_bits = n; - r = secure_bits_to_string_alloc(n, &str); - if (r < 0) - return r; - - unit_write_settingf(u, flags, name, "SecureBits=%s", str); - } - - return 1; - } else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) { - uint64_t n; - - r = sd_bus_message_read(message, "t", &n); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - _cleanup_free_ char *str = NULL; - - if (streq(name, "CapabilityBoundingSet")) - c->capability_bounding_set = n; - else /* "AmbientCapabilities" */ - c->capability_ambient_set = n; - - r = capability_set_to_string_alloc(n, &str); - if (r < 0) - return r; - - unit_write_settingf(u, flags, name, "%s=%s", name, str); - } - - return 1; - - } else if (streq(name, "Personality")) { - const char *s; - unsigned long p; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - p = personality_from_string(s); - if (p == PERSONALITY_INVALID) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid personality"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->personality = p; - unit_write_settingf(u, flags, name, "%s=%s", name, s); - } - - return 1; + } #if HAVE_SECCOMP - } else if (streq(name, "SystemCallFilter")) { + if (streq(name, "SystemCallErrorNumber")) + return bus_set_transient_errno(u, name, &c->syscall_errno, message, flags, error); + + if (streq(name, "SystemCallFilter")) { int whitelist; _cleanup_strv_free_ char **l = NULL; @@ -1361,59 +1546,42 @@ int bus_exec_context_set_transient_property( if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *joined = NULL; + bool invert = !whitelist; + char **s; if (strv_isempty(l)) { c->syscall_whitelist = false; c->syscall_filter = hashmap_free(c->syscall_filter); - } else { - char **s; - c->syscall_whitelist = whitelist; + unit_write_settingf(u, flags, name, "SystemCallFilter="); + return 1; + } - r = hashmap_ensure_allocated(&c->syscall_filter, NULL); - if (r < 0) - return r; + if (!c->syscall_filter) { + c->syscall_filter = hashmap_new(NULL); + if (!c->syscall_filter) + return log_oom(); - STRV_FOREACH(s, l) { - _cleanup_free_ char *n = NULL; - int e; + c->syscall_whitelist = whitelist; - r = parse_syscall_and_errno(*s, &n, &e); + if (c->syscall_whitelist) { + r = seccomp_parse_syscall_filter(invert, "@default", -1, c->syscall_filter, true); if (r < 0) return r; + } + } - if (*n == '@') { - const SyscallFilterSet *set; - const char *i; - - set = syscall_filter_set_find(n); - if (!set) - return -EINVAL; - - NULSTR_FOREACH(i, set->value) { - int id; - - id = seccomp_syscall_resolve_name(i); - if (id == __NR_SCMP_ERROR) - return -EINVAL; - - r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(e)); - if (r < 0) - return r; - } - - } else { - int id; + STRV_FOREACH(s, l) { + _cleanup_free_ char *n = NULL; + int e; - id = seccomp_syscall_resolve_name(n); - if (id == __NR_SCMP_ERROR) - return -EINVAL; + r = parse_syscall_and_errno(*s, &n, &e); + if (r < 0) + return r; - r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(e)); - if (r < 0) - return r; - } - } + r = seccomp_parse_syscall_filter(invert, n, e, c->syscall_filter, c->syscall_whitelist); + if (r < 0) + return r; } joined = strv_join(l, " "); @@ -1467,24 +1635,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (streq(name, "SystemCallErrorNumber")) { - int32_t n; - - r = sd_bus_message_read(message, "i", &n); - if (r < 0) - return r; - - if (n <= 0 || n > ERRNO_MAX) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SystemCallErrorNumber"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->syscall_errno = n; - - unit_write_settingf(u, flags, name, "SystemCallErrorNumber=%d", n); - } - - return 1; - } else if (streq(name, "RestrictAddressFamilies")) { int whitelist; _cleanup_strv_free_ char **l = NULL; @@ -1507,30 +1657,38 @@ int bus_exec_context_set_transient_property( if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *joined = NULL; + bool invert = !whitelist; + char **s; if (strv_isempty(l)) { c->address_families_whitelist = false; c->address_families = set_free(c->address_families); - } else { - char **s; - c->address_families_whitelist = whitelist; + unit_write_settingf(u, flags, name, "RestrictAddressFamilies="); + return 1; + } - r = set_ensure_allocated(&c->address_families, NULL); - if (r < 0) - return r; + if (!c->address_families) { + c->address_families = set_new(NULL); + if (!c->address_families) + return log_oom(); - STRV_FOREACH(s, l) { - int af; + c->address_families_whitelist = whitelist; + } - af = af_from_name(*s); - if (af <= 0) - return -EINVAL; + STRV_FOREACH(s, l) { + int af; + af = af_from_name(*s); + if (af <= 0) + return -EINVAL; + + if (!invert == c->address_families_whitelist) { r = set_put(c->address_families, INT_TO_PTR(af)); if (r < 0) return r; - } + } else + (void) set_remove(c->address_families, INT_TO_PTR(af)); } joined = strv_join(l, " "); @@ -1541,49 +1699,9 @@ int bus_exec_context_set_transient_property( } return 1; + } #endif - - } else if (streq(name, "CPUSchedulingPolicy")) { - int32_t n; - - r = sd_bus_message_read(message, "i", &n); - if (r < 0) - return r; - - if (!sched_policy_is_valid(n)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - _cleanup_free_ char *str = NULL; - - c->cpu_sched_policy = n; - r = sched_policy_to_string_alloc(n, &str); - if (r < 0) - return r; - - unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", str); - } - - return 1; - - } else if (streq(name, "CPUSchedulingPriority")) { - int32_t n; - - r = sd_bus_message_read(message, "i", &n); - if (r < 0) - return r; - - if (!ioprio_priority_is_valid(n)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->cpu_sched_priority = n; - unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", n); - } - - return 1; - - } else if (streq(name, "CPUAffinity")) { + if (streq(name, "CPUAffinity")) { const void *a; size_t n = 0; @@ -1649,22 +1767,6 @@ int bus_exec_context_set_transient_property( } return 1; - } else if (streq(name, "Nice")) { - int32_t n; - - r = sd_bus_message_read(message, "i", &n); - if (r < 0) - return r; - - if (!nice_is_valid(n)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->nice = n; - unit_write_settingf(u, flags, name, "Nice=%i", n); - } - - return 1; } else if (streq(name, "IOSchedulingClass")) { int32_t q; @@ -1710,33 +1812,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) { - const char *s; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - if (!path_is_absolute(s)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (streq(name, "TTYPath")) - r = free_and_strdup(&c->tty_path, s); - else if (streq(name, "RootImage")) - r = free_and_strdup(&c->root_image, s); - else { - assert(streq(name, "RootDirectory")); - r = free_and_strdup(&c->root_directory, s); - } - if (r < 0) - return r; - - unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, s); - } - - return 1; - } else if (streq(name, "WorkingDirectory")) { const char *s; bool missing_ok; @@ -1751,7 +1826,7 @@ int bus_exec_context_set_transient_property( } else missing_ok = false; - if (!streq(s, "~") && !path_is_absolute(s)) + if (!isempty(s) && !streq(s, "~") && !path_is_absolute(s)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'"); if (!UNIT_WRITE_FLAGS_NOOP(flags)) { @@ -1759,7 +1834,7 @@ int bus_exec_context_set_transient_property( c->working_directory = mfree(c->working_directory); c->working_directory_home = true; } else { - r = free_and_strdup(&c->working_directory, s); + r = free_and_strdup(&c->working_directory, empty_to_null(s)); if (r < 0) return r; @@ -1772,66 +1847,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (streq(name, "StandardInput")) { - const char *s; - ExecInput p; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - p = exec_input_from_string(s); - if (p < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->std_input = p; - - unit_write_settingf(u, flags, name, "StandardInput=%s", exec_input_to_string(p)); - } - - return 1; - - } else if (streq(name, "StandardOutput")) { - const char *s; - ExecOutput p; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - p = exec_output_from_string(s); - if (p < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->std_output = p; - - unit_write_settingf(u, flags, name, "StandardOutput=%s", exec_output_to_string(p)); - } - - return 1; - - } else if (streq(name, "StandardError")) { - const char *s; - ExecOutput p; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - p = exec_output_from_string(s); - if (p < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->std_error = p; - - unit_write_settingf(u, flags, name, "StandardError=%s", exec_output_to_string(p)); - } - - return 1; - } else if (STR_IN_SET(name, "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) { const char *s; @@ -1840,15 +1855,13 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (isempty(s)) - s = NULL; - else if (!fdname_is_valid(s)) + if (!isempty(s) && !fdname_is_valid(s)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name"); if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "StandardInputFileDescriptorName")) { - r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, s); + r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, empty_to_null(s)); if (r < 0) return r; @@ -1856,7 +1869,7 @@ int bus_exec_context_set_transient_property( unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=fd:%s", exec_context_fdname(c, STDIN_FILENO)); } else if (streq(name, "StandardOutputFileDescriptorName")) { - r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, s); + r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, empty_to_null(s)); if (r < 0) return r; @@ -1866,7 +1879,7 @@ int bus_exec_context_set_transient_property( } else { assert(streq(name, "StandardErrorFileDescriptorName")); - r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], s); + r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], empty_to_null(s)); if (r < 0) return r; @@ -1884,15 +1897,17 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (!path_is_absolute(s)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute", s); - if (!path_is_normalized(s)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s); + if (!isempty(s)) { + if (!path_is_absolute(s)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute", s); + if (!path_is_normalized(s)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s); + } if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "StandardInputFile")) { - r = free_and_strdup(&c->stdio_file[STDIN_FILENO], s); + r = free_and_strdup(&c->stdio_file[STDIN_FILENO], empty_to_null(s)); if (r < 0) return r; @@ -1900,7 +1915,7 @@ int bus_exec_context_set_transient_property( unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s); } else if (streq(name, "StandardOutputFile")) { - r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], s); + r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], empty_to_null(s)); if (r < 0) return r; @@ -1910,7 +1925,7 @@ int bus_exec_context_set_transient_property( } else { assert(streq(name, "StandardErrorFile")); - r = free_and_strdup(&c->stdio_file[STDERR_FILENO], s); + r = free_and_strdup(&c->stdio_file[STDERR_FILENO], empty_to_null(s)); if (r < 0) return r; @@ -1964,124 +1979,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (STR_IN_SET(name, - "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate", - "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers", - "NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute", - "RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables", - "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS", - "CPUSchedulingResetOnFork", "NonBlocking", "LockPersonality")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (streq(name, "IgnoreSIGPIPE")) - c->ignore_sigpipe = b; - else if (streq(name, "TTYVHangup")) - c->tty_vhangup = b; - else if (streq(name, "TTYReset")) - c->tty_reset = b; - else if (streq(name, "TTYVTDisallocate")) - c->tty_vt_disallocate = b; - else if (streq(name, "PrivateTmp")) - c->private_tmp = b; - else if (streq(name, "PrivateDevices")) - c->private_devices = b; - else if (streq(name, "PrivateNetwork")) - c->private_network = b; - else if (streq(name, "PrivateUsers")) - c->private_users = b; - else if (streq(name, "NoNewPrivileges")) - c->no_new_privileges = b; - else if (streq(name, "SyslogLevelPrefix")) - c->syslog_level_prefix = b; - else if (streq(name, "MemoryDenyWriteExecute")) - c->memory_deny_write_execute = b; - else if (streq(name, "RestrictRealtime")) - c->restrict_realtime = b; - else if (streq(name, "DynamicUser")) - c->dynamic_user = b; - else if (streq(name, "RemoveIPC")) - c->remove_ipc = b; - else if (streq(name, "ProtectKernelTunables")) - c->protect_kernel_tunables = b; - else if (streq(name, "ProtectKernelModules")) - c->protect_kernel_modules = b; - else if (streq(name, "ProtectControlGroups")) - c->protect_control_groups = b; - else if (streq(name, "MountAPIVFS")) - c->mount_apivfs = b; - else if (streq(name, "CPUSchedulingResetOnFork")) - c->cpu_sched_reset_on_fork = b; - else if (streq(name, "NonBlocking")) - c->non_blocking = b; - else if (streq(name, "LockPersonality")) - c->lock_personality = b; - - unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b)); - } - - return 1; - - } else if (streq(name, "UtmpIdentifier")) { - const char *id; - - r = sd_bus_message_read(message, "s", &id); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - - r = free_and_strdup(&c->utmp_id, empty_to_null(id)); - if (r < 0) - return r; - - unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "UtmpIdentifier=%s", strempty(id)); - } - - return 1; - - } else if (streq(name, "UtmpMode")) { - const char *s; - ExecUtmpMode m; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - m = exec_utmp_mode_from_string(s); - if (m < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid utmp mode"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->utmp_mode = m; - - unit_write_settingf(u, flags, name, "UtmpMode=%s", exec_utmp_mode_to_string(m)); - } - - return 1; - - } else if (streq(name, "PAMName")) { - const char *n; - - r = sd_bus_message_read(message, "s", &n); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - - r = free_and_strdup(&c->pam_name, empty_to_null(n)); - if (r < 0) - return r; - - unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "PAMName=%s", strempty(n)); - } - - return 1; - } else if (streq(name, "Environment")) { _cleanup_strv_free_ char **l = NULL; @@ -2154,21 +2051,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (streq(name, "TimerSlackNSec")) { - - nsec_t n; - - r = sd_bus_message_read(message, "t", &n); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->timer_slack_nsec = n; - unit_write_settingf(u, flags, name, "TimerSlackNSec=" NSEC_FMT, n); - } - - return 1; - } else if (streq(name, "OOMScoreAdjust")) { int oa; @@ -2323,16 +2205,15 @@ int bus_exec_context_set_transient_property( return r; STRV_FOREACH(p, l) { - const char *i = *p; + char *i = *p; size_t offset; - if (!utf8_is_valid(i)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name); - offset = i[0] == '-'; offset += i[offset] == '+'; if (!path_is_absolute(i + offset)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name); + + path_kill_slashes(i + offset); } if (!UNIT_WRITE_FLAGS_NOOP(flags)) { @@ -2363,123 +2244,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (streq(name, "ProtectSystem")) { - const char *s; - ProtectSystem ps; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - r = parse_boolean(s); - if (r > 0) - ps = PROTECT_SYSTEM_YES; - else if (r == 0) - ps = PROTECT_SYSTEM_NO; - else { - ps = protect_system_from_string(s); - if (ps < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect system value"); - } - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->protect_system = ps; - unit_write_settingf(u, flags, name, "%s=%s", name, s); - } - - return 1; - - } else if (streq(name, "ProtectHome")) { - const char *s; - ProtectHome ph; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - r = parse_boolean(s); - if (r > 0) - ph = PROTECT_HOME_YES; - else if (r == 0) - ph = PROTECT_HOME_NO; - else { - ph = protect_home_from_string(s); - if (ph < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect home value"); - } - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->protect_home = ph; - unit_write_settingf(u, flags, name, "%s=%s", name, s); - } - - return 1; - - } else if (streq(name, "KeyringMode")) { - - const char *s; - ExecKeyringMode m; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - m = exec_keyring_mode_from_string(s); - if (m < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid keyring mode"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->keyring_mode = m; - - unit_write_settingf(u, flags, name, "KeyringMode=%s", exec_keyring_mode_to_string(m)); - } - - return 1; - - } else if (streq(name, "RuntimeDirectoryPreserve")) { - const char *s; - ExecPreserveMode m; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - m = exec_preserve_mode_from_string(s); - if (m < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid preserve mode"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->runtime_directory_preserve_mode = m; - - unit_write_settingf(u, flags, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m)); - } - - return 1; - - } else if (STR_IN_SET(name, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")) { - mode_t m; - - r = sd_bus_message_read(message, "u", &m); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - ExecDirectoryType i; - - if (streq(name, "UMask")) - c->umask = m; - else - for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++) - if (startswith(name, exec_directory_type_to_string(i))) { - c->directories[i].mode = m; - break; - } - - unit_write_settingf(u, flags, name, "%s=%040o", name, m); - } - - return 1; - } else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) { _cleanup_strv_free_ char **l = NULL; char **p; @@ -2525,23 +2289,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (streq(name, "SELinuxContext")) { - const char *s; - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (isempty(s)) - c->selinux_context = mfree(c->selinux_context); - else if (free_and_strdup(&c->selinux_context, s) < 0) - return -ENOMEM; - - unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(s)); - } - - return 1; - } else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) { int ignore; const char *s; @@ -2580,43 +2327,6 @@ int bus_exec_context_set_transient_property( return 1; - } else if (streq(name, "RestrictNamespaces")) { - uint64_t rf; - - r = sd_bus_message_read(message, "t", &rf); - if (r < 0) - return r; - if ((rf & NAMESPACE_FLAGS_ALL) != rf) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown namespace types"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - _cleanup_free_ char *s = NULL; - - r = namespace_flag_to_string_many(rf, &s); - if (r < 0) - return r; - - c->restrict_namespaces = rf; - unit_write_settingf(u, flags, name, "%s=%s", name, s); - } - - return 1; - } else if (streq(name, "MountFlags")) { - uint64_t fl; - - r = sd_bus_message_read(message, "t", &fl); - if (r < 0) - return r; - if (!IN_SET(fl, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount propagation flags"); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->mount_flags = fl; - - unit_write_settingf(u, flags, name, "%s=%s", name, mount_propagation_flags_to_string(fl)); - } - - return 1; } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) { unsigned empty = true; diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h index f30f0774cd..4d9b368f81 100644 --- a/src/core/dbus-execute.h +++ b/src/core/dbus-execute.h @@ -44,3 +44,4 @@ int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *int int bus_property_get_exec_command_list(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); int bus_exec_context_set_transient_property(Unit *u, ExecContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +int bus_set_transient_exec_command(Unit *u, const char *name, ExecCommand **exec_command, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c index bf3bbb2047..53d0aad63b 100644 --- a/src/core/dbus-kill.c +++ b/src/core/dbus-kill.c @@ -20,6 +20,7 @@ #include "bus-util.h" #include "dbus-kill.h" +#include "dbus-util.h" #include "kill.h" #include "signal-util.h" @@ -34,6 +35,9 @@ const sd_bus_vtable bus_kill_vtable[] = { SD_BUS_VTABLE_END }; +static BUS_DEFINE_SET_TRANSIENT_PARSE(kill_mode, KillMode, kill_mode_from_string); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING(kill_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check); + int bus_kill_context_set_transient_property( Unit *u, KillContext *c, @@ -42,8 +46,6 @@ int bus_kill_context_set_transient_property( UnitWriteFlags flags, sd_bus_error *error) { - int r; - assert(u); assert(c); assert(name); @@ -51,75 +53,17 @@ int bus_kill_context_set_transient_property( flags |= UNIT_PRIVATE; - if (streq(name, "KillMode")) { - const char *m; - KillMode k; - - r = sd_bus_message_read(message, "s", &m); - if (r < 0) - return r; - - k = kill_mode_from_string(m); - if (k < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Kill mode '%s' not known.", m); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->kill_mode = k; - - unit_write_settingf(u, flags, name, "KillMode=%s", kill_mode_to_string(k)); - } - - return 1; - - } else if (streq(name, "KillSignal")) { - int sig; - - r = sd_bus_message_read(message, "i", &sig); - if (r < 0) - return r; - - if (!SIGNAL_VALID(sig)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal %i out of range", sig); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->kill_signal = sig; - - unit_write_settingf(u, flags, name, "KillSignal=%s", signal_to_string(sig)); - } - - return 1; - - } else if (streq(name, "SendSIGHUP")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->send_sighup = b; - - unit_write_settingf(u, flags, name, "SendSIGHUP=%s", yes_no(b)); - } - - return 1; - - } else if (streq(name, "SendSIGKILL")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - c->send_sigkill = b; + if (streq(name, "KillMode")) + return bus_set_transient_kill_mode(u, name, &c->kill_mode, message, flags, error); - unit_write_settingf(u, flags, name, "SendSIGKILL=%s", yes_no(b)); - } + if (streq(name, "SendSIGHUP")) + return bus_set_transient_bool(u, name, &c->send_sighup, message, flags, error); - return 1; + if (streq(name, "SendSIGKILL")) + return bus_set_transient_bool(u, name, &c->send_sigkill, message, flags, error); - } + if (streq(name, "KillSignal")) + return bus_set_transient_kill_signal(u, name, &c->kill_signal, message, flags, error); return 0; } diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index ec9e65879f..4fe374867c 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -2416,6 +2416,7 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0), SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0), + SD_BUS_WRITABLE_PROPERTY("ServiceWatchdogs", "b", bus_property_get_bool, bus_property_set_bool, offsetof(Manager, service_watchdogs), 0), SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0), SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0), SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned, offsetof(Manager, return_value), 0), @@ -2423,8 +2424,10 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* obsolete alias name */ + SD_BUS_PROPERTY("DefaultStartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST), + /* The following two items are obsolete alias */ + SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), + SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c index 628bce0b6a..9e52f55fa5 100644 --- a/src/core/dbus-mount.c +++ b/src/core/dbus-mount.c @@ -23,6 +23,7 @@ #include "dbus-execute.h" #include "dbus-kill.h" #include "dbus-mount.h" +#include "dbus-util.h" #include "mount.h" #include "string-util.h" #include "unit.h" @@ -129,9 +130,7 @@ static int bus_mount_set_transient_property( UnitWriteFlags flags, sd_bus_error *error) { - const char *new_property; - char **property; - int r; + Unit *u = UNIT(m); assert(m); assert(name); @@ -139,29 +138,34 @@ static int bus_mount_set_transient_property( flags |= UNIT_PRIVATE; + if (streq(name, "Where")) + return bus_set_transient_path(u, name, &m->where, message, flags, error); + if (streq(name, "What")) - property = &m->parameters_fragment.what; - else if (streq(name, "Options")) - property = &m->parameters_fragment.options; - else if (streq(name, "Type")) - property = &m->parameters_fragment.fstype; - else - return 0; - - r = sd_bus_message_read(message, "s", &new_property); - if (r < 0) - return r; + return bus_set_transient_string(u, name, &m->parameters_fragment.what, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (streq(name, "Options")) + return bus_set_transient_string(u, name, &m->parameters_fragment.options, message, flags, error); - r = free_and_strdup(property, new_property); - if (r < 0) - return r; + if (streq(name, "Type")) + return bus_set_transient_string(u, name, &m->parameters_fragment.fstype, message, flags, error); - unit_write_settingf(UNIT(m), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, new_property); - } + if (streq(name, "TimeoutUSec")) + return bus_set_transient_usec_fix_0(u, name, &m->timeout_usec, message, flags, error); - return 1; + if (streq(name, "DirectoryMode")) + return bus_set_transient_mode_t(u, name, &m->directory_mode, message, flags, error); + + if (streq(name, "SloppyOptions")) + return bus_set_transient_bool(u, name, &m->sloppy_options, message, flags, error); + + if (streq(name, "LazyUnmount")) + return bus_set_transient_bool(u, name, &m->lazy_unmount, message, flags, error); + + if (streq(name, "ForceUnmount")) + return bus_set_transient_bool(u, name, &m->force_unmount, message, flags, error); + + return 0; } int bus_mount_set_property( diff --git a/src/core/dbus-path.c b/src/core/dbus-path.c index 0f54b04f76..b3f502f4c9 100644 --- a/src/core/dbus-path.c +++ b/src/core/dbus-path.c @@ -18,9 +18,13 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "alloc-util.h" #include "bus-util.h" #include "dbus-path.h" +#include "dbus-util.h" +#include "list.h" #include "path.h" +#include "path-util.h" #include "string-util.h" #include "unit.h" @@ -85,3 +89,108 @@ const sd_bus_vtable bus_path_vtable[] = { SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Path, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_VTABLE_END }; + +static int bus_path_set_transient_property( + Path *p, + const char *name, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + Unit *u = UNIT(p); + int r; + + assert(p); + assert(name); + assert(message); + + flags |= UNIT_PRIVATE; + + if (streq(name, "MakeDirectory")) + return bus_set_transient_bool(u, name, &p->make_directory, message, flags, error); + + if (streq(name, "DirectoryMode")) + return bus_set_transient_mode_t(u, name, &p->directory_mode, message, flags, error); + + if (streq(name, "Paths")) { + const char *type_name, *path; + bool empty = true; + + r = sd_bus_message_enter_container(message, 'a', "(ss)"); + if (r < 0) + return r; + + while ((r = sd_bus_message_read(message, "(ss)", &type_name, &path)) > 0) { + PathType t; + + t = path_type_from_string(type_name); + if (t < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown path type: %s", type_name); + + if (isempty(path)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is empty", type_name); + + if (!path_is_absolute(path)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is not absolute: %s", type_name, path); + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_free_ char *k; + PathSpec *s; + + k = strdup(path); + if (!k) + return -ENOMEM; + + s = new0(PathSpec, 1); + if (!s) + return -ENOMEM; + + s->unit = u; + s->path = path_kill_slashes(k); + k = NULL; + s->type = t; + s->inotify_fd = -1; + + LIST_PREPEND(spec, p->specs, s); + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", type_name, path); + } + + empty = false; + } + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) { + path_free_specs(p); + unit_write_settingf(u, flags, name, "PathExists="); + } + + return 1; + } + + return 0; +} + +int bus_path_set_property( + Unit *u, + const char *name, + sd_bus_message *message, + UnitWriteFlags mode, + sd_bus_error *error) { + + Path *p = PATH(u); + + assert(p); + assert(name); + assert(message); + + if (u->transient && u->load_state == UNIT_STUB) + return bus_path_set_transient_property(p, name, message, mode, error); + + return 0; +} diff --git a/src/core/dbus-path.h b/src/core/dbus-path.h index 5e7e859b56..ccd88c7f86 100644 --- a/src/core/dbus-path.h +++ b/src/core/dbus-path.h @@ -20,6 +20,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "sd-bus.h" +#include "unit.h" extern const sd_bus_vtable bus_path_vtable[]; + +int bus_path_set_property(Unit *u, const char *name, sd_bus_message *i, UnitWriteFlags flags, sd_bus_error *error); diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index 9195ad36d0..a0c4a65b33 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -26,6 +26,7 @@ #include "dbus-kill.h" #include "dbus-scope.h" #include "dbus-unit.h" +#include "dbus-util.h" #include "dbus.h" #include "scope.h" #include "selinux-access.h" @@ -84,6 +85,9 @@ static int bus_scope_set_transient_property( flags |= UNIT_PRIVATE; + if (streq(name, "TimeoutStopUSec")) + return bus_set_transient_usec(UNIT(s), name, &s->timeout_stop_usec, message, flags, error); + if (streq(name, "PIDs")) { unsigned n = 0; uint32_t pid; @@ -139,21 +143,6 @@ static int bus_scope_set_transient_property( } return 1; - - } else if (streq(name, "TimeoutStopUSec")) { - uint64_t t; - - r = sd_bus_message_read(message, "t", &t); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - s->timeout_stop_usec = t; - - unit_write_settingf(UNIT(s), flags, name, "TimeoutStopSec=" USEC_FMT "us", t); - } - - return 1; } return 0; diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 0189952124..6de905b69c 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -22,15 +22,20 @@ #include "alloc-util.h" #include "async.h" +#include "bus-internal.h" #include "bus-util.h" #include "dbus-cgroup.h" #include "dbus-execute.h" #include "dbus-kill.h" #include "dbus-service.h" +#include "dbus-util.h" +#include "exit-status.h" #include "fd-util.h" #include "fileio.h" +#include "parse-util.h" #include "path-util.h" #include "service.h" +#include "signal-util.h" #include "string-util.h" #include "strv.h" #include "unit.h" @@ -41,6 +46,71 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, Servi static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess); static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction); +static int property_get_exit_status_set( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ExitStatusSet *status_set = userdata; + Iterator i; + void *id; + int r; + + assert(bus); + assert(reply); + assert(status_set); + + r = sd_bus_message_open_container(reply, 'r', "aiai"); + if (r < 0) + return r; + + r = sd_bus_message_open_container(reply, 'a', "i"); + if (r < 0) + return r; + + SET_FOREACH(id, status_set->status, i) { + int val = PTR_TO_INT(id); + + if (val < 0 || val > 255) + continue; + + r = sd_bus_message_append_basic(reply, 'i', &val); + if (r < 0) + return r; + } + + r = sd_bus_message_close_container(reply); + if (r < 0) + return r; + + r = sd_bus_message_open_container(reply, 'a', "i"); + if (r < 0) + return r; + + SET_FOREACH(id, status_set->signal, i) { + int val = PTR_TO_INT(id); + const char *str; + + str = signal_to_string(val); + if (!str) + continue; + + r = sd_bus_message_append_basic(reply, 'i', &val); + if (r < 0) + return r; + } + + r = sd_bus_message_close_container(reply); + if (r < 0) + return r; + + return sd_bus_message_close_container(reply); +} + const sd_bus_vtable bus_service_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST), @@ -57,6 +127,9 @@ const sd_bus_vtable bus_service_vtable[] = { SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("GuessMainPID", "b", bus_property_get_bool, offsetof(Service, guess_main_pid), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RestartPreventExitStatus", "(aiai)", property_get_exit_status_set, offsetof(Service, restart_prevent_status), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RestartForceExitStatus", "(aiai)", property_get_exit_status_set, offsetof(Service, restart_force_status), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("SuccessExitStatus", "(aiai)", property_get_exit_status_set, offsetof(Service, success_status), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MainPID", "u", bus_property_get_pid, offsetof(Service, main_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Service, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), SD_BUS_VTABLE_PROPERTY_CONST), @@ -88,265 +161,210 @@ const sd_bus_vtable bus_service_vtable[] = { SD_BUS_VTABLE_END }; -static int bus_service_set_transient_property( - Service *s, +static int bus_set_transient_exit_status( + Unit *u, const char *name, + ExitStatusSet *status_set, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) { - ServiceExecCommand ci; + const int *status, *signal; + size_t sz_status, sz_signal, i; int r; - assert(s); - assert(name); - assert(message); - - flags |= UNIT_PRIVATE; + r = sd_bus_message_enter_container(message, 'r', "aiai"); + if (r < 0) + return r; - if (streq(name, "RemainAfterExit")) { - int b; + r = sd_bus_message_read_array(message, 'i', (const void **) &status, &sz_status); + if (r < 0) + return r; - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; + r = sd_bus_message_read_array(message, 'i', (const void **) &signal, &sz_signal); + if (r < 0) + return r; - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - s->remain_after_exit = b; - unit_write_settingf(UNIT(s), flags, name, "RemainAfterExit=%s", yes_no(b)); - } + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + if (sz_status == 0 && sz_signal == 0 && !UNIT_WRITE_FLAGS_NOOP(flags)) { + exit_status_set_free(status_set); + unit_write_settingf(u, flags, name, "%s=", name); return 1; + } - } else if (streq(name, "Type")) { - const char *t; - ServiceType k; - - r = sd_bus_message_read(message, "s", &t); - if (r < 0) - return r; - - k = service_type_from_string(t); - if (k < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service type %s", t); + for (i = 0; i < sz_status; i++) { + if (status[i] < 0 || status[i] > 255) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid status code in %s: %i", name, status[i]); if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - s->type = k; - unit_write_settingf(UNIT(s), flags, name, "Type=%s", service_type_to_string(s->type)); - } - - return 1; - } else if (streq(name, "RuntimeMaxUSec")) { - usec_t u; + r = set_ensure_allocated(&status_set->status, NULL); + if (r < 0) + return r; - r = sd_bus_message_read(message, "t", &u); - if (r < 0) - return r; + r = set_put(status_set->status, INT_TO_PTR(status[i])); + if (r < 0) + return r; - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - s->runtime_max_usec = u; - unit_write_settingf(UNIT(s), flags, name, "RuntimeMaxSec=" USEC_FMT "us", u); + unit_write_settingf(u, flags, name, "%s=%i", name, status[i]); } + } - return 1; - - } else if (streq(name, "Restart")) { - ServiceRestart sr; - const char *v; - - r = sd_bus_message_read(message, "s", &v); - if (r < 0) - return r; + for (i = 0; i < sz_signal; i++) { + const char *str; - if (isempty(v)) - sr = SERVICE_RESTART_NO; - else { - sr = service_restart_from_string(v); - if (sr < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid restart setting: %s", v); - } + str = signal_to_string(signal[i]); + if (!str) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal in %s: %i", name, signal[i]); if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - s->restart = sr; - unit_write_settingf(UNIT(s), flags, name, "Restart=%s", service_restart_to_string(sr)); - } - - return 1; - - } else if (STR_IN_SET(name, - "StandardInputFileDescriptor", - "StandardOutputFileDescriptor", - "StandardErrorFileDescriptor")) { - int fd; + r = set_ensure_allocated(&status_set->signal, NULL); + if (r < 0) + return r; - r = sd_bus_message_read(message, "h", &fd); - if (r < 0) - return r; + r = set_put(status_set->signal, INT_TO_PTR(signal[i])); + if (r < 0) + return r; - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - int copy; - - copy = fcntl(fd, F_DUPFD_CLOEXEC, 3); - if (copy < 0) - return -errno; - - if (streq(name, "StandardInputFileDescriptor")) { - asynchronous_close(s->stdin_fd); - s->stdin_fd = copy; - } else if (streq(name, "StandardOutputFileDescriptor")) { - asynchronous_close(s->stdout_fd); - s->stdout_fd = copy; - } else { - asynchronous_close(s->stderr_fd); - s->stderr_fd = copy; - } - - s->exec_context.stdio_as_fds = true; + unit_write_settingf(u, flags, name, "%s=%s", name, str); } + } - return 1; - - } else if (streq(name, "FileDescriptorStoreMax")) { - uint32_t u; + return 1; +} - r = sd_bus_message_read(message, "u", &u); - if (r < 0) - return r; +static int bus_set_transient_std_fd( + Unit *u, + const char *name, + int *p, + bool *b, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - s->n_fd_store_max = (unsigned) u; - unit_write_settingf(UNIT(s), flags, name, "FileDescriptorStoreMax=%" PRIu32, u); - } + int fd, r; - return 1; + assert(p); + assert(b); - } else if (streq(name, "NotifyAccess")) { - const char *t; - NotifyAccess k; + r = sd_bus_message_read(message, "h", &fd); + if (r < 0) + return r; - r = sd_bus_message_read(message, "s", &t); - if (r < 0) - return r; + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + int copy; - k = notify_access_from_string(t); - if (k < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid notify access setting %s", t); + copy = fcntl(fd, F_DUPFD_CLOEXEC, 3); + if (copy < 0) + return -errno; - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - s->notify_access = k; - unit_write_settingf(UNIT(s), flags, name, "NotifyAccess=%s", notify_access_to_string(s->notify_access)); - } + asynchronous_close(*p); + *p = copy; + *b = true; + } - return 1; + return 1; +} +static BUS_DEFINE_SET_TRANSIENT_PARSE(notify_access, NotifyAccess, notify_access_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE(service_type, ServiceType, service_type_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart, ServiceRestart, service_restart_from_string); +static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name, service_name_is_valid); - } else if ((ci = service_exec_command_from_string(name)) >= 0) { - unsigned n = 0; +static int bus_service_set_transient_property( + Service *s, + const char *name, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { - r = sd_bus_message_enter_container(message, 'a', "(sasb)"); - if (r < 0) - return r; + Unit *u = UNIT(s); + ServiceExecCommand ci; + int r; - while ((r = sd_bus_message_enter_container(message, 'r', "sasb")) > 0) { - _cleanup_strv_free_ char **argv = NULL; - const char *path; - int b; + assert(s); + assert(name); + assert(message); - r = sd_bus_message_read(message, "s", &path); - if (r < 0) - return r; + flags |= UNIT_PRIVATE; - if (!path_is_absolute(path)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path); + if (streq(name, "PermissionsStartOnly")) + return bus_set_transient_bool(u, name, &s->permissions_start_only, message, flags, error); - r = sd_bus_message_read_strv(message, &argv); - if (r < 0) - return r; + if (streq(name, "RootDirectoryStartOnly")) + return bus_set_transient_bool(u, name, &s->root_directory_start_only, message, flags, error); - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; + if (streq(name, "RemainAfterExit")) + return bus_set_transient_bool(u, name, &s->remain_after_exit, message, flags, error); - r = sd_bus_message_exit_container(message); - if (r < 0) - return r; + if (streq(name, "GuessMainPID")) + return bus_set_transient_bool(u, name, &s->guess_main_pid, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - ExecCommand *c; + if (streq(name, "Type")) + return bus_set_transient_service_type(u, name, &s->type, message, flags, error); - c = new0(ExecCommand, 1); - if (!c) - return -ENOMEM; + if (streq(name, "RestartUSec")) + return bus_set_transient_usec(u, name, &s->restart_usec, message, flags, error); - c->path = strdup(path); - if (!c->path) { - free(c); - return -ENOMEM; - } + if (streq(name, "TimeoutStartUSec")) { + r = bus_set_transient_usec(u, name, &s->timeout_start_usec, message, flags, error); + if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags)) + s->start_timeout_defined = true; - c->argv = argv; - argv = NULL; + return r; + } - c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0; + if (streq(name, "TimeoutStopUSec")) + return bus_set_transient_usec(u, name, &s->timeout_stop_usec, message, flags, error); - path_kill_slashes(c->path); - exec_command_append_list(&s->exec_command[ci], c); - } + if (streq(name, "RuntimeMaxUSec")) + return bus_set_transient_usec(u, name, &s->runtime_max_usec, message, flags, error); - n++; - } + if (streq(name, "WatchdogUSec")) + return bus_set_transient_usec(u, name, &s->watchdog_usec, message, flags, error); - if (r < 0) - return r; + if (streq(name, "FileDescriptorStoreMax")) + return bus_set_transient_unsigned(u, name, &s->n_fd_store_max, message, flags, error); - r = sd_bus_message_exit_container(message); - if (r < 0) - return r; + if (streq(name, "NotifyAccess")) + return bus_set_transient_notify_access(u, name, &s->notify_access, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - _cleanup_free_ char *buf = NULL; - _cleanup_fclose_ FILE *f = NULL; - ExecCommand *c; - size_t size = 0; + if (streq(name, "PIDFile")) + return bus_set_transient_path(u, name, &s->pid_file, message, flags, error); - if (n == 0) - s->exec_command[ci] = exec_command_free_list(s->exec_command[ci]); + if (streq(name, "USBFunctionDescriptors")) + return bus_set_transient_path(u, name, &s->usb_function_descriptors, message, flags, error); - f = open_memstream(&buf, &size); - if (!f) - return -ENOMEM; + if (streq(name, "USBFunctionStrings")) + return bus_set_transient_path(u, name, &s->usb_function_strings, message, flags, error); - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + if (streq(name, "BusName")) + return bus_set_transient_bus_name(u, name, &s->bus_name, message, flags, error); - fputs("ExecStart=\n", f); + if (streq(name, "Restart")) + return bus_set_transient_service_restart(u, name, &s->restart, message, flags, error); - LIST_FOREACH(command, c, s->exec_command[ci]) { - _cleanup_free_ char *a = NULL, *t = NULL; - const char *p; + if (streq(name, "RestartPreventExitStatus")) + return bus_set_transient_exit_status(u, name, &s->restart_prevent_status, message, flags, error); - p = unit_escape_setting(c->path, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS, &t); - if (!p) - return -ENOMEM; + if (streq(name, "RestartForceExitStatus")) + return bus_set_transient_exit_status(u, name, &s->restart_force_status, message, flags, error); - a = unit_concat_strv(c->argv, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS); - if (!a) - return -ENOMEM; + if (streq(name, "SuccessExitStatus")) + return bus_set_transient_exit_status(u, name, &s->success_status, message, flags, error); - fprintf(f, "%s=%s@%s %s\n", - name, - c->flags & EXEC_COMMAND_IGNORE_FAILURE ? "-" : "", - p, - a); - } + if ((ci = service_exec_command_from_string(name)) >= 0) + return bus_set_transient_exec_command(u, name, &s->exec_command[ci], message, flags, error); - r = fflush_and_check(f); - if (r < 0) - return r; + if (streq(name, "StandardInputFileDescriptor")) + return bus_set_transient_std_fd(u, name, &s->stdin_fd, &s->exec_context.stdio_as_fds, message, flags, error); - unit_write_setting(UNIT(s), flags, name, buf); - } + if (streq(name, "StandardOutputFileDescriptor")) + return bus_set_transient_std_fd(u, name, &s->stdout_fd, &s->exec_context.stdio_as_fds, message, flags, error); - return 1; - } + if (streq(name, "StandardErrorFileDescriptor")) + return bus_set_transient_std_fd(u, name, &s->stderr_fd, &s->exec_context.stdio_as_fds, message, flags, error); return 0; } diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 930b7fa87d..035651f213 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -22,8 +22,15 @@ #include "bus-util.h" #include "dbus-cgroup.h" #include "dbus-execute.h" +#include "dbus-kill.h" #include "dbus-socket.h" +#include "dbus-util.h" +#include "fd-util.h" +#include "parse-util.h" +#include "path-util.h" #include "socket.h" +#include "socket-protocol-list.h" +#include "socket-util.h" #include "string-util.h" #include "unit.h" @@ -141,6 +148,7 @@ const sd_bus_vtable bus_socket_vtable[] = { SD_BUS_PROPERTY("MaxConnectionsPerSource", "u", bus_property_get_unsigned, offsetof(Socket, max_connections_per_source), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MessageQueueMaxMessages", "x", bus_property_get_long, offsetof(Socket, mq_maxmsg), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MessageQueueMessageSize", "x", bus_property_get_long, offsetof(Socket, mq_msgsize), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("TCPCongestion", "s", NULL, offsetof(Socket, tcp_congestion), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ReusePort", "b", bus_property_get_bool, offsetof(Socket, reuse_port), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SmackLabel", "s", NULL, offsetof(Socket, smack), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SmackLabelIPIn", "s", NULL, offsetof(Socket, smack_ip_in), SD_BUS_VTABLE_PROPERTY_CONST), @@ -162,6 +170,286 @@ const sd_bus_vtable bus_socket_vtable[] = { SD_BUS_VTABLE_END }; +static inline bool check_size_t_truncation(uint64_t t) { + return (size_t) t == t; +} + +static inline const char* socket_protocol_to_name_supported(int32_t i) { + if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP)) + return NULL; + + return socket_protocol_to_name(i); +} + +static BUS_DEFINE_SET_TRANSIENT(int, "i", int32_t, int, "%" PRIi32); +static BUS_DEFINE_SET_TRANSIENT(message_queue, "x", int64_t, long, "%" PRIi64); +static BUS_DEFINE_SET_TRANSIENT_IS_VALID(size_t_check_truncation, "t", uint64_t, size_t, "%" PRIu64, check_size_t_truncation); +static BUS_DEFINE_SET_TRANSIENT_PARSE(bind_ipv6_only, SocketAddressBindIPv6Only, parse_socket_address_bind_ipv6_only_or_bool); +static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(fdname, fdname_is_valid); +static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(ifname, ifname_valid); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(ip_tos, "i", int32_t, int, "%" PRIi32, ip_tos_to_string_alloc); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING(socket_protocol, "i", int32_t, int, "%" PRIi32, socket_protocol_to_name_supported); + +static int bus_socket_set_transient_property( + Socket *s, + const char *name, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + SocketExecCommand ci; + Unit *u = UNIT(s); + int r; + + assert(s); + assert(name); + assert(message); + + flags |= UNIT_PRIVATE; + + if (streq(name, "Accept")) + return bus_set_transient_bool(u, name, &s->accept, message, flags, error); + + if (streq(name, "Writable")) + return bus_set_transient_bool(u, name, &s->writable, message, flags, error); + + if (streq(name, "KeepAlive")) + return bus_set_transient_bool(u, name, &s->keep_alive, message, flags, error); + + if (streq(name, "NoDelay")) + return bus_set_transient_bool(u, name, &s->no_delay, message, flags, error); + + if (streq(name, "FreeBind")) + return bus_set_transient_bool(u, name, &s->free_bind, message, flags, error); + + if (streq(name, "Transparent")) + return bus_set_transient_bool(u, name, &s->transparent, message, flags, error); + + if (streq(name, "Broadcast")) + return bus_set_transient_bool(u, name, &s->broadcast, message, flags, error); + + if (streq(name, "PassCredentials")) + return bus_set_transient_bool(u, name, &s->pass_cred, message, flags, error); + + if (streq(name, "PassSecurity")) + return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error); + + if (streq(name, "ReusePort")) + return bus_set_transient_bool(u, name, &s->reuse_port, message, flags, error); + + if (streq(name, "RemoveOnStop")) + return bus_set_transient_bool(u, name, &s->remove_on_stop, message, flags, error); + + if (streq(name, "SELinuxContextFromNet")) + return bus_set_transient_bool(u, name, &s->selinux_context_from_net, message, flags, error); + + if (streq(name, "Priority")) + return bus_set_transient_int(u, name, &s->priority, message, flags, error); + + if (streq(name, "IPTTL")) + return bus_set_transient_int(u, name, &s->ip_ttl, message, flags, error); + + if (streq(name, "Mark")) + return bus_set_transient_int(u, name, &s->mark, message, flags, error); + + if (streq(name, "Backlog")) + return bus_set_transient_unsigned(u, name, &s->backlog, message, flags, error); + + if (streq(name, "MaxConnections")) + return bus_set_transient_unsigned(u, name, &s->max_connections, message, flags, error); + + if (streq(name, "MaxConnectionsPerSource")) + return bus_set_transient_unsigned(u, name, &s->max_connections_per_source, message, flags, error); + + if (streq(name, "KeepAliveProbes")) + return bus_set_transient_unsigned(u, name, &s->keep_alive_cnt, message, flags, error); + + if (streq(name, "TriggerLimitBurst")) + return bus_set_transient_unsigned(u, name, &s->trigger_limit.burst, message, flags, error); + + if (streq(name, "SocketMode")) + return bus_set_transient_mode_t(u, name, &s->socket_mode, message, flags, error); + + if (streq(name, "DirectoryMode")) + return bus_set_transient_mode_t(u, name, &s->directory_mode, message, flags, error); + + if (streq(name, "MessageQueueMaxMessages")) + return bus_set_transient_message_queue(u, name, &s->mq_maxmsg, message, flags, error); + + if (streq(name, "MessageQueueMessageSize")) + return bus_set_transient_message_queue(u, name, &s->mq_msgsize, message, flags, error); + + if (streq(name, "TimeoutUSec")) + return bus_set_transient_usec_fix_0(u, name, &s->timeout_usec, message, flags, error); + + if (streq(name, "KeepAliveTimeUSec")) + return bus_set_transient_usec(u, name, &s->keep_alive_time, message, flags, error); + + if (streq(name, "KeepAliveIntervalUSec")) + return bus_set_transient_usec(u, name, &s->keep_alive_interval, message, flags, error); + + if (streq(name, "DeferAcceptUSec")) + return bus_set_transient_usec(u, name, &s->defer_accept, message, flags, error); + + if (streq(name, "TriggerLimitIntervalUSec")) + return bus_set_transient_usec(u, name, &s->trigger_limit.interval, message, flags, error); + + if (streq(name, "SmackLabel")) + return bus_set_transient_string(u, name, &s->smack, message, flags, error); + + if (streq(name, "SmackLabelIPin")) + return bus_set_transient_string(u, name, &s->smack_ip_in, message, flags, error); + + if (streq(name, "SmackLabelIPOut")) + return bus_set_transient_string(u, name, &s->smack_ip_out, message, flags, error); + + if (streq(name, "TCPCongestion")) + return bus_set_transient_string(u, name, &s->tcp_congestion, message, flags, error); + + if (streq(name, "FileDescriptorName")) + return bus_set_transient_fdname(u, name, &s->fdname, message, flags, error); + + if (streq(name, "SocketUser")) + return bus_set_transient_user(u, name, &s->user, message, flags, error); + + if (streq(name, "SocketGroup")) + return bus_set_transient_user(u, name, &s->group, message, flags, error); + + if (streq(name, "BindIPv6Only")) + return bus_set_transient_bind_ipv6_only(u, name, &s->bind_ipv6_only, message, flags, error); + + if (streq(name, "ReceiveBuffer")) + return bus_set_transient_size_t_check_truncation(u, name, &s->receive_buffer, message, flags, error); + + if (streq(name, "SendBuffer")) + return bus_set_transient_size_t_check_truncation(u, name, &s->send_buffer, message, flags, error); + + if (streq(name, "PipeSize")) + return bus_set_transient_size_t_check_truncation(u, name, &s->pipe_size, message, flags, error); + + if (streq(name, "BindToDevice")) + return bus_set_transient_ifname(u, name, &s->bind_to_device, message, flags, error); + + if (streq(name, "IPTOS")) + return bus_set_transient_ip_tos(u, name, &s->ip_tos, message, flags, error); + + if (streq(name, "SocketProtocol")) + return bus_set_transient_socket_protocol(u, name, &s->socket_protocol, message, flags, error); + + if ((ci = socket_exec_command_from_string(name)) >= 0) + return bus_set_transient_exec_command(u, name, &s->exec_command[ci], message, flags, error); + + if (streq(name, "Symlinks")) { + _cleanup_strv_free_ char **l = NULL; + char **p; + + r = sd_bus_message_read_strv(message, &l); + if (r < 0) + return r; + + STRV_FOREACH(p, l) { + if (!path_is_absolute(*p)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Symlink path is not absolute: %s", *p); + } + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (strv_isempty(l)) { + s->symlinks = strv_free(s->symlinks); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=", name); + } else { + _cleanup_free_ char *joined = NULL; + + r = strv_extend_strv(&s->symlinks, l, true); + if (r < 0) + return -ENOMEM; + + joined = strv_join(l, " "); + if (!joined) + return -ENOMEM; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined); + } + } + + return 1; + + } else if (streq(name, "Listen")) { + const char *t, *a; + bool empty = true; + + r = sd_bus_message_enter_container(message, 'a', "(ss)"); + if (r < 0) + return r; + + while ((r = sd_bus_message_read(message, "(ss)", &t, &a)) > 0) { + _cleanup_free_ SocketPort *p = NULL; + + p = new0(SocketPort, 1); + if (!p) + return log_oom(); + + p->type = socket_port_type_from_string(t); + if (p->type < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown Socket type: %s", t); + + if (p->type != SOCKET_SOCKET) { + p->path = strdup(a); + path_kill_slashes(p->path); + + } else if (streq(t, "Netlink")) { + r = socket_address_parse_netlink(&p->address, a); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid netlink address: %s", a); + + } else { + r = socket_address_parse(&p->address, a); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address: %s", a); + + p->address.type = socket_address_type_from_string(t); + if (p->address.type < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address type: %s", t); + + if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Address family not supported: %s", a); + } + + p->fd = -1; + p->auxiliary_fds = NULL; + p->n_auxiliary_fds = 0; + p->socket = s; + + empty = false; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + SocketPort *tail; + + LIST_FIND_TAIL(port, s->ports, tail); + LIST_INSERT_AFTER(port, s->ports, tail, p); + + p = NULL; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Listen%s=%s", t, a); + } + } + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) { + socket_free_ports(s); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "ListenStream="); + } + + return 1; + } + + return 0; +} + int bus_socket_set_property( Unit *u, const char *name, @@ -170,12 +458,37 @@ int bus_socket_set_property( sd_bus_error *error) { Socket *s = SOCKET(u); + int r; assert(s); assert(name); assert(message); - return bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error); + assert(s); + assert(name); + assert(message); + + r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error); + if (r != 0) + return r; + + if (u->transient && u->load_state == UNIT_STUB) { + /* This is a transient unit, let's load a little more */ + + r = bus_socket_set_transient_property(s, name, message, flags, error); + if (r != 0) + return r; + + r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, flags, error); + if (r != 0) + return r; + + r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, flags, error); + if (r != 0) + return r; + } + + return 0; } int bus_socket_commit_properties(Unit *u) { diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c index 3e64536b17..1eedf217fe 100644 --- a/src/core/dbus-timer.c +++ b/src/core/dbus-timer.c @@ -21,6 +21,7 @@ #include "alloc-util.h" #include "bus-util.h" #include "dbus-timer.h" +#include "dbus-util.h" #include "strv.h" #include "timer.h" #include "unit.h" @@ -179,6 +180,7 @@ static int bus_timer_set_transient_property( UnitWriteFlags flags, sd_bus_error *error) { + Unit *u = UNIT(t); int r; assert(t); @@ -187,7 +189,130 @@ static int bus_timer_set_transient_property( flags |= UNIT_PRIVATE; - if (STR_IN_SET(name, + if (streq(name, "AccuracyUSec")) + return bus_set_transient_usec(u, name, &t->accuracy_usec, message, flags, error); + + if (streq(name, "AccuracySec")) { + log_notice("Client is using obsolete AccuracySec= transient property, please use AccuracyUSec= instead."); + return bus_set_transient_usec(u, "AccuracyUSec", &t->accuracy_usec, message, flags, error); + } + + if (streq(name, "RandomizedDelayUSec")) + return bus_set_transient_usec(u, name, &t->random_usec, message, flags, error); + + if (streq(name, "WakeSystem")) + return bus_set_transient_bool(u, name, &t->wake_system, message, flags, error); + + if (streq(name, "Persistent")) + return bus_set_transient_bool(u, name, &t->persistent, message, flags, error); + + if (streq(name, "RemainAfterElapse")) + return bus_set_transient_bool(u, name, &t->remain_after_elapse, message, flags, error); + + if (streq(name, "TimersMonotonic")) { + const char *base_name; + usec_t usec = 0; + bool empty = true; + + r = sd_bus_message_enter_container(message, 'a', "(st)"); + if (r < 0) + return r; + + while ((r = sd_bus_message_read(message, "(st)", &base_name, &usec)) > 0) { + TimerBase b; + + b = timer_base_from_string(base_name); + if (b < 0 || b == TIMER_CALENDAR) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid timer base: %s", base_name); + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + char ts[FORMAT_TIMESPAN_MAX]; + TimerValue *v; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", base_name, + format_timespan(ts, sizeof(ts), usec, USEC_PER_MSEC)); + + v = new0(TimerValue, 1); + if (!v) + return -ENOMEM; + + v->base = b; + v->value = usec; + + LIST_PREPEND(value, t->values, v); + } + + empty = false; + } + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) { + timer_free_values(t); + unit_write_setting(u, flags, name, "OnActiveSec="); + } + + return 1; + + } else if (streq(name, "TimersCalendar")) { + const char *base_name, *str; + bool empty = true; + + r = sd_bus_message_enter_container(message, 'a', "(ss)"); + if (r < 0) + return r; + + while ((r = sd_bus_message_read(message, "(ss)", &base_name, &str)) > 0) { + _cleanup_(calendar_spec_freep) CalendarSpec *c = NULL; + TimerBase b; + + b = timer_base_from_string(base_name); + if (b != TIMER_CALENDAR) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid timer base: %s", base_name); + + r = calendar_spec_from_string(str, &c); + if (r == -EINVAL) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid calendar spec: %s", str); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + TimerValue *v; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", base_name, str); + + v = new0(TimerValue, 1); + if (!v) + return -ENOMEM; + + v->base = b; + v->calendar_spec = c; + c = NULL; + + LIST_PREPEND(value, t->values, v); + } + + empty = false; + } + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) { + timer_free_values(t); + unit_write_setting(u, flags, name, "OnCalendar="); + } + + return 1; + + } else if (STR_IN_SET(name, "OnActiveSec", "OnBootSec", "OnStartupSec", @@ -196,27 +321,30 @@ static int bus_timer_set_transient_property( TimerValue *v; TimerBase b = _TIMER_BASE_INVALID; - usec_t u = 0; + usec_t usec = 0; + + log_notice("Client is using obsolete %s= transient property, please use TimersMonotonic= instead.", name); b = timer_base_from_string(name); if (b < 0) - return -EINVAL; + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown timer base"); - r = sd_bus_message_read(message, "t", &u); + r = sd_bus_message_read(message, "t", &usec); if (r < 0) return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { char time[FORMAT_TIMESPAN_MAX]; - unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC)); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, + format_timespan(time, sizeof(time), usec, USEC_PER_MSEC)); v = new0(TimerValue, 1); if (!v) return -ENOMEM; v->base = b; - v->value = u; + v->value = usec; LIST_PREPEND(value, t->values, v); } @@ -226,84 +354,36 @@ static int bus_timer_set_transient_property( } else if (streq(name, "OnCalendar")) { TimerValue *v; - CalendarSpec *c = NULL; + _cleanup_(calendar_spec_freep) CalendarSpec *c = NULL; const char *str; + log_notice("Client is using obsolete %s= transient property, please use TimersCalendar= instead.", name); + r = sd_bus_message_read(message, "s", &str); if (r < 0) return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = calendar_spec_from_string(str, &c); + if (r == -EINVAL) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid calendar spec"); if (r < 0) return r; - unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, str); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, str); v = new0(TimerValue, 1); - if (!v) { - calendar_spec_free(c); + if (!v) return -ENOMEM; - } v->base = TIMER_CALENDAR; v->calendar_spec = c; + c = NULL; LIST_PREPEND(value, t->values, v); } return 1; - - } else if (STR_IN_SET(name, "AccuracyUSec", "AccuracySec")) { - usec_t u = 0; - - if (streq(name, "AccuracySec")) - log_notice("Client is using obsolete AccuracySec= transient property, please use AccuracyUSec= instead."); - - r = sd_bus_message_read(message, "t", &u); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - t->accuracy_usec = u; - unit_write_settingf(UNIT(t), flags, name, "AccuracySec=" USEC_FMT "us", u); - } - - return 1; - - } else if (streq(name, "RandomizedDelayUSec")) { - usec_t u = 0; - - r = sd_bus_message_read(message, "t", &u); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - t->random_usec = u; - unit_write_settingf(UNIT(t), flags, name, "RandomizedDelaySec=" USEC_FMT "us", u); - } - - return 1; - - } else if (STR_IN_SET(name, "WakeSystem", "Persistent", "RemainAfterElapse")) { - int b; - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (streq(name, "WakeSystem")) - t->wake_system = b; - else if (streq(name, "Persistent")) - t->persistent = b; - else /* RemainAfterElapse */ - t->remain_after_elapse = b; - - unit_write_settingf(UNIT(t), flags, name, "%s=%s", name, yes_no(b)); - } - - return 1; } return 0; diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index cdab461d58..7085eee930 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -24,12 +24,15 @@ #include "bpf-firewall.h" #include "bus-common-errors.h" #include "cgroup-util.h" +#include "condition.h" #include "dbus-job.h" #include "dbus-unit.h" +#include "dbus-util.h" #include "dbus.h" #include "fd-util.h" #include "locale-util.h" #include "log.h" +#include "path-util.h" #include "process-util.h" #include "selinux-access.h" #include "signal-util.h" @@ -37,6 +40,7 @@ #include "string-util.h" #include "strv.h" #include "user-util.h" +#include "web-util.h" static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode); static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState); @@ -795,7 +799,7 @@ const sd_bus_vtable bus_unit_vtable[] = { SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Perpetual", "b", bus_property_get_bool, offsetof(Unit, perpetual), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("StartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action, offsetof(Unit, failure_action), SD_BUS_VTABLE_PROPERTY_CONST), @@ -823,6 +827,7 @@ const sd_bus_vtable bus_unit_vtable[] = { SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_obsolete_dependencies, 0, SD_BUS_VTABLE_HIDDEN), SD_BUS_PROPERTY("RequisiteOfOverridable", "as", property_get_obsolete_dependencies, 0, SD_BUS_VTABLE_HIDDEN), SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), + SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), SD_BUS_VTABLE_END }; @@ -1352,6 +1357,81 @@ static int bus_unit_set_live_property( return 0; } +static BUS_DEFINE_SET_TRANSIENT_PARSE(collect_mode, CollectMode, collect_mode_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE(emergency_action, EmergencyAction, emergency_action_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE(job_mode, JobMode, job_mode_from_string); + +static int bus_set_transient_conditions( + Unit *u, + const char *name, + Condition **list, + bool is_condition, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + const char *type_name, *param; + int trigger, negate, r; + bool empty = true; + + assert(list); + + r = sd_bus_message_enter_container(message, 'a', "(sbbs)"); + if (r < 0) + return r; + + while ((r = sd_bus_message_read(message, "(sbbs)", &type_name, &trigger, &negate, ¶m)) > 0) { + ConditionType t; + + t = is_condition ? condition_type_from_string(type_name) : assert_type_from_string(type_name); + if (t < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid condition type: %s", type_name); + + if (t != CONDITION_NULL) { + if (isempty(param)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Condition parameter in %s is empty", type_name); + + if (condition_takes_path(t) && !path_is_absolute(param)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in condition %s is not absolute: %s", type_name, param); + } else + param = NULL; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + Condition *c; + + c = condition_new(t, param, trigger, negate); + if (!c) + return -ENOMEM; + + LIST_PREPEND(conditions, *list, c); + + if (t != CONDITION_NULL) + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, + "%s=%s%s%s", type_name, + trigger ? "|" : "", negate ? "!" : "", param); + else + unit_write_settingf(u, flags, name, + "%s=%s%s", type_name, + trigger ? "|" : "", yes_no(!negate)); + } + + empty = false; + } + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) { + *list = condition_free_list(*list); + unit_write_settingf(u, flags, name, "%sNull=", is_condition ? "Condition" : "Assert"); + } + + return 1; +} + static int bus_unit_set_transient_property( Unit *u, const char *name, @@ -1359,6 +1439,7 @@ static int bus_unit_set_transient_property( UnitWriteFlags flags, sd_bus_error *error) { + UnitDependency d = _UNIT_DEPENDENCY_INVALID; int r; assert(u); @@ -1368,35 +1449,100 @@ static int bus_unit_set_transient_property( /* Handles settings when transient units are created. This settings cannot be altered anymore after the unit * has been created. */ - if (streq(name, "DefaultDependencies")) { - int b; + if (streq(name, "SourcePath")) + return bus_set_transient_path(u, name, &u->source_path, message, flags, error); - r = sd_bus_message_read(message, "b", &b); - if (r < 0) - return r; + if (streq(name, "StopWhenUnneeded")) + return bus_set_transient_bool(u, name, &u->stop_when_unneeded, message, flags, error); - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - u->default_dependencies = b; - unit_write_settingf(u, flags, name, "DefaultDependencies=%s", yes_no(b)); - } + if (streq(name, "RefuseManualStart")) + return bus_set_transient_bool(u, name, &u->refuse_manual_start, message, flags, error); - return 1; + if (streq(name, "RefuseManualStop")) + return bus_set_transient_bool(u, name, &u->refuse_manual_stop, message, flags, error); - } else if (streq(name, "CollectMode")) { - const char *s; - CollectMode m; + if (streq(name, "AllowIsolate")) + return bus_set_transient_bool(u, name, &u->allow_isolate, message, flags, error); - r = sd_bus_message_read(message, "s", &s); + if (streq(name, "DefaultDependencies")) + return bus_set_transient_bool(u, name, &u->default_dependencies, message, flags, error); + + if (streq(name, "OnFailureJobMode")) + return bus_set_transient_job_mode(u, name, &u->on_failure_job_mode, message, flags, error); + + if (streq(name, "IgnoreOnIsolate")) + return bus_set_transient_bool(u, name, &u->ignore_on_isolate, message, flags, error); + + if (streq(name, "JobTimeoutUSec")) { + r = bus_set_transient_usec_fix_0(u, name, &u->job_timeout, message, flags, error); + if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags) && !u->job_running_timeout_set) + u->job_running_timeout = u->job_timeout; + } + + if (streq(name, "JobRunningTimeoutUSec")) { + r = bus_set_transient_usec_fix_0(u, name, &u->job_running_timeout, message, flags, error); + if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags)) + u->job_running_timeout_set = true; + + return r; + } + + if (streq(name, "JobTimeoutAction")) + return bus_set_transient_emergency_action(u, name, &u->job_timeout_action, message, flags, error); + + if (streq(name, "JobTimeoutRebootArgument")) + return bus_set_transient_string(u, name, &u->job_timeout_reboot_arg, message, flags, error); + + if (streq(name, "StartLimitIntervalUSec")) + return bus_set_transient_usec(u, name, &u->start_limit.interval, message, flags, error); + + if (streq(name, "StartLimitBurst")) + return bus_set_transient_unsigned(u, name, &u->start_limit.burst, message, flags, error); + + if (streq(name, "StartLimitAction")) + return bus_set_transient_emergency_action(u, name, &u->start_limit_action, message, flags, error); + + if (streq(name, "FailureAction")) + return bus_set_transient_emergency_action(u, name, &u->failure_action, message, flags, error); + + if (streq(name, "SuccessAction")) + return bus_set_transient_emergency_action(u, name, &u->success_action, message, flags, error); + + if (streq(name, "RebootArgument")) + return bus_set_transient_string(u, name, &u->reboot_arg, message, flags, error); + + if (streq(name, "CollectMode")) + return bus_set_transient_collect_mode(u, name, &u->collect_mode, message, flags, error); + + if (streq(name, "Conditions")) + return bus_set_transient_conditions(u, name, &u->conditions, true, message, flags, error); + + if (streq(name, "Asserts")) + return bus_set_transient_conditions(u, name, &u->asserts, false, message, flags, error); + + if (streq(name, "Documentation")) { + _cleanup_strv_free_ char **l = NULL; + char **p; + + r = sd_bus_message_read_strv(message, &l); if (r < 0) return r; - m = collect_mode_from_string(s); - if (m < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown garbage collection mode: %s", s); + STRV_FOREACH(p, l) { + if (!documentation_url_is_valid(*p)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid URL in %s: %s", name, *p); + } if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - u->collect_mode = m; - unit_write_settingf(u, flags, name, "CollectMode=%s", collect_mode_to_string(m)); + if (strv_isempty(l)) { + u->documentation = strv_free(u->documentation); + unit_write_settingf(u, flags, name, "%s=", name); + } else { + strv_extend_strv(&u->documentation, l, false); + + STRV_FOREACH(p, l) + unit_write_settingf(u, flags, name, "%s=%s", name, *p); + } } return 1; @@ -1439,30 +1585,40 @@ static int bus_unit_set_transient_property( return 1; - } else if (STR_IN_SET(name, - "Requires", "RequiresOverridable", - "Requisite", "RequisiteOverridable", - "Wants", - "BindsTo", - "Conflicts", - "Before", "After", - "OnFailure", - "PropagatesReloadTo", "ReloadPropagatedFrom", - "PartOf")) { - - UnitDependency d; - const char *other; + } else if (streq(name, "RequiresMountsFor")) { + _cleanup_strv_free_ char **l = NULL; + char **p; - if (streq(name, "RequiresOverridable")) - d = UNIT_REQUIRES; /* redirect for obsolete unit dependency type */ - else if (streq(name, "RequisiteOverridable")) - d = UNIT_REQUISITE; /* same here */ - else { - d = unit_dependency_from_string(name); - if (d < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit dependency: %s", name); + r = sd_bus_message_read_strv(message, &l); + if (r < 0) + return r; + + STRV_FOREACH(p, l) { + if (!path_is_absolute(*p)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not absolute: %s", name, *p); + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + r = unit_require_mounts_for(u, *p, UNIT_DEPENDENCY_FILE); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to add required mount \"%s\": %m", *p); + + unit_write_settingf(u, flags, name, "%s=%s", name, *p); + } } + return 1; + } + + if (streq(name, "RequiresOverridable")) + d = UNIT_REQUIRES; /* redirect for obsolete unit dependency type */ + else if (streq(name, "RequisiteOverridable")) + d = UNIT_REQUISITE; /* same here */ + else + d = unit_dependency_from_string(name); + + if (d >= 0) { + const char *other; + r = sd_bus_message_enter_container(message, 'a', "s"); if (r < 0) return r; @@ -1482,7 +1638,7 @@ static int bus_unit_set_transient_property( if (!label) return -ENOMEM; - unit_write_settingf(u, flags, label, "%s=%s", name, other); + unit_write_settingf(u, flags, label, "%s=%s", unit_dependency_to_string(d), other); } } @@ -1495,30 +1651,6 @@ static int bus_unit_set_transient_property( return 1; - } else if (STR_IN_SET(name, "FailureAction", "SuccessAction")) { - EmergencyAction action; - const char *s; - - r = sd_bus_message_read(message, "s", &s); - if (r < 0) - return r; - - action = emergency_action_from_string(s); - if (action < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid emergency action: %s", s); - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - - if (streq(name, "FailureAction")) - u->failure_action = action; - else - u->success_action = action; - - unit_write_settingf(u, flags, name, "%s=%s", name, emergency_action_to_string(action)); - } - - return 1; - } else if (streq(name, "AddRef")) { int b; diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c new file mode 100644 index 0000000000..75bbd07604 --- /dev/null +++ b/src/core/dbus-util.c @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "bus-util.h" +#include "dbus-util.h" +#include "parse-util.h" +#include "path-util.h" +#include "unit-printf.h" +#include "user-util.h" +#include "unit.h" + +BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o"); +BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32); +BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user, valid_user_group_name_or_id); +BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path, path_is_absolute); + +int bus_set_transient_string( + Unit *u, + const char *name, + char **p, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + const char *v; + int r; + + assert(p); + + r = sd_bus_message_read(message, "s", &v); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + r = free_and_strdup(p, empty_to_null(v)); + if (r < 0) + return r; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, + "%s=%s", name, strempty(v)); + } + + return 1; +} + +int bus_set_transient_bool( + Unit *u, + const char *name, + bool *p, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + int v, r; + + assert(p); + + r = sd_bus_message_read(message, "b", &v); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + *p = v; + unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v)); + } + + return 1; +} + +int bus_set_transient_usec_internal( + Unit *u, + const char *name, + usec_t *p, + bool fix_0, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + uint64_t v; + int r; + + assert(p); + + r = sd_bus_message_read(message, "t", &v); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + char *n, ts[FORMAT_TIMESPAN_MAX]; + + if (fix_0) + *p = v != 0 ? v: USEC_INFINITY; + else + *p = v; + + n = strndupa(name, strlen(name) - 4); + unit_write_settingf(u, flags, name, "%sSec=%s", n, + format_timespan(ts, sizeof(ts), v, USEC_PER_MSEC)); + } + + return 1; +} diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h new file mode 100644 index 0000000000..8260298577 --- /dev/null +++ b/src/core/dbus-util.h @@ -0,0 +1,351 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "sd-bus.h" +#include "unit.h" + +#define BUS_DEFINE_SET_TRANSIENT(function, bus_type, type, cast_type, fmt) \ + int bus_set_transient_##function( \ + Unit *u, \ + const char *name, \ + cast_type *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + type v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, bus_type, &v); \ + if (r < 0) \ + return r; \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + *p = (cast_type) v; \ + unit_write_settingf(u, flags, name, \ + "%s=" fmt, name, v); \ + } \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define BUS_DEFINE_SET_TRANSIENT_IS_VALID(function, bus_type, type, cast_type, fmt, check) \ + int bus_set_transient_##function( \ + Unit *u, \ + const char *name, \ + cast_type *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + type v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, bus_type, &v); \ + if (r < 0) \ + return r; \ + \ + if (!check(v)) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Invalid %s setting: " fmt, name, v); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + *p = (cast_type) v; \ + unit_write_settingf(u, flags, name, \ + "%s=" fmt, name, v); \ + } \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define BUS_DEFINE_SET_TRANSIENT_TO_STRING(function, bus_type, type, cast_type, fmt, to_string) \ + int bus_set_transient_##function( \ + Unit *u, \ + const char *name, \ + cast_type *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + const char *s; \ + type v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, bus_type, &v); \ + if (r < 0) \ + return r; \ + \ + s = to_string(v); \ + if (!s) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Invalid %s setting: " fmt, name, v); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + *p = (cast_type) v; \ + unit_write_settingf(u, flags, name, \ + "%s=%s", name, s); \ + } \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(function, bus_type, type, cast_type, fmt, to_string) \ + int bus_set_transient_##function( \ + Unit *u, \ + const char *name, \ + cast_type *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + _cleanup_free_ char *s = NULL; \ + type v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, bus_type, &v); \ + if (r < 0) \ + return r; \ + \ + r = to_string(v, &s); \ + if (r == -EINVAL) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Invalid %s setting: " fmt, name, v); \ + if (r < 0) \ + return r; \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + *p = (cast_type) v; \ + unit_write_settingf(u, flags, name, \ + "%s=%s", name, s); \ + } \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define BUS_DEFINE_SET_TRANSIENT_PARSE(function, type, parse) \ + int bus_set_transient_##function( \ + Unit *u, \ + const char *name, \ + type *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + const char *s; \ + type v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, "s", &s); \ + if (r < 0) \ + return r; \ + \ + v = parse(s); \ + if (v < 0) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Invalid %s setting: %s", name, s); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + *p = v; \ + unit_write_settingf(u, flags, name, \ + "%s=%s", name, s); \ + } \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(function, type, parse) \ + int bus_set_transient_##function( \ + Unit *u, \ + const char *name, \ + type *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + const char *s; \ + type v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, "s", &s); \ + if (r < 0) \ + return r; \ + \ + r = parse(s, &v); \ + if (r < 0) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Invalid %s setting: %s", name, s); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + *p = v; \ + unit_write_settingf(u, flags, name, \ + "%s=%s", name, strempty(s)); \ + } \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(function, check) \ + int bus_set_transient_##function( \ + Unit *u, \ + const char *name, \ + char **p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + const char *v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, "s", &v); \ + if (r < 0) \ + return r; \ + \ + if (!isempty(v) && !check(v)) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Invalid %s setting: %s", name, v); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + r = free_and_strdup(p, empty_to_null(v)); \ + if (r < 0) \ + return r; \ + \ + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, \ + "%s=%s", name, strempty(v)); \ + } \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val, str) \ + int bus_cgroup_set_##function( \ + Unit *u, \ + const char *name, \ + uint64_t *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + uint64_t v; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, "t", &v); \ + if (r < 0) \ + return r; \ + \ + if (!check(v)) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Value specified in %s is out of range", name); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + *p = v; \ + unit_invalidate_cgroup(u, (mask)); \ + \ + if (v == (val)) \ + unit_write_settingf(u, flags, name, \ + "%s=" str, name); \ + else \ + unit_write_settingf(u, flags, name, \ + "%s=%" PRIu64, name, v); \ + } \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define BUS_DEFINE_SET_CGROUP_SCALE(function, mask, scale) \ + int bus_cgroup_set_##function##_scale( \ + Unit *u, \ + const char *name, \ + uint64_t *p, \ + sd_bus_message *message, \ + UnitWriteFlags flags, \ + sd_bus_error *error) { \ + \ + uint64_t v; \ + uint32_t raw; \ + int r; \ + \ + assert(p); \ + \ + r = sd_bus_message_read(message, "u", &raw); \ + if (r < 0) \ + return r; \ + \ + v = scale(raw, UINT32_MAX); \ + if (v <= 0 || v >= UINT64_MAX) \ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \ + "Value specified in %s is out of range", name); \ + \ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \ + const char *e; \ + \ + *p = v; \ + unit_invalidate_cgroup(u, (mask)); \ + \ + /* Chop off suffix */ \ + assert_se(e = endswith(name, "Scale")); \ + name = strndupa(name, e - name); \ + \ + unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, \ + (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); \ + } \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +int bus_set_transient_mode_t(Unit *u, const char *name, mode_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +int bus_set_transient_unsigned(Unit *u, const char *name, unsigned *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +int bus_set_transient_user(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +int bus_set_transient_usec_internal(Unit *u, const char *name, usec_t *p, bool fix_0, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +static inline int bus_set_transient_usec(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) { + return bus_set_transient_usec_internal(u, name, p, false, message, flags, error); +} +static inline int bus_set_transient_usec_fix_0(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) { + return bus_set_transient_usec_internal(u, name, p, true, message, flags, error); +} diff --git a/src/core/dbus.c b/src/core/dbus.c index b7d8af9396..1c3fca353a 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -37,9 +37,11 @@ #include "dbus-unit.h" #include "dbus.h" #include "fd-util.h" +#include "fs-util.h" #include "log.h" #include "missing.h" #include "mkdir.h" +#include "process-util.h" #include "selinux-access.h" #include "special.h" #include "string-util.h" @@ -603,18 +605,16 @@ static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) { assert(m); assert(bus); - r = sd_bus_add_match( + r = sd_bus_match_signal_async( bus, NULL, - "sender='org.freedesktop.DBus.Local'," - "type='signal'," - "path='/org/freedesktop/DBus/Local'," - "interface='org.freedesktop.DBus.Local'," - "member='Disconnected'", - signal_disconnected, m); - + "org.freedesktop.DBus.Local", + "/org/freedesktop/DBus/Local", + "org.freedesktop.DBus.Local", + "Disconnected", + signal_disconnected, NULL, m); if (r < 0) - return log_error_errno(r, "Failed to register match for Disconnected message: %m"); + return log_error_errno(r, "Failed to request match for Disconnected message: %m"); return 0; } @@ -683,6 +683,12 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void return 0; } + r = sd_bus_set_sender(bus, "org.freedesktop.systemd1"); + if (r < 0) { + log_warning_errno(r, "Failed to set direct connection sender: %m"); + return 0; + } + r = sd_bus_start(bus); if (r < 0) { log_warning_errno(r, "Failed to start new connection bus: %m"); @@ -813,26 +819,23 @@ static int bus_setup_api(Manager *m, sd_bus *bus) { log_error_errno(r, "Failed to subscribe to NameOwnerChanged signal for '%s': %m", name); } - r = sd_bus_add_match( + r = sd_bus_match_signal_async( bus, NULL, - "type='signal'," - "sender='org.freedesktop.DBus'," - "path='/org/freedesktop/DBus'," - "interface='org.freedesktop.systemd1.Activator'," - "member='ActivationRequest'", - signal_activation_request, m); + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.systemd1.Activator", + "ActivationRequest", + signal_activation_request, NULL, m); if (r < 0) log_warning_errno(r, "Failed to subscribe to activation signal: %m"); - /* Allow replacing of our name, to ease implementation of - * reexecution, where we keep the old connection open until - * after the new connection is set up and the name installed - * to allow clients to synchronously wait for reexecution to - * finish */ - r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT); + /* Allow replacing of our name, to ease implementation of reexecution, where we keep the old connection open + * until after the new connection is set up and the name installed to allow clients to synchronously wait for + * reexecution to finish */ + r = sd_bus_request_name_async(bus, NULL, "org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT, NULL, NULL); if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); + return log_error_errno(r, "Failed to request name: %m"); r = manager_sync_bus_names(m, bus); if (r < 0) @@ -857,28 +860,21 @@ static int bus_init_api(Manager *m) { r = sd_bus_open_system(&bus); else r = sd_bus_open_user(&bus); - - if (r < 0) { - log_debug("Failed to connect to API bus, retrying later..."); - return 0; - } + if (r < 0) + return log_error_errno(r, "Failed to connect to API bus: %m"); r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL); - if (r < 0) { - log_error_errno(r, "Failed to attach API bus to event loop: %m"); - return 0; - } + if (r < 0) + return log_error_errno(r, "Failed to attach API bus to event loop: %m"); r = bus_setup_disconnected_match(m, bus); if (r < 0) - return 0; + return r; } r = bus_setup_api(m, bus); - if (r < 0) { - log_error_errno(r, "Failed to set up API bus: %m"); - return 0; - } + if (r < 0) + return log_error_errno(r, "Failed to set up API bus: %m"); m->api_bus = bus; bus = NULL; @@ -894,16 +890,16 @@ static int bus_setup_system(Manager *m, sd_bus *bus) { /* if we are a user instance we get the Released message via the system bus */ if (MANAGER_IS_USER(m)) { - r = sd_bus_add_match( + r = sd_bus_match_signal_async( bus, NULL, - "type='signal'," - "interface='org.freedesktop.systemd1.Agent'," - "member='Released'," - "path='/org/freedesktop/systemd1/agent'", - signal_agent_released, m); + NULL, + "/org/freedesktop/systemd1/agent", + "org.freedesktop.systemd1.Agent", + "Released", + signal_agent_released, NULL, m); if (r < 0) - log_warning_errno(r, "Failed to register Released match on system bus: %m"); + log_warning_errno(r, "Failed to request Released match on system bus: %m"); } log_debug("Successfully connected to system bus."); @@ -924,26 +920,20 @@ static int bus_init_system(Manager *m) { } r = sd_bus_open_system(&bus); - if (r < 0) { - log_debug("Failed to connect to system bus, retrying later..."); - return 0; - } + if (r < 0) + return log_error_errno(r, "Failed to connect to system bus: %m"); r = bus_setup_disconnected_match(m, bus); if (r < 0) - return 0; + return r; r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL); - if (r < 0) { - log_error_errno(r, "Failed to attach system bus to event loop: %m"); - return 0; - } + if (r < 0) + return log_error_errno(r, "Failed to attach system bus to event loop: %m"); r = bus_setup_system(m, bus); - if (r < 0) { - log_error_errno(r, "Failed to set up system bus: %m"); - return 0; - } + if (r < 0) + return log_error_errno(r, "Failed to set up system bus: %m"); m->system_bus = bus; bus = NULL; @@ -1005,6 +995,9 @@ static int bus_init_private(Manager *m) { if (r < 0) return log_error_errno(errno, "Failed to make private socket listening: %m"); + /* Generate an inotify event in case somebody waits for this socket to appear using inotify() */ + (void) touch(sa.un.sun_path); + r = sd_event_add_io(m->event, &s, fd, EPOLLIN, bus_on_connection, m); if (r < 0) return log_error_errno(r, "Failed to allocate event source: %m"); @@ -1026,16 +1019,16 @@ int bus_init(Manager *m, bool try_bus_connect) { if (try_bus_connect) { r = bus_init_system(m); if (r < 0) - return r; + return log_error_errno(r, "Failed to initialize D-Bus connection: %m"); r = bus_init_api(m); if (r < 0) - return r; + return log_error_errno(r, "Error occured during D-Bus APIs initialization: %m"); } r = bus_init_private(m); if (r < 0) - return r; + return log_error_errno(r, "Failed to create private D-Bus server: %m"); return 0; } diff --git a/src/core/device.c b/src/core/device.c index dec6e74f95..a43664d3bd 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -796,14 +796,12 @@ static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, } if (streq(action, "change")) { - _cleanup_free_ char *e = NULL; Unit *u; + Device *d, *l, *n; - r = unit_name_from_path(sysfs, ".device", &e); - if (r < 0) - log_error_errno(r, "Failed to generate unit name from device path: %m"); - else { - u = manager_get_unit(m, e); + l = hashmap_get(m->devices_by_sysfs, sysfs); + LIST_FOREACH_SAFE(same_sysfs, d, n, l) { + u = &d->meta; if (u && UNIT_VTABLE(u)->active_state(u) == UNIT_ACTIVE) { r = manager_propagate_reload(m, u, JOB_REPLACE, NULL); if (r < 0) diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c index 308608e426..decfacd600 100644 --- a/src/core/emergency-action.c +++ b/src/core/emergency-action.c @@ -49,6 +49,11 @@ int emergency_action( if (action == EMERGENCY_ACTION_NONE) return -ECANCELED; + if (!m->service_watchdogs) { + log_warning("Watchdog disabled! Not acting on: %s", reason); + return -ECANCELED; + } + if (!MANAGER_IS_SYSTEM(m)) { /* Downgrade all options to simply exiting if we run * in user mode */ diff --git a/src/core/execute.c b/src/core/execute.c index f20246796f..0df3971df6 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1207,27 +1207,19 @@ static int setup_pam( parent_pid = getpid_cached(); - pam_pid = fork(); - if (pam_pid < 0) { - r = -errno; + r = safe_fork("(sd-pam)", 0, &pam_pid); + if (r < 0) goto fail; - } - - if (pam_pid == 0) { + if (r == 0) { int sig, ret = EXIT_PAM; /* The child's job is to reset the PAM session on * termination */ barrier_set_role(&barrier, BARRIER_CHILD); - /* This string must fit in 10 chars (i.e. the length - * of "/sbin/init"), to look pretty in /bin/ps */ - rename_process("(sd-pam)"); - - /* Make sure we don't keep open the passed fds in this - child. We assume that otherwise only those fds are - open here that have been opened by PAM. */ - close_many(fds, n_fds); + /* Make sure we don't keep open the passed fds in this child. We assume that otherwise only those fds + * are open here that have been opened by PAM. */ + (void) close_many(fds, n_fds); /* Drop privileges - we don't need any to pam_close_session * and this will make PR_SET_PDEATHSIG work in most cases. @@ -1784,7 +1776,7 @@ static int build_pass_environment(const ExecContext *c, char ***ret) { static bool exec_needs_mount_namespace( const ExecContext *context, const ExecParameters *params, - ExecRuntime *runtime) { + const ExecRuntime *runtime) { assert(context); assert(params); @@ -1797,12 +1789,7 @@ static bool exec_needs_mount_namespace( !strv_isempty(context->inaccessible_paths)) return true; - if (context->n_bind_mounts > 0 || - !strv_isempty(context->directories[EXEC_DIRECTORY_RUNTIME].paths) || - !strv_isempty(context->directories[EXEC_DIRECTORY_STATE].paths) || - !strv_isempty(context->directories[EXEC_DIRECTORY_CACHE].paths) || - !strv_isempty(context->directories[EXEC_DIRECTORY_LOGS].paths) || - !strv_isempty(context->directories[EXEC_DIRECTORY_CONFIGURATION].paths)) + if (context->n_bind_mounts > 0) return true; if (context->mount_flags != 0) @@ -1822,6 +1809,12 @@ static bool exec_needs_mount_namespace( if (context->mount_apivfs && (context->root_image || context->root_directory)) return true; + if (context->dynamic_user && + (!strv_isempty(context->directories[EXEC_DIRECTORY_STATE].paths) || + !strv_isempty(context->directories[EXEC_DIRECTORY_CACHE].paths) || + !strv_isempty(context->directories[EXEC_DIRECTORY_LOGS].paths))) + return true; + return false; } @@ -1831,7 +1824,6 @@ static int setup_private_users(uid_t uid, gid_t gid) { _cleanup_close_ int unshare_ready_fd = -1; _cleanup_(sigkill_waitp) pid_t pid = 0; uint64_t c = 1; - siginfo_t si; ssize_t n; int r; @@ -1879,11 +1871,10 @@ static int setup_private_users(uid_t uid, gid_t gid) { if (pipe2(errno_pipe, O_CLOEXEC) < 0) return -errno; - pid = fork(); - if (pid < 0) - return -errno; - - if (pid == 0) { + r = safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &pid); + if (r < 0) + return r; + if (r == 0) { _cleanup_close_ int fd = -1; const char *a; pid_t ppid; @@ -1972,13 +1963,11 @@ static int setup_private_users(uid_t uid, gid_t gid) { if (n != 0) /* on success we should have read 0 bytes */ return -EIO; - r = wait_for_terminate(pid, &si); + r = wait_for_terminate_and_check("(sd-userns)", pid, 0); + pid = 0; if (r < 0) return r; - pid = 0; - - /* If something strange happened with the child, let's consider this fatal, too */ - if (si.si_code != CLD_EXITED || si.si_status != 0) + if (r != EXIT_SUCCESS) /* If something strange happened with the child, let's consider this fatal, too */ return -EIO; return 0; @@ -3418,7 +3407,7 @@ static int exec_child( return log_oom(); } - if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) { + if (DEBUG_LOGGING) { _cleanup_free_ char *line; line = exec_command_line(final_argv); @@ -4162,19 +4151,19 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { if (c->pam_name) fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name); - if (strv_length(c->read_write_paths) > 0) { + if (!strv_isempty(c->read_write_paths)) { fprintf(f, "%sReadWritePaths:", prefix); strv_fprintf(f, c->read_write_paths); fputs("\n", f); } - if (strv_length(c->read_only_paths) > 0) { + if (!strv_isempty(c->read_only_paths)) { fprintf(f, "%sReadOnlyPaths:", prefix); strv_fprintf(f, c->read_only_paths); fputs("\n", f); } - if (strv_length(c->inaccessible_paths) > 0) { + if (!strv_isempty(c->inaccessible_paths)) { fprintf(f, "%sInaccessiblePaths:", prefix); strv_fprintf(f, c->inaccessible_paths); fputs("\n", f); diff --git a/src/core/ip-address-access.c b/src/core/ip-address-access.c index 8d72fc03bf..08bd4c0bce 100644 --- a/src/core/ip-address-access.c +++ b/src/core/ip-address-access.c @@ -210,13 +210,12 @@ IPAddressAccessItem* ip_address_access_reduce(IPAddressAccessItem *first) { &b->address, b->prefixlen, &a->address); - if (r <= 0) - continue; - - /* b covers a fully, then let's drop a */ - - LIST_REMOVE(items, first, a); - free(a); + if (r > 0) { + /* b covers a fully, then let's drop a */ + LIST_REMOVE(items, first, a); + free(a); + break; + } } } diff --git a/src/core/job.c b/src/core/job.c index 2ea7834dfd..c6de8d27e4 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -306,8 +306,7 @@ void job_dump(Job *j, FILE*f, const char *prefix) { assert(j); assert(f); - if (!prefix) - prefix = ""; + prefix = strempty(prefix); fprintf(f, "%s-> Job %u:\n" @@ -1244,7 +1243,7 @@ void job_shutdown_magic(Job *j) { if (detect_container() > 0) return; - asynchronous_sync(); + (void) asynchronous_sync(NULL); } int job_get_timeout(Job *j, usec_t *timeout) { diff --git a/src/core/kill.c b/src/core/kill.c index f438c4d8fa..5dfcb780fa 100644 --- a/src/core/kill.c +++ b/src/core/kill.c @@ -34,8 +34,7 @@ void kill_context_init(KillContext *c) { void kill_context_dump(KillContext *c, FILE *f, const char *prefix) { assert(c); - if (!prefix) - prefix = ""; + prefix = strempty(prefix); fprintf(f, "%sKillMode: %s\n" diff --git a/src/core/killall.c b/src/core/killall.c index e77763e161..daa9c4ea20 100644 --- a/src/core/killall.c +++ b/src/core/killall.c @@ -89,7 +89,7 @@ static bool ignore_proc(pid_t pid, bool warn_rootfs) { return true; } -static void wait_for_children(Set *pids, sigset_t *mask) { +static void wait_for_children(Set *pids, sigset_t *mask, usec_t timeout) { usec_t until; assert(mask); @@ -97,7 +97,7 @@ static void wait_for_children(Set *pids, sigset_t *mask) { if (set_isempty(pids)) return; - until = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC; + until = now(CLOCK_MONOTONIC) + timeout; for (;;) { struct timespec ts; int k; @@ -221,7 +221,7 @@ static int killall(int sig, Set *pids, bool send_sighup) { return set_size(pids); } -void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup) { +void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup, usec_t timeout) { sigset_t mask, oldmask; _cleanup_set_free_ Set *pids = NULL; @@ -241,7 +241,7 @@ void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup) { log_warning_errno(errno, "kill(-1, SIGCONT) failed: %m"); if (wait_for_exit) - wait_for_children(pids, &mask); + wait_for_children(pids, &mask, timeout); assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0); } diff --git a/src/core/killall.h b/src/core/killall.h index 01bd6e52b3..45e97ab594 100644 --- a/src/core/killall.h +++ b/src/core/killall.h @@ -20,4 +20,6 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup); +#include "time-util.h" + +void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup, usec_t timeout); diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 240f331778..dde5010e02 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -214,6 +214,7 @@ Unit.RefuseManualStop, config_parse_bool, 0, Unit.AllowIsolate, config_parse_bool, 0, offsetof(Unit, allow_isolate) Unit.DefaultDependencies, config_parse_bool, 0, offsetof(Unit, default_dependencies) Unit.OnFailureJobMode, config_parse_job_mode, 0, offsetof(Unit, on_failure_job_mode) +m4_dnl The following is a legacy alias name for compatibility Unit.OnFailureIsolate, config_parse_job_mode_isolate, 0, offsetof(Unit, on_failure_job_mode) Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate) Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LEGACY, 0 @@ -241,6 +242,7 @@ Unit.ConditionFileIsExecutable, config_parse_unit_condition_path, CONDITION_F Unit.ConditionNeedsUpdate, config_parse_unit_condition_path, CONDITION_NEEDS_UPDATE, offsetof(Unit, conditions) Unit.ConditionFirstBoot, config_parse_unit_condition_string, CONDITION_FIRST_BOOT, offsetof(Unit, conditions) Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, conditions) +Unit.ConditionKernelVersion, config_parse_unit_condition_string, CONDITION_KERNEL_VERSION, offsetof(Unit, conditions) Unit.ConditionArchitecture, config_parse_unit_condition_string, CONDITION_ARCHITECTURE, offsetof(Unit, conditions) Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, offsetof(Unit, conditions) Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, offsetof(Unit, conditions) @@ -249,6 +251,7 @@ Unit.ConditionHost, config_parse_unit_condition_string, CONDITION_H Unit.ConditionACPower, config_parse_unit_condition_string, CONDITION_AC_POWER, offsetof(Unit, conditions) Unit.ConditionUser, config_parse_unit_condition_string, CONDITION_USER, offsetof(Unit, conditions) Unit.ConditionGroup, config_parse_unit_condition_string, CONDITION_GROUP, offsetof(Unit, conditions) +Unit.ConditionControlGroupController, config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER, offsetof(Unit, conditions) Unit.ConditionNull, config_parse_unit_condition_null, 0, offsetof(Unit, conditions) Unit.AssertPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, offsetof(Unit, asserts) Unit.AssertPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, offsetof(Unit, asserts) @@ -262,6 +265,7 @@ Unit.AssertFileIsExecutable, config_parse_unit_condition_path, CONDITION_F Unit.AssertNeedsUpdate, config_parse_unit_condition_path, CONDITION_NEEDS_UPDATE, offsetof(Unit, asserts) Unit.AssertFirstBoot, config_parse_unit_condition_string, CONDITION_FIRST_BOOT, offsetof(Unit, asserts) Unit.AssertKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, asserts) +Unit.AssertKernelVersion, config_parse_unit_condition_string, CONDITION_KERNEL_VERSION, offsetof(Unit, asserts) Unit.AssertArchitecture, config_parse_unit_condition_string, CONDITION_ARCHITECTURE, offsetof(Unit, asserts) Unit.AssertVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, offsetof(Unit, asserts) Unit.AssertSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, offsetof(Unit, asserts) @@ -270,6 +274,7 @@ Unit.AssertHost, config_parse_unit_condition_string, CONDITION_H Unit.AssertACPower, config_parse_unit_condition_string, CONDITION_AC_POWER, offsetof(Unit, asserts) Unit.AssertUser, config_parse_unit_condition_string, CONDITION_USER, offsetof(Unit, asserts) Unit.AssertGroup, config_parse_unit_condition_string, CONDITION_GROUP, offsetof(Unit, asserts) +Unit.AssertControlGroupController, config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER, offsetof(Unit, asserts) Unit.AssertNull, config_parse_unit_condition_null, 0, offsetof(Unit, asserts) Unit.CollectMode, config_parse_collect_mode, 0, offsetof(Unit, collect_mode) m4_dnl diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index d6c616502b..00408c4b84 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -64,6 +64,7 @@ #include "securebits.h" #include "securebits-util.h" #include "signal-util.h" +#include "socket-protocol-list.h" #include "stat-util.h" #include "string-util.h" #include "strv.h" @@ -433,11 +434,9 @@ int config_parse_socket_listen(const char *unit, p->n_auxiliary_fds = 0; p->socket = s; - if (s->ports) { - LIST_FIND_TAIL(port, s->ports, tail); - LIST_INSERT_AFTER(port, s->ports, tail, p); - } else - LIST_PREPEND(port, s->ports, p); + LIST_FIND_TAIL(port, s->ports, tail); + LIST_INSERT_AFTER(port, s->ports, tail, p); + p = NULL; return 0; @@ -454,6 +453,7 @@ int config_parse_socket_protocol(const char *unit, void *data, void *userdata) { Socket *s; + int r; assert(filename); assert(lvalue); @@ -462,15 +462,17 @@ int config_parse_socket_protocol(const char *unit, s = SOCKET(data); - if (streq(rvalue, "udplite")) - s->socket_protocol = IPPROTO_UDPLITE; - else if (streq(rvalue, "sctp")) - s->socket_protocol = IPPROTO_SCTP; - else { + r = socket_protocol_from_name(rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid socket protocol, ignoring: %s", rvalue); + return 0; + } else if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Socket protocol not supported, ignoring: %s", rvalue); return 0; } + s->socket_protocol = r; + return 0; } @@ -495,19 +497,13 @@ int config_parse_socket_bind(const char *unit, s = SOCKET(data); - b = socket_address_bind_ipv6_only_from_string(rvalue); + b = parse_socket_address_bind_ipv6_only_or_bool(rvalue); if (b < 0) { - int r; - - r = parse_boolean(rvalue); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse bind IPv6 only value, ignoring: %s", rvalue); - return 0; - } + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse bind IPv6 only value, ignoring: %s", rvalue); + return 0; + } - s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH; - } else - s->bind_ipv6_only = b; + s->bind_ipv6_only = b; return 0; } @@ -2891,60 +2887,6 @@ int config_parse_documentation(const char *unit, } #if HAVE_SECCOMP - -static int syscall_filter_parse_one( - const char *unit, - const char *filename, - unsigned line, - ExecContext *c, - bool invert, - const char *t, - bool warn, - int errno_num) { - int r; - - if (t[0] == '@') { - const SyscallFilterSet *set; - const char *i; - - set = syscall_filter_set_find(t); - if (!set) { - if (warn) - log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown system call group, ignoring: %s", t); - return 0; - } - - NULSTR_FOREACH(i, set->value) { - r = syscall_filter_parse_one(unit, filename, line, c, invert, i, false, errno_num); - if (r < 0) - return r; - } - } else { - int id; - - id = seccomp_syscall_resolve_name(t); - if (id == __NR_SCMP_ERROR) { - if (warn) - log_syntax(unit, LOG_WARNING, filename, line, 0, "Failed to parse system call, ignoring: %s", t); - return 0; - } - - /* If we previously wanted to forbid a syscall and now - * we want to allow it, then remove it from the list. - */ - if (!invert == c->syscall_whitelist) { - r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num)); - if (r == 0) - return 0; - if (r < 0) - return log_oom(); - } else - (void) hashmap_remove(c->syscall_filter, INT_TO_PTR(id + 1)); - } - - return 0; -} - int config_parse_syscall_filter( const char *unit, const char *filename, @@ -2993,7 +2935,7 @@ int config_parse_syscall_filter( c->syscall_whitelist = true; /* Accept default syscalls if we are on a whitelist */ - r = syscall_filter_parse_one(unit, filename, line, c, false, "@default", false, -1); + r = seccomp_parse_syscall_filter(false, "@default", -1, c->syscall_filter, true); if (r < 0) return r; } @@ -3020,7 +2962,7 @@ int config_parse_syscall_filter( continue; } - r = syscall_filter_parse_one(unit, filename, line, c, invert, name, true, num); + r = seccomp_parse_syscall_filter_and_warn(invert, name, num, c->syscall_filter, c->syscall_whitelist, unit, filename, line); if (r < 0) return r; } @@ -3575,7 +3517,8 @@ int config_parse_device_allow( if (!path) return log_oom(); - if (!is_deviceallow_pattern(path)) { + if (!is_deviceallow_pattern(path) && + !path_startswith(path, "/run/systemd/inaccessible/")) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path); return 0; } @@ -3675,7 +3618,8 @@ int config_parse_io_device_weight( if (!path) return log_oom(); - if (!path_startswith(path, "/dev")) { + if (!path_startswith(path, "/dev") && + !path_startswith(path, "/run/systemd/inaccessible/")) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path); return 0; } @@ -3748,7 +3692,8 @@ int config_parse_io_limit( if (!path) return log_oom(); - if (!path_startswith(path, "/dev")) { + if (!path_startswith(path, "/dev") && + !path_startswith(path, "/run/systemd/inaccessible/")) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path); return 0; } @@ -3862,7 +3807,8 @@ int config_parse_blockio_device_weight( if (!path) return log_oom(); - if (!path_startswith(path, "/dev")) { + if (!path_startswith(path, "/dev") && + !path_startswith(path, "/run/systemd/inaccessible/")) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path); return 0; } @@ -3936,7 +3882,8 @@ int config_parse_blockio_bandwidth( if (!path) return log_oom(); - if (!path_startswith(path, "/dev")) { + if (!path_startswith(path, "/dev") && + !path_startswith(path, "/run/systemd/inaccessible/")) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path); return 0; } @@ -4002,6 +3949,8 @@ int config_parse_job_mode_isolate( return 0; } + log_notice("%s is deprecated. Please use OnFailureJobMode= instead", lvalue); + *m = r ? JOB_ISOLATE : JOB_REPLACE; return 0; } @@ -4412,7 +4361,7 @@ int config_parse_protect_home( void *userdata) { ExecContext *c = data; - int k; + ProtectHome h; assert(filename); assert(lvalue); @@ -4422,23 +4371,14 @@ int config_parse_protect_home( /* Our enum shall be a superset of booleans, hence first try * to parse as boolean, and then as enum */ - k = parse_boolean(rvalue); - if (k > 0) - c->protect_home = PROTECT_HOME_YES; - else if (k == 0) - c->protect_home = PROTECT_HOME_NO; - else { - ProtectHome h; - - h = protect_home_from_string(rvalue); - if (h < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect home value, ignoring: %s", rvalue); - return 0; - } - - c->protect_home = h; + h = parse_protect_home_or_bool(rvalue); + if (h < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect home value, ignoring: %s", rvalue); + return 0; } + c->protect_home = h; + return 0; } @@ -4455,7 +4395,7 @@ int config_parse_protect_system( void *userdata) { ExecContext *c = data; - int k; + ProtectSystem s; assert(filename); assert(lvalue); @@ -4465,23 +4405,14 @@ int config_parse_protect_system( /* Our enum shall be a superset of booleans, hence first try * to parse as boolean, and then as enum */ - k = parse_boolean(rvalue); - if (k > 0) - c->protect_system = PROTECT_SYSTEM_YES; - else if (k == 0) - c->protect_system = PROTECT_SYSTEM_NO; - else { - ProtectSystem s; - - s = protect_system_from_string(rvalue); - if (s < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect system value, ignoring: %s", rvalue); - return 0; - } - - c->protect_system = s; + s = parse_protect_system_or_bool(rvalue); + if (s < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect system value, ignoring: %s", rvalue); + return 0; } + c->protect_system = s; + return 0; } diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index 6240a83197..0c43cf2418 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -20,6 +20,7 @@ #include <errno.h> #include <stdlib.h> +#include <string.h> #include "env-util.h" #include "fileio.h" diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c index 9a75525894..1528034e81 100644 --- a/src/core/loopback-setup.c +++ b/src/core/loopback-setup.c @@ -32,21 +32,27 @@ struct state { unsigned n_messages; int rcode; - const char *title; + const char *error_message; + const char *success_message; }; static int generic_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { struct state *s = userdata; + int r; assert(s); assert(s->n_messages > 0); s->n_messages--; errno = 0; - log_debug_errno(sd_netlink_message_get_errno(m), "Failed to %s: %m", s->title); - s->rcode = sd_netlink_message_get_errno(m); + r = sd_netlink_message_get_errno(m); + if (r < 0) + log_debug_errno(r, "%s: %m", s->error_message); + else + log_debug("%s", s->success_message); + s->rcode = r; return 0; } @@ -165,9 +171,16 @@ static bool check_loopback(sd_netlink *rtnl) { int loopback_setup(void) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; - struct state state_4 = { .title = "add address 127.0.0.1 to loopback interface" }, - state_6 = { .title = "add address ::1 to loopback interface"}, - state_up = { .title = "bring loopback interface up" }; + struct state state_4 = { + .error_message = "Failed to add address 127.0.0.1 to loopback interface", + .success_message = "Successfully added address 127.0.0.1 to loopback interface", + }, state_6 = { + .error_message = "Failed to add address ::1 to loopback interface", + .success_message = "Successfully added address ::1 to loopback interface", + }, state_up = { + .error_message = "Failed to bring loopback interface up", + .success_message = "Successfully brought loopback interface up", + }; int r; r = sd_netlink_open(&rtnl); diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c index 767e97206c..1b7424800c 100644 --- a/src/core/machine-id-setup.c +++ b/src/core/machine-id-setup.c @@ -119,16 +119,15 @@ int machine_id_setup(const char *root, sd_id128_t machine_id, sd_id128_t *ret) { fd = open(etc_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) { if (old_errno == EROFS && errno == ENOENT) - log_error_errno(errno, + return log_error_errno(errno, "System cannot boot: Missing /etc/machine-id and /etc is mounted read-only.\n" "Booting up is supported only when:\n" "1) /etc/machine-id exists and is populated.\n" "2) /etc/machine-id exists and is empty.\n" "3) /etc/machine-id is missing and /etc is writable.\n"); else - log_error_errno(errno, "Cannot open %s: %m", etc_machine_id); - - return -errno; + return log_error_errno(errno, + "Cannot open %s: %m", etc_machine_id); } writable = false; diff --git a/src/core/main.c b/src/core/main.c index 2ad5073368..56200a8fad 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -91,6 +91,7 @@ #include "terminal-util.h" #include "umask-util.h" #include "user-util.h" +#include "util.h" #include "virt.h" #include "watchdog.h" @@ -111,6 +112,7 @@ static char *arg_confirm_spawn = NULL; static ShowStatus arg_show_status = _SHOW_STATUS_UNSET; static bool arg_switched_root = false; static bool arg_no_pager = false; +static bool arg_service_watchdogs = true; static char ***arg_join_controllers = NULL; static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL; static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; @@ -395,6 +397,14 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat arg_confirm_spawn = s; } + } else if (proc_cmdline_key_streq(key, "systemd.service_watchdogs")) { + + r = value ? parse_boolean(value) : true; + if (r < 0) + log_warning("Failed to parse service watchdog switch %s. Ignoring.", value); + else + arg_service_watchdogs = r; + } else if (proc_cmdline_key_streq(key, "systemd.show_status")) { if (value) { @@ -854,6 +864,7 @@ static void set_manager_settings(Manager *m) { assert(m); m->confirm_spawn = arg_confirm_spawn; + m->service_watchdogs = arg_service_watchdogs; m->runtime_watchdog = arg_runtime_watchdog; m->shutdown_watchdog = arg_shutdown_watchdog; m->cad_burst_action = arg_cad_burst_action; @@ -885,7 +896,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_SWITCHED_ROOT, ARG_DEFAULT_STD_OUTPUT, ARG_DEFAULT_STD_ERROR, - ARG_MACHINE_ID + ARG_MACHINE_ID, + ARG_SERVICE_WATCHDOGS, }; static const struct option options[] = { @@ -912,6 +924,7 @@ static int parse_argv(int argc, char *argv[]) { { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, }, { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, }, { "machine-id", required_argument, NULL, ARG_MACHINE_ID }, + { "service-watchdogs", required_argument, NULL, ARG_SERVICE_WATCHDOGS }, {} }; @@ -1066,6 +1079,13 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(r, "Failed to parse confirm spawn option: %m"); break; + case ARG_SERVICE_WATCHDOGS: + r = parse_boolean(optarg); + if (r < 0) + return log_error_errno(r, "Failed to parse service watchdogs boolean: %s", optarg); + arg_service_watchdogs = r; + break; + case ARG_SHOW_STATUS: if (optarg) { r = parse_show_status(optarg, &arg_show_status); @@ -1336,20 +1356,23 @@ static int enforce_syscall_archs(Set *archs) { static int status_welcome(void) { _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL; + const char *fn; int r; - r = parse_env_file("/etc/os-release", NEWLINE, - "PRETTY_NAME", &pretty_name, - "ANSI_COLOR", &ansi_color, - NULL); - if (r == -ENOENT) - r = parse_env_file("/usr/lib/os-release", NEWLINE, + if (arg_show_status <= 0) + return 0; + + FOREACH_STRING(fn, "/etc/os-release", "/usr/lib/os-release") { + r = parse_env_file(fn, NEWLINE, "PRETTY_NAME", &pretty_name, "ANSI_COLOR", &ansi_color, NULL); + if (r != -ENOENT) + break; + } if (r < 0 && r != -ENOENT) - log_warning_errno(r, "Failed to read os-release file: %m"); + log_warning_errno(r, "Failed to read os-release file, ignoring: %m"); if (log_get_show_color()) return status_printf(NULL, false, false, @@ -1413,32 +1436,29 @@ static int bump_unix_max_dgram_qlen(void) { static int fixup_environment(void) { _cleanup_free_ char *term = NULL; + const char *t; int r; - /* We expect the environment to be set correctly - * if run inside a container. */ + /* Only fix up the environment when we are started as PID 1 */ + if (getpid_cached() != 1) + return 0; + + /* We expect the environment to be set correctly if run inside a container. */ if (detect_container() > 0) return 0; - /* When started as PID1, the kernel uses /dev/console - * for our stdios and uses TERM=linux whatever the - * backend device used by the console. We try to make - * a better guess here since some consoles might not - * have support for color mode for example. + /* When started as PID1, the kernel uses /dev/console for our stdios and uses TERM=linux whatever the backend + * device used by the console. We try to make a better guess here since some consoles might not have support + * for color mode for example. * - * However if TERM was configured through the kernel - * command line then leave it alone. */ - + * However if TERM was configured through the kernel command line then leave it alone. */ r = proc_cmdline_get_key("TERM", 0, &term); if (r < 0) return r; - if (r == 0) { - term = strdup(default_term_for_tty("/dev/console")); - if (!term) - return -ENOMEM; - } - if (setenv("TERM", term, 1) < 0) + t = term ?: default_term_for_tty("/dev/console"); + + if (setenv("TERM", t, 1) < 0) return -errno; return 0; @@ -1457,7 +1477,7 @@ static void redirect_telinit(int argc, char *argv[]) { execv(SYSTEMCTL_BINARY_PATH, argv); log_error_errno(errno, "Failed to exec " SYSTEMCTL_BINARY_PATH ": %m"); - exit(1); + exit(EXIT_FAILURE); #endif } @@ -1466,17 +1486,19 @@ static int become_shutdown( int retval) { char log_level[DECIMAL_STR_MAX(int) + 1], - exit_code[DECIMAL_STR_MAX(uint8_t) + 1]; + exit_code[DECIMAL_STR_MAX(uint8_t) + 1], + timeout[DECIMAL_STR_MAX(usec_t) + 1]; - const char* command_line[11] = { + const char* command_line[13] = { SYSTEMD_SHUTDOWN_BINARY_PATH, shutdown_verb, + "--timeout", timeout, "--log-level", log_level, "--log-target", }; _cleanup_strv_free_ char **env_block = NULL; - size_t pos = 5; + size_t pos = 7; int r; assert(shutdown_verb); @@ -1484,6 +1506,7 @@ static int become_shutdown( env_block = strv_copy(environ); xsprintf(log_level, "%d", log_get_max_level()); + xsprintf(timeout, "%" PRI_USEC "us", arg_default_timeout_stop_usec); switch (log_get_target()) { @@ -1603,7 +1626,7 @@ static void initialize_coredump(bool skip_setup) { /* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored * until the systemd-coredump tool is enabled via sysctl. */ if (!skip_setup) - (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0); + disable_coredumps(); } static void do_reexecute( @@ -1639,7 +1662,7 @@ static void do_reexecute( if (switch_root_dir) { /* Kill all remaining processes from the initrd, but don't wait for them, so that we can handle the * SIGCHLD for them after deserializing. */ - broadcast_signal(SIGTERM, false, true); + broadcast_signal(SIGTERM, false, true, arg_default_timeout_stop_usec); /* And switch root with MS_MOVE, because we remove the old directory afterwards and detach it. */ r = switch_root(switch_root_dir, "/mnt", true, MS_MOVE); @@ -1889,11 +1912,13 @@ static void log_execution_mode(bool *ret_first_boot) { log_info("Running with unpopulated /etc."); } } else { - _cleanup_free_ char *t; + if (DEBUG_LOGGING) { + _cleanup_free_ char *t; - t = uid_to_name(getuid()); - log_debug(PACKAGE_STRING " running in %suser mode for user " UID_FMT "/%s. (" SYSTEMD_FEATURES ")", - arg_action == ACTION_TEST ? " test" : "", getuid(), strna(t)); + t = uid_to_name(getuid()); + log_debug(PACKAGE_STRING " running in %suser mode for user " UID_FMT "/%s. (" SYSTEMD_FEATURES ")", + arg_action == ACTION_TEST ? " test" : "", getuid(), strna(t)); + } *ret_first_boot = false; } @@ -1916,31 +1941,42 @@ static int initialize_runtime( * - Some only apply when we first start up, but not when we reexecute */ - if (arg_system && !skip_setup) { - if (arg_show_status > 0) + if (arg_action != ACTION_RUN) + return 0; + + if (arg_system) { + /* Make sure we leave a core dump without panicing the kernel. */ + install_crash_handler(); + + if (!skip_setup) { + r = mount_cgroup_controllers(arg_join_controllers); + if (r < 0) { + *ret_error_message = "Failed to mount cgroup hierarchies"; + return r; + } + status_welcome(); + hostname_setup(); + machine_id_setup(NULL, arg_machine_id, NULL); + loopback_setup(); + bump_unix_max_dgram_qlen(); + test_usr(); + write_container_id(); + } - hostname_setup(); - machine_id_setup(NULL, arg_machine_id, NULL); - loopback_setup(); - bump_unix_max_dgram_qlen(); - test_usr(); - write_container_id(); - } + if (arg_watchdog_device) { + r = watchdog_set_device(arg_watchdog_device); + if (r < 0) + log_warning_errno(r, "Failed to set watchdog device to %s, ignoring: %m", arg_watchdog_device); + } - if (arg_system && arg_watchdog_device) { - r = watchdog_set_device(arg_watchdog_device); - if (r < 0) - log_warning_errno(r, "Failed to set watchdog device to %s, ignoring: %m", - arg_watchdog_device); + if (arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY) + watchdog_set_timeout(&arg_runtime_watchdog); } - if (arg_system && arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY) - watchdog_set_timeout(&arg_runtime_watchdog); - if (arg_timer_slack_nsec != NSEC_INFINITY) if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0) - log_error_errno(errno, "Failed to adjust timer slack: %m"); + log_warning_errno(errno, "Failed to adjust timer slack, ignoring: %m"); if (arg_system && !cap_test_all(arg_capability_bounding_set)) { r = capability_bounding_set_drop_usermode(arg_capability_bounding_set); @@ -2053,60 +2089,256 @@ static void free_arguments(void) { arg_syscall_archs = set_free(arg_syscall_archs); } +static int load_configuration(int argc, char **argv, const char **ret_error_message) { + int r; + + assert(ret_error_message); + + r = initialize_join_controllers(); + if (r < 0) { + *ret_error_message = "Failed to initialize cgroup controller joining table"; + return r; + } + + arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U); + + r = parse_config_file(); + if (r < 0) { + *ret_error_message = "Failed to parse config file"; + return r; + } + + if (arg_system) { + r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0); + if (r < 0) + log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); + } + + /* Note that this also parses bits from the kernel command line, including "debug". */ + log_parse_environment(); + + r = parse_argv(argc, argv); + if (r < 0) { + *ret_error_message = "Failed to parse commandline arguments"; + return r; + } + + /* Initialize default unit */ + if (!arg_default_unit) { + arg_default_unit = strdup(SPECIAL_DEFAULT_TARGET); + if (!arg_default_unit) { + *ret_error_message = "Failed to set default unit"; + return log_oom(); + } + } + + /* Initialize the show status setting if it hasn't been set explicitly yet */ + if (arg_show_status == _SHOW_STATUS_UNSET) + arg_show_status = SHOW_STATUS_YES; + + return 0; +} + +static int safety_checks(void) { + + if (getpid_cached() == 1 && + arg_action != ACTION_RUN) { + log_error("Unsupported execution mode while PID 1."); + return -EPERM; + } + + if (getpid_cached() == 1 && + !arg_system) { + log_error("Can't run --user mode as PID 1."); + return -EPERM; + } + + if (arg_action == ACTION_RUN && + arg_system && + getpid_cached() != 1) { + log_error("Can't run system mode unless PID 1."); + return -EPERM; + } + + if (arg_action == ACTION_TEST && + geteuid() == 0) { + log_error("Don't run test mode as root."); + return -EPERM; + } + + if (!arg_system && + arg_action == ACTION_RUN && + sd_booted() <= 0) { + log_error("Trying to run as user instance, but the system has not been booted with systemd."); + return -EOPNOTSUPP; + } + + if (!arg_system && + arg_action == ACTION_RUN && + !getenv("XDG_RUNTIME_DIR")) { + log_error("Trying to run as user instance, but $XDG_RUNTIME_DIR is not set."); + return -EUNATCH; + } + + if (arg_system && + arg_action == ACTION_RUN && + running_in_chroot() > 0) { + log_error("Cannot be run in a chroot() environment."); + return -EOPNOTSUPP; + } + + return 0; +} + +static int initialize_security( + bool *loaded_policy, + dual_timestamp *security_start_timestamp, + dual_timestamp *security_finish_timestamp, + const char **ret_error_message) { + + int r; + + assert(loaded_policy); + assert(security_start_timestamp); + assert(security_finish_timestamp); + assert(ret_error_message); + + dual_timestamp_get(security_start_timestamp); + + r = mac_selinux_setup(loaded_policy); + if (r < 0) { + *ret_error_message = "Failed to load SELinux policy"; + return r; + } + + r = mac_smack_setup(loaded_policy); + if (r < 0) { + *ret_error_message = "Failed to load SMACK policy"; + return r; + } + + r = ima_setup(); + if (r < 0) { + *ret_error_message = "Failed to load IMA policy"; + return r; + } + + dual_timestamp_get(security_finish_timestamp); + return 0; +} + +static void test_summary(Manager *m) { + assert(m); + + printf("-> By units:\n"); + manager_dump_units(m, stdout, "\t"); + + printf("-> By jobs:\n"); + manager_dump_jobs(m, stdout, "\t"); +} + +static int collect_fds(FDSet **ret_fds, const char **ret_error_message) { + int r; + + assert(ret_fds); + assert(ret_error_message); + + r = fdset_new_fill(ret_fds); + if (r < 0) { + *ret_error_message = "Failed to allocate fd set"; + return log_emergency_errno(r, "Failed to allocate fd set: %m"); + } + + fdset_cloexec(*ret_fds, true); + + if (arg_serialization) + assert_se(fdset_remove(*ret_fds, fileno(arg_serialization)) >= 0); + + return 0; +} + +static void setup_console_terminal(bool skip_setup) { + + if (!arg_system) + return; + + /* Become a session leader if we aren't one yet. */ + (void) setsid(); + + /* If we are init, we connect stdin/stdout/stderr to /dev/null and make sure we don't have a controlling + * tty. */ + (void) release_terminal(); + + /* Reset the console, but only if this is really init and we are freshly booted */ + if (getpid_cached() == 1 && !skip_setup) + (void) console_setup(); +} + +static bool early_skip_setup_check(int argc, char *argv[]) { + bool found_deserialize = false; + int i; + + /* Determine if this is a reexecution or normal bootup. We do the full command line parsing much later, so + * let's just have a quick peek here. Note that if we have switched root, do all the special setup things + * anyway, even if in that case we also do deserialization. */ + + for (i = 1; i < argc; i++) { + + if (streq(argv[i], "--switched-root")) + return false; /* If we switched root, don't skip the setup. */ + else if (streq(argv[i], "--deserialize")) + found_deserialize = true; + } + + return found_deserialize; /* When we are deserializing, then we are reexecuting, hence avoid the extensive setup */ +} + int main(int argc, char *argv[]) { - Manager *m = NULL; - int r, retval = EXIT_FAILURE; + + dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL, userspace_timestamp = DUAL_TIMESTAMP_NULL, kernel_timestamp = DUAL_TIMESTAMP_NULL, + security_start_timestamp = DUAL_TIMESTAMP_NULL, security_finish_timestamp = DUAL_TIMESTAMP_NULL; + struct rlimit saved_rlimit_nofile = RLIMIT_MAKE_CONST(0), saved_rlimit_memlock = RLIMIT_MAKE_CONST((rlim_t) -1); + bool skip_setup, loaded_policy = false, queue_default_job = false, first_boot = false, reexecute = false; + char *switch_root_dir = NULL, *switch_root_init = NULL; usec_t before_startup, after_startup; + static char systemd[] = "systemd"; char timespan[FORMAT_TIMESPAN_MAX]; + const char *shutdown_verb = NULL, *error_message = NULL; + int r, retval = EXIT_FAILURE; + Manager *m = NULL; FDSet *fds = NULL; - bool reexecute = false; - const char *shutdown_verb = NULL; - dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL; - dual_timestamp userspace_timestamp = DUAL_TIMESTAMP_NULL; - dual_timestamp kernel_timestamp = DUAL_TIMESTAMP_NULL; - dual_timestamp security_start_timestamp = DUAL_TIMESTAMP_NULL; - dual_timestamp security_finish_timestamp = DUAL_TIMESTAMP_NULL; - static char systemd[] = "systemd"; - bool skip_setup = false; - bool loaded_policy = false; - bool queue_default_job = false; - bool first_boot = false; - char *switch_root_dir = NULL, *switch_root_init = NULL; - struct rlimit saved_rlimit_nofile = RLIMIT_MAKE_CONST(0), saved_rlimit_memlock = RLIMIT_MAKE_CONST((rlim_t) -1); - const char *error_message = NULL; + /* SysV compatibility: redirect init → telinit */ redirect_telinit(argc, argv); + /* Take timestamps early on */ dual_timestamp_from_monotonic(&kernel_timestamp, 0); dual_timestamp_get(&userspace_timestamp); - /* Determine if this is a reexecution or normal bootup. We do - * the full command line parsing much later, so let's just - * have a quick peek here. */ - if (strv_find(argv+1, "--deserialize")) - skip_setup = true; + /* Figure out whether we need to do initialize the system, or if we already did that because we are + * reexecuting */ + skip_setup = early_skip_setup_check(argc, argv); - /* If we have switched root, do all the special setup - * things */ - if (strv_find(argv+1, "--switched-root")) - skip_setup = false; - - /* If we get started via the /sbin/init symlink then we are - called 'init'. After a subsequent reexecution we are then - called 'systemd'. That is confusing, hence let's call us - systemd right-away. */ + /* If we get started via the /sbin/init symlink then we are called 'init'. After a subsequent reexecution we + * are then called 'systemd'. That is confusing, hence let's call us systemd right-away. */ program_invocation_short_name = systemd; (void) prctl(PR_SET_NAME, systemd); + /* Save the original command line */ saved_argv = argv; saved_argc = argc; + /* Make sure that if the user says "syslog" we actually log to the journal. */ log_set_upgrade_syslog_to_journal(true); if (getpid_cached() == 1) { /* Disable the umask logic */ umask(0); + /* Make sure that at least initially we do not ever log to journald/syslogd, because it might not be activated + * yet (even though the log socket for it exists). */ + log_set_prohibit_ipc(true); + /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is * important so that we never end up logging to any foreign stderr, for example if we have to log in a * child process right before execve()'ing the actual binary, at a point in time where socket @@ -2131,18 +2363,13 @@ int main(int argc, char *argv[]) { goto finish; } - dual_timestamp_get(&security_start_timestamp); - if (mac_selinux_setup(&loaded_policy) < 0) { - error_message = "Failed to load SELinux policy"; - goto finish; - } else if (mac_smack_setup(&loaded_policy) < 0) { - error_message = "Failed to load SMACK policy"; - goto finish; - } else if (ima_setup() < 0) { - error_message = "Failed to load IMA policy"; + r = initialize_security( + &loaded_policy, + &security_start_timestamp, + &security_finish_timestamp, + &error_message); + if (r < 0) goto finish; - } - dual_timestamp_get(&security_finish_timestamp); } if (mac_selinux_init() < 0) { @@ -2165,7 +2392,6 @@ int main(int argc, char *argv[]) { /* Running inside a container, as PID 1 */ arg_system = true; log_set_target(LOG_TARGET_CONSOLE); - log_close_console(); /* force reopen of /dev/console */ log_open(); /* For later on, see above... */ @@ -2187,11 +2413,14 @@ int main(int argc, char *argv[]) { initialize_coredump(skip_setup); + r = fixup_environment(); + if (r < 0) { + log_emergency_errno(r, "Failed to fix up PID 1 environment: %m"); + error_message = "Failed to fix up PID1 environment"; + goto finish; + } + if (arg_system) { - if (fixup_environment() < 0) { - error_message = "Failed to fix up PID1 environment"; - goto finish; - } /* Try to figure out if we can use colors with the console. No * need to do that for user instances since they never log @@ -2202,12 +2431,6 @@ int main(int argc, char *argv[]) { log_warning_errno(r, "Failed to redirect standard streams to /dev/null: %m"); } - r = initialize_join_controllers(); - if (r < 0) { - error_message = "Failed to initialize cgroup controllers"; - goto finish; - } - /* Mount /proc, /sys and friends, so that /proc/cmdline and * /proc/$PID/fd is available. */ if (getpid_cached() == 1) { @@ -2227,62 +2450,19 @@ int main(int argc, char *argv[]) { (void) reset_all_signal_handlers(); (void) ignore_signals(SIGNALS_IGNORE, -1); - arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U); - - if (parse_config_file() < 0) { - error_message = "Failed to parse config file"; - goto finish; - } - - if (arg_system) { - r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0); - if (r < 0) - log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); - } - - /* Note that this also parses bits from the kernel command - * line, including "debug". */ - log_parse_environment(); - - if (parse_argv(argc, argv) < 0) { - error_message = "Failed to parse commandline arguments"; - goto finish; - } - - /* Initialize default unit */ - if (!arg_default_unit) { - arg_default_unit = strdup(SPECIAL_DEFAULT_TARGET); - if (!arg_default_unit) { - r = log_oom(); - error_message = "Failed to set default unit"; - goto finish; - } - } - - if (arg_action == ACTION_TEST && - geteuid() == 0) { - log_error("Don't run test mode as root."); - goto finish; - } - - if (!arg_system && - arg_action == ACTION_RUN && - sd_booted() <= 0) { - log_error("Trying to run as user instance, but the system has not been booted with systemd."); + r = load_configuration(argc, argv, &error_message); + if (r < 0) goto finish; - } - if (arg_system && - arg_action == ACTION_RUN && - running_in_chroot() > 0) { - log_error("Cannot be run in a chroot() environment."); + r = safety_checks(); + if (r < 0) goto finish; - } - if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP)) { + if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP, ACTION_DUMP_CONFIGURATION_ITEMS)) pager_open(arg_no_pager, false); + + if (arg_action != ACTION_RUN) skip_setup = true; - } if (arg_action == ACTION_HELP) { retval = help(); @@ -2291,83 +2471,41 @@ int main(int argc, char *argv[]) { retval = version(); goto finish; } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) { - pager_open(arg_no_pager, false); unit_dump_config_items(stdout); retval = EXIT_SUCCESS; goto finish; } - if (!arg_system && - !getenv("XDG_RUNTIME_DIR")) { - log_error("Trying to run as user instance, but $XDG_RUNTIME_DIR is not set."); - goto finish; - } - assert_se(IN_SET(arg_action, ACTION_RUN, ACTION_TEST)); - /* Close logging fds, in order not to confuse fdset below */ - log_close(); - - /* Remember open file descriptors for later deserialization */ - if (arg_action == ACTION_RUN) { - r = fdset_new_fill(&fds); - if (r < 0) { - log_emergency_errno(r, "Failed to allocate fd set: %m"); - error_message = "Failed to allocate fd set"; - goto finish; - } else - fdset_cloexec(fds, true); - - if (arg_serialization) - assert_se(fdset_remove(fds, fileno(arg_serialization)) >= 0); - - if (arg_system) - /* Become a session leader if we aren't one yet. */ - setsid(); - } - /* Move out of the way, so that we won't block unmounts */ assert_se(chdir("/") == 0); - /* Reset the console, but only if this is really init and we - * are freshly booted */ - if (arg_system && arg_action == ACTION_RUN) { - - /* If we are init, we connect stdin/stdout/stderr to - * /dev/null and make sure we don't have a controlling - * tty. */ - release_terminal(); - - if (getpid_cached() == 1 && !skip_setup) - console_setup(); - } - - /* Open the logging devices, if possible and necessary */ - log_open(); - - if (arg_show_status == _SHOW_STATUS_UNSET) - arg_show_status = SHOW_STATUS_YES; + if (arg_action == ACTION_RUN) { - /* Make sure we leave a core dump without panicing the - * kernel. */ - if (getpid_cached() == 1) { - install_crash_handler(); + /* Close logging fds, in order not to confuse collecting passed fds and terminal logic below */ + log_close(); - r = mount_cgroup_controllers(arg_join_controllers); + /* Remember open file descriptors for later deserialization */ + r = collect_fds(&fds, &error_message); if (r < 0) goto finish; + + /* Give up any control of the console, but make sure its initialized. */ + setup_console_terminal(skip_setup); + + /* Open the logging devices, if possible and necessary */ + log_open(); } log_execution_mode(&first_boot); - if (arg_action == ACTION_RUN) { - r = initialize_runtime(skip_setup, - &saved_rlimit_nofile, - &saved_rlimit_memlock, - &error_message); - if (r < 0) - goto finish; - } + r = initialize_runtime(skip_setup, + &saved_rlimit_nofile, + &saved_rlimit_memlock, + &error_message); + if (r < 0) + goto finish; r = manager_new(arg_system ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, arg_action == ACTION_TEST ? MANAGER_TEST_FULL : 0, @@ -2416,36 +2554,20 @@ int main(int argc, char *argv[]) { "Loaded units and determined initial transaction in %s.", format_timespan(timespan, sizeof(timespan), after_startup - before_startup, 100 * USEC_PER_MSEC)); - if (arg_system) { - _cleanup_free_ char *taint; - - taint = manager_taint_string(m); - if (!isempty(taint)) - log_struct(LOG_NOTICE, - LOG_MESSAGE("System is tainted: %s", taint), - "TAINT=%s", taint, - "MESSAGE_ID=" SD_MESSAGE_TAINTED_STR, - NULL); - } - if (arg_action == ACTION_TEST) { - printf("-> By units:\n"); - manager_dump_units(m, stdout, "\t"); - - printf("-> By jobs:\n"); - manager_dump_jobs(m, stdout, "\t"); + test_summary(m); retval = EXIT_SUCCESS; goto finish; } - r = invoke_main_loop(m, - &reexecute, - &retval, - &shutdown_verb, - &fds, - &switch_root_dir, - &switch_root_init, - &error_message); + (void) invoke_main_loop(m, + &reexecute, + &retval, + &shutdown_verb, + &fds, + &switch_root_dir, + &switch_root_init, + &error_message); finish: pager_close(); diff --git a/src/core/manager.c b/src/core/manager.c index 81c4d5289b..e837a46f56 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -83,6 +83,7 @@ #include "string-table.h" #include "string-util.h" #include "strv.h" +#include "strxcpyx.h" #include "terminal-util.h" #include "time-util.h" #include "transaction.h" @@ -109,6 +110,7 @@ static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32 static int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata); static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata); static int manager_dispatch_run_queue(sd_event_source *source, void *userdata); +static int manager_dispatch_sigchld(sd_event_source *source, void *userdata); static int manager_run_environment_generators(Manager *m); static int manager_run_generators(Manager *m); @@ -263,7 +265,7 @@ static int manager_dispatch_ask_password_fd(sd_event_source *source, assert(m); - flush_fd(fd); + (void) flush_fd(fd); m->have_ask_password = have_ask_password(); if (m->have_ask_password < 0) @@ -513,23 +515,31 @@ static int manager_setup_signals(Manager *m) { return 0; } -static void manager_clean_environment(Manager *m) { +static void manager_sanitize_environment(Manager *m) { assert(m); - /* Let's remove some environment variables that we - * need ourselves to communicate with our clients */ + /* Let's remove some environment variables that we need ourselves to communicate with our clients */ strv_env_unset_many( m->environment, - "NOTIFY_SOCKET", + "EXIT_CODE", + "EXIT_STATUS", + "INVOCATION_ID", + "JOURNAL_STREAM", + "LISTEN_FDNAMES", + "LISTEN_FDS", + "LISTEN_PID", "MAINPID", "MANAGERPID", - "LISTEN_PID", - "LISTEN_FDS", - "LISTEN_FDNAMES", + "NOTIFY_SOCKET", + "REMOTE_ADDR", + "REMOTE_PORT", + "SERVICE_RESULT", "WATCHDOG_PID", "WATCHDOG_USEC", - "INVOCATION_ID", NULL); + + /* Let's order the environment alphabetically, just to make it pretty */ + strv_sort(m->environment); } static int manager_default_environment(Manager *m) { @@ -556,8 +566,7 @@ static int manager_default_environment(Manager *m) { if (!m->environment) return -ENOMEM; - manager_clean_environment(m); - strv_sort(m->environment); + manager_sanitize_environment(m); return 0; } @@ -627,6 +636,29 @@ static int manager_setup_run_queue(Manager *m) { return 0; } +static int manager_setup_sigchld_event_source(Manager *m) { + int r; + + assert(m); + assert(!m->sigchld_event_source); + + r = sd_event_add_defer(m->event, &m->sigchld_event_source, manager_dispatch_sigchld, m); + if (r < 0) + return r; + + r = sd_event_source_set_priority(m->sigchld_event_source, SD_EVENT_PRIORITY_NORMAL-7); + if (r < 0) + return r; + + r = sd_event_source_set_enabled(m->sigchld_event_source, SD_EVENT_OFF); + if (r < 0) + return r; + + (void) sd_event_source_set_description(m->sigchld_event_source, "manager-sigchld"); + + return 0; +} + int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) { Manager *m; int r; @@ -727,6 +759,10 @@ int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) { if (r < 0) goto fail; + r = manager_setup_sigchld_event_source(m); + if (r < 0) + goto fail; + m->udev = udev_new(); if (!m->udev) { r = -ENOMEM; @@ -810,7 +846,7 @@ static int manager_setup_notify(Manager *m) { /* Process notification messages a bit earlier than SIGCHLD, so that we can still identify to which * service an exit message belongs. */ - r = sd_event_source_set_priority(m->notify_event_source, SD_EVENT_PRIORITY_NORMAL-7); + r = sd_event_source_set_priority(m->notify_event_source, SD_EVENT_PRIORITY_NORMAL-8); if (r < 0) return log_error_errno(r, "Failed to set priority of notify event source: %m"); @@ -939,7 +975,7 @@ static int manager_setup_user_lookup_fd(Manager *m) { /* Process even earlier than the notify event source, so that we always know first about valid UID/GID * resolutions */ - r = sd_event_source_set_priority(m->user_lookup_event_source, SD_EVENT_PRIORITY_NORMAL-8); + r = sd_event_source_set_priority(m->user_lookup_event_source, SD_EVENT_PRIORITY_NORMAL-11); if (r < 0) return log_error_errno(errno, "Failed to set priority ot user lookup event source: %m"); @@ -1170,14 +1206,14 @@ Manager* manager_free(Manager *m) { hashmap_free(m->units); hashmap_free(m->units_by_invocation_id); hashmap_free(m->jobs); - hashmap_free(m->watch_pids1); - hashmap_free(m->watch_pids2); + hashmap_free(m->watch_pids); hashmap_free(m->watch_bus); set_free(m->startup_units); set_free(m->failed_units); sd_event_source_unref(m->signal_event_source); + sd_event_source_unref(m->sigchld_event_source); sd_event_source_unref(m->notify_event_source); sd_event_source_unref(m->cgroups_agent_event_source); sd_event_source_unref(m->time_change_event_source); @@ -1872,27 +1908,40 @@ static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, ui return 0; } -static void manager_invoke_notify_message(Manager *m, Unit *u, pid_t pid, const char *buf, FDSet *fds) { - _cleanup_strv_free_ char **tags = NULL; +static void manager_invoke_notify_message( + Manager *m, + Unit *u, + const struct ucred *ucred, + const char *buf, + FDSet *fds) { assert(m); assert(u); + assert(ucred); assert(buf); - tags = strv_split(buf, "\n\r"); - if (!tags) { - log_oom(); + if (u->notifygen == m->notifygen) /* Already invoked on this same unit in this same iteration? */ return; - } + u->notifygen = m->notifygen; + + if (UNIT_VTABLE(u)->notify_message) { + _cleanup_strv_free_ char **tags = NULL; - if (UNIT_VTABLE(u)->notify_message) - UNIT_VTABLE(u)->notify_message(u, pid, tags, fds); - else if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) { + tags = strv_split(buf, NEWLINE); + if (!tags) { + log_oom(); + return; + } + + UNIT_VTABLE(u)->notify_message(u, ucred, tags, fds); + + } else if (DEBUG_LOGGING) { _cleanup_free_ char *x = NULL, *y = NULL; - x = cescape(buf); + x = ellipsize(buf, 20, 90); if (x) - y = ellipsize(x, 20, 90); + y = cescape(x); + log_unit_debug(u, "Got notification message \"%s\", ignoring.", strnull(y)); } } @@ -1920,9 +1969,11 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t struct cmsghdr *cmsg; struct ucred *ucred = NULL; - Unit *u1, *u2, *u3; + _cleanup_free_ Unit **array_copy = NULL; + Unit *u1, *u2, **array; int r, *fd_array = NULL; unsigned n_fds = 0; + bool found = false; ssize_t n; assert(m); @@ -1969,7 +2020,7 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t } } - if (!ucred || ucred->pid <= 0) { + if (!ucred || !pid_is_valid(ucred->pid)) { log_warning("Received notify message without valid credentials. Ignoring."); return 0; } @@ -1989,22 +2040,41 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t /* Make sure it's NUL-terminated. */ buf[n] = 0; - /* Notify every unit that might be interested, but try - * to avoid notifying the same one multiple times. */ + /* Increase the generation counter used for filtering out duplicate unit invocations. */ + m->notifygen++; + + /* Notify every unit that might be interested, which might be multiple. */ u1 = manager_get_unit_by_pid_cgroup(m, ucred->pid); - if (u1) - manager_invoke_notify_message(m, u1, ucred->pid, buf, fds); + u2 = hashmap_get(m->watch_pids, PID_TO_PTR(ucred->pid)); + array = hashmap_get(m->watch_pids, PID_TO_PTR(-ucred->pid)); + if (array) { + size_t k = 0; - u2 = hashmap_get(m->watch_pids1, PID_TO_PTR(ucred->pid)); - if (u2 && u2 != u1) - manager_invoke_notify_message(m, u2, ucred->pid, buf, fds); + while (array[k]) + k++; - u3 = hashmap_get(m->watch_pids2, PID_TO_PTR(ucred->pid)); - if (u3 && u3 != u2 && u3 != u1) - manager_invoke_notify_message(m, u3, ucred->pid, buf, fds); + array_copy = newdup(Unit*, array, k+1); + if (!array_copy) + log_oom(); + } + /* And now invoke the per-unit callbacks. Note that manager_invoke_notify_message() will handle duplicate units + * make sure we only invoke each unit's handler once. */ + if (u1) { + manager_invoke_notify_message(m, u1, ucred, buf, fds); + found = true; + } + if (u2) { + manager_invoke_notify_message(m, u2, ucred, buf, fds); + found = true; + } + if (array_copy) + for (size_t i = 0; array_copy[i]; i++) { + manager_invoke_notify_message(m, array_copy[i], ucred, buf, fds); + found = true; + } - if (!u1 && !u2 && !u3) - log_warning("Cannot find unit for notify message of PID "PID_FMT".", ucred->pid); + if (!found) + log_warning("Cannot find unit for notify message of PID "PID_FMT", ignoring.", ucred->pid); if (fdset_size(fds) > 0) log_warning("Got extra auxiliary fds with notification message, closing them."); @@ -2012,89 +2082,111 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t return 0; } -static void invoke_sigchld_event(Manager *m, Unit *u, const siginfo_t *si) { - uint64_t iteration; +static void manager_invoke_sigchld_event( + Manager *m, + Unit *u, + const siginfo_t *si) { assert(m); assert(u); assert(si); - sd_event_get_iteration(m->event, &iteration); - - log_unit_debug(u, "Child "PID_FMT" belongs to %s", si->si_pid, u->id); + /* Already invoked the handler of this unit in this iteration? Then don't process this again */ + if (u->sigchldgen == m->sigchldgen) + return; + u->sigchldgen = m->sigchldgen; + log_unit_debug(u, "Child "PID_FMT" belongs to %s.", si->si_pid, u->id); unit_unwatch_pid(u, si->si_pid); - if (UNIT_VTABLE(u)->sigchld_event) { - if (set_size(u->pids) <= 1 || - iteration != u->sigchldgen || - unit_main_pid(u) == si->si_pid || - unit_control_pid(u) == si->si_pid) { - UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status); - u->sigchldgen = iteration; - } else - log_debug("%s already issued a sigchld this iteration %" PRIu64 ", skipping. Pids still being watched %d", u->id, iteration, set_size(u->pids)); - } + if (UNIT_VTABLE(u)->sigchld_event) + UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status); } -static int manager_dispatch_sigchld(Manager *m) { +static int manager_dispatch_sigchld(sd_event_source *source, void *userdata) { + Manager *m = userdata; + siginfo_t si = {}; + int r; + + assert(source); assert(m); - for (;;) { - siginfo_t si = {}; + /* First we call waitd() for a PID and do not reap the zombie. That way we can still access /proc/$PID for it + * while it is a zombie. */ - /* First we call waitd() for a PID and do not reap the - * zombie. That way we can still access /proc/$PID for - * it while it is a zombie. */ - if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) { + if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) { - if (errno == ECHILD) - break; + if (errno == ECHILD) + goto turn_off; - if (errno == EINTR) - continue; + log_error_errno(errno, "Failed to peek for child with waitid(), ignoring: %m"); + return 0; + } - return -errno; + if (si.si_pid <= 0) + goto turn_off; + + if (IN_SET(si.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED)) { + _cleanup_free_ Unit **array_copy = NULL; + _cleanup_free_ char *name = NULL; + Unit *u1, *u2, **array; + + (void) get_process_comm(si.si_pid, &name); + + log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)", + si.si_pid, strna(name), + sigchld_code_to_string(si.si_code), + si.si_status, + strna(si.si_code == CLD_EXITED + ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL) + : signal_to_string(si.si_status))); + + /* Increase the generation counter used for filtering out duplicate unit invocations */ + m->sigchldgen++; + + /* And now figure out the unit this belongs to, it might be multiple... */ + u1 = manager_get_unit_by_pid_cgroup(m, si.si_pid); + u2 = hashmap_get(m->watch_pids, PID_TO_PTR(si.si_pid)); + array = hashmap_get(m->watch_pids, PID_TO_PTR(-si.si_pid)); + if (array) { + size_t n = 0; + + /* Cound how many entries the array has */ + while (array[n]) + n++; + + /* Make a copy of the array so that we don't trip up on the array changing beneath us */ + array_copy = newdup(Unit*, array, n+1); + if (!array_copy) + log_oom(); } - if (si.si_pid <= 0) - break; + /* Finally, execute them all. Note that u1, u2 and the array might contain duplicates, but + * that's fine, manager_invoke_sigchld_event() will ensure we only invoke the handlers once for + * each iteration. */ + if (u1) + manager_invoke_sigchld_event(m, u1, &si); + if (u2) + manager_invoke_sigchld_event(m, u2, &si); + if (array_copy) + for (size_t i = 0; array_copy[i]; i++) + manager_invoke_sigchld_event(m, array_copy[i], &si); + } - if (IN_SET(si.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED)) { - _cleanup_free_ char *name = NULL; - Unit *u1, *u2, *u3; - - get_process_comm(si.si_pid, &name); - - log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)", - si.si_pid, strna(name), - sigchld_code_to_string(si.si_code), - si.si_status, - strna(si.si_code == CLD_EXITED - ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL) - : signal_to_string(si.si_status))); - - /* And now figure out the unit this belongs - * to, it might be multiple... */ - u1 = manager_get_unit_by_pid_cgroup(m, si.si_pid); - if (u1) - invoke_sigchld_event(m, u1, &si); - u2 = hashmap_get(m->watch_pids1, PID_TO_PTR(si.si_pid)); - if (u2 && u2 != u1) - invoke_sigchld_event(m, u2, &si); - u3 = hashmap_get(m->watch_pids2, PID_TO_PTR(si.si_pid)); - if (u3 && u3 != u2 && u3 != u1) - invoke_sigchld_event(m, u3, &si); - } + /* And now, we actually reap the zombie. */ + if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) { + log_error_errno(errno, "Failed to dequeue child, ignoring: %m"); + return 0; + } - /* And now, we actually reap the zombie. */ - if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) { - if (errno == EINTR) - continue; + return 0; - return -errno; - } - } +turn_off: + /* All children processed for now, turn off event source */ + + r = sd_event_source_set_enabled(m->sigchld_event_source, SD_EVENT_OFF); + if (r < 0) + return log_error_errno(r, "Failed to disable SIGCHLD event source: %m"); return 0; } @@ -2126,7 +2218,6 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t Manager *m = userdata; ssize_t n; struct signalfd_siginfo sfsi; - bool sigchld = false; int r; assert(m); @@ -2137,195 +2228,192 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t return 0; } - for (;;) { - n = read(m->signal_fd, &sfsi, sizeof(sfsi)); - if (n != sizeof(sfsi)) { - if (n >= 0) { - log_warning("Truncated read from signal fd (%zu bytes)!", n); - return 0; - } + n = read(m->signal_fd, &sfsi, sizeof(sfsi)); + if (n != sizeof(sfsi)) { + if (n >= 0) { + log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n); + return 0; + } - if (IN_SET(errno, EINTR, EAGAIN)) - break; + if (IN_SET(errno, EINTR, EAGAIN)) + return 0; - /* We return an error here, which will kill this handler, - * to avoid a busy loop on read error. */ - return log_error_errno(errno, "Reading from signal fd failed: %m"); - } + /* We return an error here, which will kill this handler, + * to avoid a busy loop on read error. */ + return log_error_errno(errno, "Reading from signal fd failed: %m"); + } - log_received_signal(sfsi.ssi_signo == SIGCHLD || - (sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m)) - ? LOG_DEBUG : LOG_INFO, - &sfsi); + log_received_signal(sfsi.ssi_signo == SIGCHLD || + (sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m)) + ? LOG_DEBUG : LOG_INFO, + &sfsi); - switch (sfsi.ssi_signo) { + switch (sfsi.ssi_signo) { - case SIGCHLD: - sigchld = true; - break; + case SIGCHLD: + r = sd_event_source_set_enabled(m->sigchld_event_source, SD_EVENT_ON); + if (r < 0) + log_warning_errno(r, "Failed to enable SIGCHLD even source, ignoring: %m"); - case SIGTERM: - if (MANAGER_IS_SYSTEM(m)) { - /* This is for compatibility with the - * original sysvinit */ - r = verify_run_space_and_log("Refusing to reexecute"); - if (r >= 0) - m->exit_code = MANAGER_REEXECUTE; - break; - } + break; - _fallthrough_; - case SIGINT: - if (MANAGER_IS_SYSTEM(m)) - manager_handle_ctrl_alt_del(m); - else - manager_start_target(m, SPECIAL_EXIT_TARGET, - JOB_REPLACE_IRREVERSIBLY); + case SIGTERM: + if (MANAGER_IS_SYSTEM(m)) { + /* This is for compatibility with the + * original sysvinit */ + r = verify_run_space_and_log("Refusing to reexecute"); + if (r >= 0) + m->exit_code = MANAGER_REEXECUTE; break; + } - case SIGWINCH: - if (MANAGER_IS_SYSTEM(m)) - manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE); + _fallthrough_; + case SIGINT: + if (MANAGER_IS_SYSTEM(m)) + manager_handle_ctrl_alt_del(m); + else + manager_start_target(m, SPECIAL_EXIT_TARGET, + JOB_REPLACE_IRREVERSIBLY); + break; - /* This is a nop on non-init */ - break; + case SIGWINCH: + if (MANAGER_IS_SYSTEM(m)) + manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE); - case SIGPWR: - if (MANAGER_IS_SYSTEM(m)) - manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE); + /* This is a nop on non-init */ + break; - /* This is a nop on non-init */ - break; + case SIGPWR: + if (MANAGER_IS_SYSTEM(m)) + manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE); - case SIGUSR1: { - Unit *u; + /* This is a nop on non-init */ + break; - u = manager_get_unit(m, SPECIAL_DBUS_SERVICE); + case SIGUSR1: { + Unit *u; - if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) { - log_info("Trying to reconnect to bus..."); - bus_init(m, true); - } + u = manager_get_unit(m, SPECIAL_DBUS_SERVICE); - if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) { - log_info("Loading D-Bus service..."); - manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE); - } + if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) { + log_info("Trying to reconnect to bus..."); + bus_init(m, true); + } + + if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) { + log_info("Loading D-Bus service..."); + manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE); + } + break; + } + + case SIGUSR2: { + _cleanup_free_ char *dump = NULL; + + r = manager_get_dump_string(m, &dump); + if (r < 0) { + log_warning_errno(errno, "Failed to acquire manager dump: %m"); break; } - case SIGUSR2: { - _cleanup_free_ char *dump = NULL; + log_dump(LOG_INFO, dump); + break; + } - r = manager_get_dump_string(m, &dump); - if (r < 0) { - log_warning_errno(errno, "Failed to acquire manager dump: %m"); - break; - } + case SIGHUP: + r = verify_run_space_and_log("Refusing to reload"); + if (r >= 0) + m->exit_code = MANAGER_RELOAD; + break; + + default: { + + /* Starting SIGRTMIN+0 */ + static const struct { + const char *target; + JobMode mode; + } target_table[] = { + [0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE }, + [1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE }, + [2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE }, + [3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY }, + [4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY }, + [5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY }, + [6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY }, + }; + + /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */ + static const ManagerExitCode code_table[] = { + [0] = MANAGER_HALT, + [1] = MANAGER_POWEROFF, + [2] = MANAGER_REBOOT, + [3] = MANAGER_KEXEC, + }; - log_dump(LOG_INFO, dump); + if ((int) sfsi.ssi_signo >= SIGRTMIN+0 && + (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) { + int idx = (int) sfsi.ssi_signo - SIGRTMIN; + manager_start_target(m, target_table[idx].target, + target_table[idx].mode); break; } - case SIGHUP: - r = verify_run_space_and_log("Refusing to reload"); - if (r >= 0) - m->exit_code = MANAGER_RELOAD; + if ((int) sfsi.ssi_signo >= SIGRTMIN+13 && + (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) { + m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13]; break; + } - default: { - - /* Starting SIGRTMIN+0 */ - static const struct { - const char *target; - JobMode mode; - } target_table[] = { - [0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE }, - [1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE }, - [2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE }, - [3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY }, - [4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY }, - [5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY }, - [6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY } - }; - - /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */ - static const ManagerExitCode code_table[] = { - [0] = MANAGER_HALT, - [1] = MANAGER_POWEROFF, - [2] = MANAGER_REBOOT, - [3] = MANAGER_KEXEC - }; - - if ((int) sfsi.ssi_signo >= SIGRTMIN+0 && - (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) { - int idx = (int) sfsi.ssi_signo - SIGRTMIN; - manager_start_target(m, target_table[idx].target, - target_table[idx].mode); - break; - } + switch (sfsi.ssi_signo - SIGRTMIN) { - if ((int) sfsi.ssi_signo >= SIGRTMIN+13 && - (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) { - m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13]; - break; - } + case 20: + manager_set_show_status(m, SHOW_STATUS_YES); + break; + + case 21: + manager_set_show_status(m, SHOW_STATUS_NO); + break; + + case 22: + log_set_max_level(LOG_DEBUG); + log_info("Setting log level to debug."); + break; + + case 23: + log_set_max_level(LOG_INFO); + log_info("Setting log level to info."); + break; - switch (sfsi.ssi_signo - SIGRTMIN) { - - case 20: - manager_set_show_status(m, SHOW_STATUS_YES); - break; - - case 21: - manager_set_show_status(m, SHOW_STATUS_NO); - break; - - case 22: - log_set_max_level(LOG_DEBUG); - log_info("Setting log level to debug."); - break; - - case 23: - log_set_max_level(LOG_INFO); - log_info("Setting log level to info."); - break; - - case 24: - if (MANAGER_IS_USER(m)) { - m->exit_code = MANAGER_EXIT; - return 0; - } - - /* This is a nop on init */ - break; - - case 26: - case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */ - log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); - log_notice("Setting log target to journal-or-kmsg."); - break; - - case 27: - log_set_target(LOG_TARGET_CONSOLE); - log_notice("Setting log target to console."); - break; - - case 28: - log_set_target(LOG_TARGET_KMSG); - log_notice("Setting log target to kmsg."); - break; - - default: - log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo)); + case 24: + if (MANAGER_IS_USER(m)) { + m->exit_code = MANAGER_EXIT; + return 0; } - } - } - } - if (sigchld) - manager_dispatch_sigchld(m); + /* This is a nop on init */ + break; + + case 26: + case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */ + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_notice("Setting log target to journal-or-kmsg."); + break; + + case 27: + log_set_target(LOG_TARGET_CONSOLE); + log_notice("Setting log target to console."); + break; + + case 28: + log_set_target(LOG_TARGET_KMSG); + log_notice("Setting log target to kmsg."); + break; + + default: + log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo)); + } + }} return 0; } @@ -2362,8 +2450,15 @@ static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32 assert(m); assert(m->idle_pipe[2] == fd); + /* There's at least one Type=idle child that just gave up on us waiting for the boot process to complete. Let's + * now turn off any further console output if there's at least one service that needs console access, so that + * from now on our own output should not spill into that service's output anymore. After all, we support + * Type=idle only to beautify console output and it generally is set on services that want to own the console + * exclusively without our interference. */ m->no_console_output = m->n_on_console > 0; + /* Acknowledge the child's request, and let all all other children know too that they shouldn't wait any longer + * by closing the pipes towards them, which is what they are waiting for. */ manager_close_idle_pipe(m); return 0; @@ -2400,11 +2495,10 @@ int manager_loop(Manager *m) { manager_check_finished(m); - /* There might still be some zombies hanging around from - * before we were exec()'ed. Let's reap them. */ - r = manager_dispatch_sigchld(m); + /* There might still be some zombies hanging around from before we were exec()'ed. Let's reap them. */ + r = sd_event_source_set_enabled(m->sigchld_event_source, SD_EVENT_ON); if (r < 0) - return r; + return log_error_errno(r, "Failed to enable SIGCHLD event source: %m"); while (m->exit_code == MANAGER_OK) { usec_t wait_usec; @@ -2643,6 +2737,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) { fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs); fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr)); fprintf(f, "ready-sent=%s\n", yes_no(m->ready_sent)); + fprintf(f, "taint-logged=%s\n", yes_no(m->taint_logged)); + fprintf(f, "service-watchdogs=%s\n", yes_no(m->service_watchdogs)); for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) { /* The userspace and finish timestamps only apply to the host system, hence only serialize them there */ @@ -2805,6 +2901,24 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { else m->ready_sent = m->ready_sent || b; + } else if ((val = startswith(l, "taint-logged="))) { + int b; + + b = parse_boolean(val); + if (b < 0) + log_notice("Failed to parse taint-logged flag %s", val); + else + m->taint_logged = m->taint_logged || b; + + } else if ((val = startswith(l, "service-watchdogs="))) { + int b; + + b = parse_boolean(val); + if (b < 0) + log_notice("Failed to parse service-watchdogs flag %s", val); + else + m->service_watchdogs = b; + } else if (startswith(l, "env=")) { r = deserialize_environment(&m->environment, l); if (r == -ENOMEM) @@ -3026,6 +3140,9 @@ int manager_reload(Manager *m) { manager_vacuum_uid_refs(m); manager_vacuum_gid_refs(m); + /* It might be safe to log to the journal now. */ + manager_recheck_journal(m); + /* Sync current state of bus names with our set of listening units */ if (m->api_bus) manager_sync_bus_names(m, m->api_bus); @@ -3062,6 +3179,27 @@ bool manager_unit_inactive_or_pending(Manager *m, const char *name) { return unit_inactive_or_pending(u); } +static void log_taint_string(Manager *m) { + _cleanup_free_ char *taint = NULL; + + assert(m); + + if (MANAGER_IS_USER(m) || m->taint_logged) + return; + + m->taint_logged = true; /* only check for taint once */ + + taint = manager_taint_string(m); + if (isempty(taint)) + return; + + log_struct(LOG_NOTICE, + LOG_MESSAGE("System is tainted: %s", taint), + "TAINT=%s", taint, + "MESSAGE_ID=" SD_MESSAGE_TAINTED_STR, + NULL); +} + static void manager_notify_finished(Manager *m) { char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX]; usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec; @@ -3070,6 +3208,11 @@ static void manager_notify_finished(Manager *m) { return; if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) { + char ts[FORMAT_TIMESPAN_MAX]; + char buf[FORMAT_TIMESPAN_MAX + STRLEN(" (firmware) + ") + FORMAT_TIMESPAN_MAX + STRLEN(" (loader) + ")] + = {}; + char *p = buf; + size_t size = sizeof buf; /* Note that MANAGER_TIMESTAMP_KERNEL's monotonic value is always at 0, and * MANAGER_TIMESTAMP_FIRMWARE's and MANAGER_TIMESTAMP_LOADER's monotonic value should be considered @@ -3080,6 +3223,11 @@ static void manager_notify_finished(Manager *m) { userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic; total_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic + m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic; + if (firmware_usec > 0) + size = strpcpyf(&p, size, "%s (firmware) + ", format_timespan(ts, sizeof(ts), firmware_usec, USEC_PER_MSEC)); + if (loader_usec > 0) + size = strpcpyf(&p, size, "%s (loader) + ", format_timespan(ts, sizeof(ts), loader_usec, USEC_PER_MSEC)); + if (dual_timestamp_is_set(&m->timestamps[MANAGER_TIMESTAMP_INITRD])) { /* The initrd case on bare-metal*/ @@ -3091,7 +3239,8 @@ static void manager_notify_finished(Manager *m) { "KERNEL_USEC="USEC_FMT, kernel_usec, "INITRD_USEC="USEC_FMT, initrd_usec, "USERSPACE_USEC="USEC_FMT, userspace_usec, - LOG_MESSAGE("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.", + LOG_MESSAGE("Startup finished in %s%s (kernel) + %s (initrd) + %s (userspace) = %s.", + buf, format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC), format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC), format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC), @@ -3107,14 +3256,15 @@ static void manager_notify_finished(Manager *m) { "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR, "KERNEL_USEC="USEC_FMT, kernel_usec, "USERSPACE_USEC="USEC_FMT, userspace_usec, - LOG_MESSAGE("Startup finished in %s (kernel) + %s (userspace) = %s.", + LOG_MESSAGE("Startup finished in %s%s (kernel) + %s (userspace) = %s.", + buf, format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC), format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC), format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)), NULL); } } else { - /* The container case */ + /* The container and --user case */ firmware_usec = loader_usec = initrd_usec = kernel_usec = 0; total_usec = userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic; @@ -3134,32 +3284,55 @@ static void manager_notify_finished(Manager *m) { "STATUS=Startup finished in %s.", format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)); m->ready_sent = true; + + log_taint_string(m); } -void manager_check_finished(Manager *m) { +static void manager_send_ready(Manager *m) { assert(m); - if (MANAGER_IS_RELOADING(m)) + /* We send READY=1 on reaching basic.target only when running in --user mode. */ + if (!MANAGER_IS_USER(m) || m->ready_sent) + return; + + m->ready_sent = true; + + sd_notifyf(false, + "READY=1\n" + "STATUS=Reached " SPECIAL_BASIC_TARGET "."); +} + +static void manager_check_basic_target(Manager *m) { + Unit *u; + + assert(m); + + /* Small shortcut */ + if (m->ready_sent && m->taint_logged) return; - /* Verify that we are actually running currently. Initially - * the exit code is set to invalid, and during operation it is - * then set to MANAGER_OK */ - if (m->exit_code != MANAGER_OK) + u = manager_get_unit(m, SPECIAL_BASIC_TARGET); + if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) return; /* For user managers, send out READY=1 as soon as we reach basic.target */ - if (MANAGER_IS_USER(m) && !m->ready_sent) { - Unit *u; + manager_send_ready(m); - u = manager_get_unit(m, SPECIAL_BASIC_TARGET); - if (u && !u->job) { - sd_notifyf(false, - "READY=1\n" - "STATUS=Reached " SPECIAL_BASIC_TARGET "."); - m->ready_sent = true; - } - } + /* Log the taint string as soon as we reach basic.target */ + log_taint_string(m); +} + +void manager_check_finished(Manager *m) { + assert(m); + + if (MANAGER_IS_RELOADING(m)) + return; + + /* Verify that we have entered the event loop already, and not left it again. */ + if (!MANAGER_IS_RUNNING(m)) + return; + + manager_check_basic_target(m); if (hashmap_size(m->jobs) > 0) { if (m->jobs_in_progress_event_source) @@ -3308,8 +3481,7 @@ int manager_environment_add(Manager *m, char **minus, char **plus) { strv_free(b); m->environment = l; - manager_clean_environment(m); - strv_sort(m->environment); + manager_sanitize_environment(m); return 0; } @@ -3333,28 +3505,50 @@ int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) { return 0; } -void manager_recheck_journal(Manager *m) { +static bool manager_journal_is_running(Manager *m) { Unit *u; assert(m); + /* If we are the user manager we can safely assume that the journal is up */ if (!MANAGER_IS_SYSTEM(m)) - return; + return true; + /* Check that the socket is not only up, but in RUNNING state */ u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET); - if (u && SOCKET(u)->state != SOCKET_RUNNING) { - log_close_journal(); - return; - } + if (!u) + return false; + if (SOCKET(u)->state != SOCKET_RUNNING) + return false; + /* Similar, check if the daemon itself is fully up, too */ u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE); - if (u && SERVICE(u)->state != SERVICE_RUNNING) { - log_close_journal(); + if (!u) + return false; + if (SERVICE(u)->state != SERVICE_RUNNING) + return false; + + return true; +} + +void manager_recheck_journal(Manager *m) { + + assert(m); + + /* Don't bother with this unless we are in the special situation of being PID 1 */ + if (getpid_cached() != 1) return; - } - /* Hmm, OK, so the socket is fully up and the service is up - * too, then let's make use of the thing. */ + if (manager_journal_is_running(m)) { + + /* The journal is fully and entirely up? If so, let's permit logging to it, if that's configured. */ + log_set_prohibit_ipc(false); + } else { + + /* If the journal is down, don't ever log to it, otherwise we might end up deadlocking ourselves as we + * might trigger an activation ourselves we can't fulfill */ + log_set_prohibit_ipc(true); + } log_open(); } @@ -3392,10 +3586,7 @@ static bool manager_get_show_status(Manager *m, StatusType type) { if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0) return false; - if (m->show_status > 0) - return true; - - return false; + return m->show_status > 0; } const char *manager_get_confirm_spawn(Manager *m) { @@ -3919,6 +4110,21 @@ char *manager_taint_string(Manager *m) { return buf; } +void manager_ref_console(Manager *m) { + assert(m); + + m->n_on_console++; +} + +void manager_unref_console(Manager *m) { + + assert(m->n_on_console > 0); + m->n_on_console--; + + if (m->n_on_console == 0) + m->no_console_output = false; /* unset no_console_output flag, since the console is definitely free now */ +} + static const char *const manager_state_table[_MANAGER_STATE_MAX] = { [MANAGER_INITIALIZING] = "initializing", [MANAGER_STARTING] = "starting", diff --git a/src/core/manager.h b/src/core/manager.h index 902af2609d..0eed67b46a 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -145,14 +145,14 @@ struct Manager { sd_event *event; - /* We use two hash tables here, since the same PID might be - * watched by two different units: once the unit that forked - * it off, and possibly a different unit to which it was - * joined as cgroup member. Since we know that it is either - * one or two units for each PID we just use to hashmaps - * here. */ - Hashmap *watch_pids1; /* pid => Unit object n:1 */ - Hashmap *watch_pids2; /* pid => Unit object n:1 */ + /* This maps PIDs we care about to units that are interested in. We allow multiple units to he interested in + * the same PID and multiple PIDs to be relevant to the same unit. Since in most cases only a single unit will + * be interested in the same PID we use a somewhat special encoding here: the first unit interested in a PID is + * stored directly in the hashmap, keyed by the PID unmodified. If there are other units interested too they'll + * be stored in a NULL-terminated array, and keyed by the negative PID. This is safe as pid_t is signed and + * negative PIDs are not used for regular processes but process groups, which we don't care about in this + * context, but this allows us to use the negative range for our own purposes. */ + Hashmap *watch_pids; /* pid => unit as well as -pid => array of units */ /* A set contains all units which cgroup should be refreshed after startup */ Set *startup_units; @@ -172,6 +172,8 @@ struct Manager { int signal_fd; sd_event_source *signal_event_source; + sd_event_source *sigchld_event_source; + int time_change_fd; sd_event_source *time_change_event_source; @@ -261,8 +263,15 @@ struct Manager { bool taint_usr:1; + /* Have we already sent out the READY=1 notification? */ bool ready_sent:1; + /* Have we already printed the taint line if necessary? */ + bool taint_logged:1; + + /* Have we ever changed the "kernel.pid_max" sysctl? */ + bool sysctl_pid_max_changed:1; + unsigned test_run_flags:8; /* If non-zero, exit with the following value when the systemd @@ -273,6 +282,7 @@ struct Manager { ShowStatus show_status; char *confirm_spawn; bool no_console_output; + bool service_watchdogs; ExecOutput default_std_output, default_std_error; @@ -343,8 +353,13 @@ struct Manager { int first_boot; /* tri-state */ - /* prefixes of e.g. RuntimeDirectory= */ + /* Prefixes of e.g. RuntimeDirectory= */ char *prefix[_EXEC_DIRECTORY_TYPE_MAX]; + + /* Used in the SIGCHLD and sd_notify() message invocation logic to avoid that we dispatch the same event + * multiple times on the same unit. */ + unsigned sigchldgen; + unsigned notifygen; }; #define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM) @@ -354,6 +369,9 @@ struct Manager { #define MANAGER_IS_FINISHED(m) (dual_timestamp_is_set((m)->timestamps + MANAGER_TIMESTAMP_FINISH)) +/* The exit code is set to OK as soon as we enter the main loop, and set otherwise as soon as we are done with it */ +#define MANAGER_IS_RUNNING(m) ((m)->exit_code == MANAGER_OK) + int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **m); Manager* manager_free(Manager *m); @@ -437,6 +455,9 @@ void manager_deserialize_gid_refs_one(Manager *m, const char *value); char *manager_taint_string(Manager *m); +void manager_ref_console(Manager *m); +void manager_unref_console(Manager *m); + const char *manager_state_to_string(ManagerState m) _const_; ManagerState manager_state_from_string(const char *s) _pure_; diff --git a/src/core/meson.build b/src/core/meson.build index 535ccde468..bc034082a5 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -60,6 +60,8 @@ libcore_la_sources = ''' dbus-timer.h dbus-unit.c dbus-unit.h + dbus-util.c + dbus-util.h dbus.c dbus.h device.c diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index 7171d8fda4..a0c5f5aaae 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -155,10 +155,12 @@ bool mount_point_ignore(const char *path) { } static int mount_one(const MountPoint *p, bool relabel) { - int r; + int r, priority; assert(p); + priority = (p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG; + if (p->condition_fn && !p->condition_fn()) return 0; @@ -168,7 +170,7 @@ static int mount_one(const MountPoint *p, bool relabel) { r = path_is_mount_point(p->where, NULL, AT_SYMLINK_FOLLOW); if (r < 0 && r != -ENOENT) { - log_full_errno((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, r, "Failed to determine whether %s is a mount point: %m", p->where); + log_full_errno(priority, r, "Failed to determine whether %s is a mount point: %m", p->where); return (p->mode & MNT_FATAL) ? r : 0; } if (r > 0) @@ -196,7 +198,7 @@ static int mount_one(const MountPoint *p, bool relabel) { p->type, p->flags, p->options) < 0) { - log_full_errno((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, errno, "Failed to mount %s at %s: %m", p->type, p->where); + log_full_errno(priority, errno, "Failed to mount %s at %s: %m", p->type, p->where); return (p->mode & MNT_FATAL) ? -errno : 0; } @@ -205,10 +207,13 @@ static int mount_one(const MountPoint *p, bool relabel) { (void) label_fix(p->where, false, false); if (p->mode & MNT_CHECK_WRITABLE) { - r = access(p->where, W_OK); - if (r < 0) { + if (access(p->where, W_OK) < 0) { + r = -errno; + (void) umount(p->where); (void) rmdir(p->where); + + log_full_errno(priority, r, "Mount point %s not writable after mounting: %m", p->where); return (p->mode & MNT_FATAL) ? r : 0; } } diff --git a/src/core/mount.c b/src/core/mount.c index b25bb9cb40..4c12542bd7 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -55,7 +55,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter); static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { [MOUNT_DEAD] = UNIT_INACTIVE, [MOUNT_MOUNTING] = UNIT_ACTIVATING, - [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE, + [MOUNT_MOUNTING_DONE] = UNIT_ACTIVATING, [MOUNT_MOUNTED] = UNIT_ACTIVE, [MOUNT_REMOUNTING] = UNIT_RELOADING, [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING, @@ -164,6 +164,10 @@ static void mount_init(Unit *u) { assert(u->load_state == UNIT_STUB); m->timeout_usec = u->manager->default_timeout_start_usec; + + m->exec_context.std_output = u->manager->default_std_output; + m->exec_context.std_error = u->manager->default_std_error; + m->directory_mode = 0755; /* We need to make sure that /usr/bin/mount is always called @@ -938,7 +942,7 @@ static void mount_enter_mounting(Mount *m) { assert(m); - r = unit_fail_if_symlink(UNIT(m), m->where); + r = unit_fail_if_noncanonical(UNIT(m), m->where); if (r < 0) goto fail; @@ -1131,10 +1135,6 @@ static int mount_reload(Unit *u) { Mount *m = MOUNT(u); assert(m); - - if (m->state == MOUNT_MOUNTING_DONE) /* not yet ready to reload, try again */ - return -EAGAIN; - assert(m->state == MOUNT_MOUNTED); mount_enter_remounting(m); @@ -1276,23 +1276,25 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) { log_unit_full(u, f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, 0, "Mount process exited, code=%s status=%i", sigchld_code_to_string(code), status); - /* Note that mount(8) returning and the kernel sending us a mount table change event might happen - * out-of-order. If an operation succeed we assume the kernel will follow soon too and already change into the - * resulting state. If it fails we check if the kernel still knows about the mount. and change state - * accordingly. */ + /* Note that due to the io event priority logic, we can be sure the new mountinfo is loaded + * before we process the SIGCHLD for the mount command. */ switch (m->state) { case MOUNT_MOUNTING: - case MOUNT_MOUNTING_DONE: + /* Our mount point has not appeared in mountinfo. Something went wrong. */ - if (f == MOUNT_SUCCESS || m->from_proc_self_mountinfo) - /* If /bin/mount returned success, or if we see the mount point in /proc/self/mountinfo we are - * happy. If we see the first condition first, we should see the second condition - * immediately after – or /bin/mount lies to us and is broken. */ - mount_enter_mounted(m, f); - else - mount_enter_dead(m, f); + if (f == MOUNT_SUCCESS) { + /* Either /bin/mount has an unexpected definition of success, + * or someone raced us and we lost. */ + log_unit_warning(UNIT(m), "Mount process finished, but there is no mount."); + f = MOUNT_FAILURE_PROTOCOL; + } + mount_enter_dead(m, f); + break; + + case MOUNT_MOUNTING_DONE: + mount_enter_mounted(m, f); break; case MOUNT_REMOUNTING: @@ -1302,28 +1304,31 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) { break; case MOUNT_UNMOUNTING: - case MOUNT_UNMOUNTING_SIGKILL: - case MOUNT_UNMOUNTING_SIGTERM: - if (m->from_proc_self_mountinfo) { + if (f == MOUNT_SUCCESS && m->from_proc_self_mountinfo) { /* Still a mount point? If so, let's try again. Most likely there were multiple mount points - * stacked on top of each other. Note that due to the io event priority logic we can be sure - * the new mountinfo is loaded before we process the SIGCHLD for the mount command. */ + * stacked on top of each other. We might exceed the timeout specified by the user overall, + * but we will stop as soon as any one umount times out. */ if (m->n_retry_umount < RETRY_UMOUNT_MAX) { log_unit_debug(u, "Mount still present, trying again."); m->n_retry_umount++; mount_enter_unmounting(m); } else { - log_unit_debug(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount); + log_unit_warning(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount); mount_enter_mounted(m, f); } } else - mount_enter_dead(m, f); + mount_enter_dead_or_mounted(m, f); break; + case MOUNT_UNMOUNTING_SIGKILL: + case MOUNT_UNMOUNTING_SIGTERM: + mount_enter_dead_or_mounted(m, f); + break; + default: assert_not_reached("Uh, control process died at wrong time."); } @@ -1486,7 +1491,7 @@ static int mount_setup_existing_unit( flags->just_changed = r1 > 0 || r2 > 0 || r3 > 0; flags->is_mounted = true; - flags->just_mounted = !MOUNT(u)->from_proc_self_mountinfo; + flags->just_mounted = !MOUNT(u)->from_proc_self_mountinfo || MOUNT(u)->just_mounted; MOUNT(u)->from_proc_self_mountinfo = true; @@ -1748,7 +1753,7 @@ static void mount_enumerate(Manager *m) { goto fail; } - r = sd_event_source_set_priority(m->mount_event_source, -10); + r = sd_event_source_set_priority(m->mount_event_source, SD_EVENT_PRIORITY_NORMAL-10); if (r < 0) { log_error_errno(r, "Failed to adjust mount watch priority: %m"); goto fail; @@ -1947,6 +1952,7 @@ static const char* const mount_result_table[_MOUNT_RESULT_MAX] = { [MOUNT_FAILURE_SIGNAL] = "signal", [MOUNT_FAILURE_CORE_DUMP] = "core-dump", [MOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit", + [MOUNT_FAILURE_PROTOCOL] = "protocol", }; DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult); diff --git a/src/core/mount.h b/src/core/mount.h index 44fe3b889e..1a496def84 100644 --- a/src/core/mount.h +++ b/src/core/mount.h @@ -35,12 +35,13 @@ typedef enum MountExecCommand { typedef enum MountResult { MOUNT_SUCCESS, - MOUNT_FAILURE_RESOURCES, + MOUNT_FAILURE_RESOURCES, /* a bit of a misnomer, just our catch-all error for errnos we didn't expect */ MOUNT_FAILURE_TIMEOUT, MOUNT_FAILURE_EXIT_CODE, MOUNT_FAILURE_SIGNAL, MOUNT_FAILURE_CORE_DUMP, MOUNT_FAILURE_START_LIMIT_HIT, + MOUNT_FAILURE_PROTOCOL, _MOUNT_RESULT_MAX, _MOUNT_RESULT_INVALID = -1 } MountResult; diff --git a/src/core/namespace.c b/src/core/namespace.c index a3262fcc4d..70089f212a 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -42,6 +42,7 @@ #include "path-util.h" #include "selinux-util.h" #include "socket-util.h" +#include "stat-util.h" #include "string-table.h" #include "string-util.h" #include "strv.h" @@ -496,6 +497,35 @@ static void drop_outside_root(const char *root_directory, MountEntry *m, unsigne *n = t - m; } +static int clone_device_node(const char *d, const char *temporary_mount) { + const char *dn; + struct stat st; + int r; + + if (stat(d, &st) < 0) { + if (errno == ENOENT) + return 0; + return -errno; + } + + if (!S_ISBLK(st.st_mode) && + !S_ISCHR(st.st_mode)) + return -EINVAL; + + if (st.st_rdev == 0) + return 0; + + dn = strjoina(temporary_mount, d); + + mac_selinux_create_file_prepare(d, st.st_mode); + r = mknod(dn, st.st_mode, st.st_rdev); + mac_selinux_create_file_clear(); + if (r < 0) + return log_debug_errno(errno, "mknod failed for %s: %m", d); + + return 1; +} + static int mount_private_dev(MountEntry *m) { static const char devnodes[] = "/dev/null\0" @@ -531,14 +561,33 @@ static int mount_private_dev(MountEntry *m) { goto fail; } - devptmx = strjoina(temporary_mount, "/dev/ptmx"); - if (symlink("pts/ptmx", devptmx) < 0) { - r = -errno; + /* /dev/ptmx can either be a device node or a symlink to /dev/pts/ptmx + * when /dev/ptmx a device node, /dev/pts/ptmx has 000 permissions making it inaccessible + * thus, in that case make a clone + * + * in nspawn and other containers it will be a symlink, in that case make it a symlink + */ + r = is_symlink("/dev/ptmx"); + if (r < 0) goto fail; + if (r > 0) { + devptmx = strjoina(temporary_mount, "/dev/ptmx"); + if (symlink("pts/ptmx", devptmx) < 0) { + r = -errno; + goto fail; + } + } else { + r = clone_device_node("/dev/ptmx", temporary_mount); + if (r < 0) + goto fail; + if (r == 0) { + r = -ENXIO; + goto fail; + } } devshm = strjoina(temporary_mount, "/dev/shm"); - (void) mkdir(devshm, 01777); + (void) mkdir(devshm, 0755); r = mount("/dev/shm", devshm, NULL, MS_BIND, NULL); if (r < 0) { r = -errno; @@ -557,42 +606,9 @@ static int mount_private_dev(MountEntry *m) { (void) symlink("/run/systemd/journal/dev-log", devlog); NULSTR_FOREACH(d, devnodes) { - _cleanup_free_ char *dn = NULL; - struct stat st; - - r = stat(d, &st); - if (r < 0) { - - if (errno == ENOENT) - continue; - - r = -errno; - goto fail; - } - - if (!S_ISBLK(st.st_mode) && - !S_ISCHR(st.st_mode)) { - r = -EINVAL; - goto fail; - } - - if (st.st_rdev == 0) - continue; - - dn = strappend(temporary_mount, d); - if (!dn) { - r = -ENOMEM; - goto fail; - } - - mac_selinux_create_file_prepare(d, st.st_mode); - r = mknod(dn, st.st_mode, st.st_rdev); - mac_selinux_create_file_clear(); - - if (r < 0) { - r = -errno; + r = clone_device_node(d, temporary_mount); + if (r < 0) goto fail; - } } dev_setup(temporary_mount, UID_INVALID, GID_INVALID); @@ -1450,6 +1466,18 @@ static const char *const protect_home_table[_PROTECT_HOME_MAX] = { DEFINE_STRING_TABLE_LOOKUP(protect_home, ProtectHome); +ProtectHome parse_protect_home_or_bool(const char *s) { + int r; + + r = parse_boolean(s); + if (r > 0) + return PROTECT_HOME_YES; + if (r == 0) + return PROTECT_HOME_NO; + + return protect_home_from_string(s); +} + static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = { [PROTECT_SYSTEM_NO] = "no", [PROTECT_SYSTEM_YES] = "yes", @@ -1459,6 +1487,18 @@ static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = { DEFINE_STRING_TABLE_LOOKUP(protect_system, ProtectSystem); +ProtectSystem parse_protect_system_or_bool(const char *s) { + int r; + + r = parse_boolean(s); + if (r > 0) + return PROTECT_SYSTEM_YES; + if (r == 0) + return PROTECT_SYSTEM_NO; + + return protect_system_from_string(s); +} + static const char* const namespace_type_table[] = { [NAMESPACE_MOUNT] = "mnt", [NAMESPACE_CGROUP] = "cgroup", diff --git a/src/core/namespace.h b/src/core/namespace.h index f0f198362c..42d841c4d2 100644 --- a/src/core/namespace.h +++ b/src/core/namespace.h @@ -101,9 +101,11 @@ int setup_netns(int netns_storage_socket[2]); const char* protect_home_to_string(ProtectHome p) _const_; ProtectHome protect_home_from_string(const char *s) _pure_; +ProtectHome parse_protect_home_or_bool(const char *s); const char* protect_system_to_string(ProtectSystem p) _const_; ProtectSystem protect_system_from_string(const char *s) _pure_; +ProtectSystem parse_protect_system_or_bool(const char *s); void bind_mount_free_many(BindMount *b, unsigned n); int bind_mount_add(BindMount **b, unsigned *n, const BindMount *item); diff --git a/src/core/path.c b/src/core/path.c index 6b22451a08..8a5ec0a72f 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -772,6 +772,9 @@ const UnitVTable path_vtable = { "Unit\0" "Path\0" "Install\0", + .private_section = "Path", + + .can_transient = true, .init = path_init, .done = path_done, @@ -794,5 +797,6 @@ const UnitVTable path_vtable = { .reset_failed = path_reset_failed, - .bus_vtable = bus_path_vtable + .bus_vtable = bus_path_vtable, + .bus_set_property = bus_path_set_property, }; diff --git a/src/core/scope.c b/src/core/scope.c index 10454d56b0..468dd81217 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -472,19 +472,16 @@ static void scope_notify_cgroup_empty_event(Unit *u) { static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) { - /* If we get a SIGCHLD event for one of the processes we were - interested in, then we look for others to watch, under the - assumption that we'll sooner or later get a SIGCHLD for - them, as the original process we watched was probably the - parent of them, and they are hence now our children. */ + assert(u); + /* If we get a SIGCHLD event for one of the processes we were interested in, then we look for others to + * watch, under the assumption that we'll sooner or later get a SIGCHLD for them, as the original + * process we watched was probably the parent of them, and they are hence now our children. */ unit_tidy_watch_pids(u, 0, 0); unit_watch_all_pids(u); - /* If the PID set is empty now, then let's finish this off - (On unified we use proper notifications) */ - if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids)) - scope_notify_cgroup_empty_event(u); + /* If the PID set is empty now, then let's finish this off. */ + unit_synthesize_cgroup_empty_event(u); } static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) { diff --git a/src/core/service.c b/src/core/service.c index ef1be33260..6476dc68c5 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -866,9 +866,45 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) { cgroup_context_dump(&s->cgroup_context, f, prefix); } +static int service_is_suitable_main_pid(Service *s, pid_t pid, int prio) { + Unit *owner; + + assert(s); + assert(pid_is_valid(pid)); + + /* Checks whether the specified PID is suitable as main PID for this service. returns negative if not, 0 if the + * PID is questionnable but should be accepted if the source of configuration is trusted. > 0 if the PID is + * good */ + + if (pid == getpid_cached() || pid == 1) { + log_unit_full(UNIT(s), prio, 0, "New main PID "PID_FMT" is the manager, refusing.", pid); + return -EPERM; + } + + if (pid == s->control_pid) { + log_unit_full(UNIT(s), prio, 0, "New main PID "PID_FMT" is the control process, refusing.", pid); + return -EPERM; + } + + if (!pid_is_alive(pid)) { + log_unit_full(UNIT(s), prio, 0, "New main PID "PID_FMT" does not exist or is a zombie.", pid); + return -ESRCH; + } + + owner = manager_get_unit_by_pid(UNIT(s)->manager, pid); + if (owner == UNIT(s)) { + log_unit_debug(UNIT(s), "New main PID "PID_FMT" belongs to service, we are happy.", pid); + return 1; /* Yay, it's definitely a good PID */ + } + + return 0; /* Hmm it's a suspicious PID, let's accept it if configuration source is trusted */ +} + static int service_load_pid_file(Service *s, bool may_warn) { + char procfs[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; _cleanup_free_ char *k = NULL; - int r; + _cleanup_close_ int fd = -1; + int r, prio; pid_t pid; assert(s); @@ -876,30 +912,47 @@ static int service_load_pid_file(Service *s, bool may_warn) { if (!s->pid_file) return -ENOENT; - r = read_one_line_file(s->pid_file, &k); - if (r < 0) { - if (may_warn) - log_unit_info_errno(UNIT(s), r, "PID file %s not readable (yet?) after %s: %m", s->pid_file, service_state_to_string(s->state)); - return r; - } + prio = may_warn ? LOG_INFO : LOG_DEBUG; + + fd = chase_symlinks(s->pid_file, NULL, CHASE_OPEN|CHASE_SAFE, NULL); + if (fd == -EPERM) + return log_unit_full(UNIT(s), prio, fd, "Permission denied while opening PID file or unsafe symlink chain: %s", s->pid_file); + if (fd < 0) + return log_unit_full(UNIT(s), prio, fd, "Can't open PID file %s (yet?) after %s: %m", s->pid_file, service_state_to_string(s->state)); + + /* Let's read the PID file now that we chased it down. But we need to convert the O_PATH fd chase_symlinks() returned us into a proper fd first. */ + xsprintf(procfs, "/proc/self/fd/%i", fd); + r = read_one_line_file(procfs, &k); + if (r < 0) + return log_unit_error_errno(UNIT(s), r, "Can't convert PID files %s O_PATH file descriptor to proper file descriptor: %m", s->pid_file); r = parse_pid(k, &pid); - if (r < 0) { - if (may_warn) - log_unit_info_errno(UNIT(s), r, "Failed to read PID from file %s: %m", s->pid_file); + if (r < 0) + return log_unit_full(UNIT(s), prio, r, "Failed to parse PID from file %s: %m", s->pid_file); + + if (s->main_pid_known && pid == s->main_pid) + return 0; + + r = service_is_suitable_main_pid(s, pid, prio); + if (r < 0) return r; - } + if (r == 0) { + struct stat st; - if (!pid_is_alive(pid)) { - if (may_warn) - log_unit_info(UNIT(s), "PID "PID_FMT" read from file %s does not exist or is a zombie.", pid, s->pid_file); - return -ESRCH; + /* Hmm, it's not clear if the new main PID is safe. Let's allow this if the PID file is owned by root */ + + if (fstat(fd, &st) < 0) + return log_unit_error_errno(UNIT(s), errno, "Failed to fstat() PID file O_PATH fd: %m"); + + if (st.st_uid != 0) { + log_unit_error(UNIT(s), "New main PID "PID_FMT" does not belong to service, and PID file is not owned by root. Refusing.", pid); + return -EPERM; + } + + log_unit_debug(UNIT(s), "New main PID "PID_FMT" does not belong to service, but we'll accept it since PID file is owned by root.", pid); } if (s->main_pid_known) { - if (pid == s->main_pid) - return 0; - log_unit_debug(UNIT(s), "Main PID changing: "PID_FMT" -> "PID_FMT, s->main_pid, pid); service_unwatch_main_pid(s); @@ -915,7 +968,7 @@ static int service_load_pid_file(Service *s, bool may_warn) { if (r < 0) /* FIXME: we need to do something here */ return log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" for service: %m", pid); - return 0; + return 1; } static void service_search_main_pid(Service *s) { @@ -1007,26 +1060,6 @@ static void service_set_state(Service *s, ServiceState state) { if (state == SERVICE_EXITED && !MANAGER_IS_RELOADING(UNIT(s)->manager)) unit_prune_cgroup(UNIT(s)); - /* For remain_after_exit services, let's see if we can "release" the - * hold on the console, since unit_notify() only does that in case of - * change of state */ - if (state == SERVICE_EXITED && - s->remain_after_exit && - UNIT(s)->manager->n_on_console > 0) { - - ExecContext *ec; - - ec = unit_get_exec_context(UNIT(s)); - if (ec && exec_context_may_touch_console(ec)) { - Manager *m = UNIT(s)->manager; - - m->n_on_console--; - if (m->n_on_console == 0) - /* unset no_console_output flag, since the console is free */ - m->no_console_output = false; - } - } - if (old_state != state) log_unit_debug(UNIT(s), "Changed %s -> %s", service_state_to_string(old_state), service_state_to_string(state)); @@ -1080,8 +1113,7 @@ static int service_coldplug(Unit *u) { if (s->main_pid > 0 && pid_is_unwaited(s->main_pid) && - ((s->deserialized_state == SERVICE_START && IN_SET(s->type, SERVICE_FORKING, SERVICE_DBUS, SERVICE_ONESHOT, SERVICE_NOTIFY)) || - IN_SET(s->deserialized_state, + (IN_SET(s->deserialized_state, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, @@ -2586,10 +2618,8 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, if (parse_pid(value, &pid) < 0) log_unit_debug(u, "Failed to parse main-pid value: %s", value); - else { - service_set_main_pid(s, pid); - unit_watch_pid(UNIT(s), pid); - } + else + (void) service_set_main_pid(s, pid); } else if (streq(key, "main-pid-known")) { int b; @@ -2960,6 +2990,7 @@ static void service_notify_cgroup_empty_event(Unit *u) { } static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + bool notify_dbus = true; Service *s = SERVICE(u); ServiceResult f; @@ -2981,7 +3012,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { /* Forking services may occasionally move to a new PID. * As long as they update the PID file before exiting the old * PID, they're fine. */ - if (service_load_pid_file(s, false) == 0) + if (service_load_pid_file(s, false) > 0) return; s->main_pid = 0; @@ -3238,23 +3269,21 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { assert_not_reached("Uh, control process died at wrong time."); } } - } + } else /* Neither control nor main PID? If so, don't notify about anything */ + notify_dbus = false; /* Notify clients about changed exit status */ - unit_add_to_dbus_queue(u); + if (notify_dbus) + unit_add_to_dbus_queue(u); - /* We got one SIGCHLD for the service, let's watch all - * processes that are now running of the service, and watch - * that. Among the PIDs we then watch will be children - * reassigned to us, which hopefully allows us to identify - * when all children are gone */ + /* If we get a SIGCHLD event for one of the processes we were interested in, then we look for others to watch, + * under the assumption that we'll sooner or later get a SIGCHLD for them, as the original process we watched + * was probably the parent of them, and they are hence now our children. */ unit_tidy_watch_pids(u, s->main_pid, s->control_pid); unit_watch_all_pids(u); - /* If the PID set is empty now, then let's finish this off - (On unified we use proper notifications) */ - if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids)) - unit_add_to_cgroup_empty_queue(u); + /* If the PID set is empty now, then let's check if the cgroup is empty too and finish off the unit. */ + unit_synthesize_cgroup_empty_event(u); } static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) { @@ -3364,10 +3393,14 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void watchdog_usec = service_get_watchdog_usec(s); - log_unit_error(UNIT(s), "Watchdog timeout (limit %s)!", - format_timespan(t, sizeof(t), watchdog_usec, 1)); + if (UNIT(s)->manager->service_watchdogs) { + log_unit_error(UNIT(s), "Watchdog timeout (limit %s)!", + format_timespan(t, sizeof(t), watchdog_usec, 1)); - service_enter_signal(s, SERVICE_STOP_SIGABRT, SERVICE_FAILURE_WATCHDOG); + service_enter_signal(s, SERVICE_STOP_SIGABRT, SERVICE_FAILURE_WATCHDOG); + } else + log_unit_warning(UNIT(s), "Watchdog disabled! Ignoring watchdog timeout (limit %s)!", + format_timespan(t, sizeof(t), watchdog_usec, 1)); return 0; } @@ -3406,37 +3439,55 @@ static bool service_notify_message_authorized(Service *s, pid_t pid, char **tags return true; } -static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds) { +static void service_notify_message( + Unit *u, + const struct ucred *ucred, + char **tags, + FDSet *fds) { + Service *s = SERVICE(u); bool notify_dbus = false; const char *e; char **i; + int r; assert(u); + assert(ucred); - if (!service_notify_message_authorized(SERVICE(u), pid, tags, fds)) + if (!service_notify_message_authorized(SERVICE(u), ucred->pid, tags, fds)) return; - if (log_get_max_level() >= LOG_DEBUG) { + if (DEBUG_LOGGING) { _cleanup_free_ char *cc = NULL; cc = strv_join(tags, ", "); - log_unit_debug(u, "Got notification message from PID "PID_FMT" (%s)", pid, isempty(cc) ? "n/a" : cc); + log_unit_debug(u, "Got notification message from PID "PID_FMT" (%s)", ucred->pid, isempty(cc) ? "n/a" : cc); } /* Interpret MAINPID= */ e = strv_find_startswith(tags, "MAINPID="); if (e && IN_SET(s->state, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD)) { - if (parse_pid(e, &pid) < 0) - log_unit_warning(u, "Failed to parse MAINPID= field in notification message: %s", e); - else if (pid == s->control_pid) - log_unit_warning(u, "A control process cannot also be the main process"); - else if (pid == getpid_cached() || pid == 1) - log_unit_warning(u, "Service manager can't be main process, ignoring sd_notify() MAINPID= field"); - else if (pid != s->main_pid) { - service_set_main_pid(s, pid); - unit_watch_pid(UNIT(s), pid); - notify_dbus = true; + pid_t new_main_pid; + + if (parse_pid(e, &new_main_pid) < 0) + log_unit_warning(u, "Failed to parse MAINPID= field in notification message, ignoring: %s", e); + else if (!s->main_pid_known || new_main_pid != s->main_pid) { + + r = service_is_suitable_main_pid(s, new_main_pid, LOG_WARNING); + if (r == 0) { + /* The new main PID is a bit suspicous, which is OK if the sender is privileged. */ + + if (ucred->uid == 0) { + log_unit_debug(u, "New main PID "PID_FMT" does not belong to service, but we'll accept it as the request to change it came from a privileged process.", new_main_pid); + r = 1; + } else + log_unit_debug(u, "New main PID "PID_FMT" does not belong to service, refusing.", new_main_pid); + } + if (r > 0) { + service_set_main_pid(s, new_main_pid); + unit_watch_pid(UNIT(s), new_main_pid); + notify_dbus = true; + } } } @@ -3735,6 +3786,32 @@ static int service_control_pid(Unit *u) { return s->control_pid; } +static bool service_needs_console(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + /* We provide our own implementation of this here, instead of relying of the generic implementation + * unit_needs_console() provides, since we want to return false if we are in SERVICE_EXITED state. */ + + if (!exec_context_may_touch_console(&s->exec_context)) + return false; + + return IN_SET(s->state, + SERVICE_START_PRE, + SERVICE_START, + SERVICE_START_POST, + SERVICE_RUNNING, + SERVICE_RELOAD, + SERVICE_STOP, + SERVICE_STOP_SIGABRT, + SERVICE_STOP_SIGTERM, + SERVICE_STOP_SIGKILL, + SERVICE_STOP_POST, + SERVICE_FINAL_SIGTERM, + SERVICE_FINAL_SIGKILL); +} + static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { [SERVICE_RESTART_NO] = "no", [SERVICE_RESTART_ON_SUCCESS] = "on-success", @@ -3850,6 +3927,7 @@ const UnitVTable service_vtable = { .bus_commit_properties = bus_service_commit_properties, .get_timeout = service_get_timeout, + .needs_console = service_needs_console, .can_transient = true, .status_message_formats = { diff --git a/src/core/shutdown.c b/src/core/shutdown.c index aca89d13d1..cc31b33f1c 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -31,10 +31,11 @@ #include <unistd.h> #include "alloc-util.h" +#include "async.h" #include "cgroup-util.h" -#include "fd-util.h" #include "def.h" #include "exec-util.h" +#include "fd-util.h" #include "fileio.h" #include "killall.h" #include "log.h" @@ -57,6 +58,7 @@ static char* arg_verb; static uint8_t arg_exit_code; +static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC; static int parse_argv(int argc, char *argv[]) { enum { @@ -65,6 +67,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_LOG_COLOR, ARG_LOG_LOCATION, ARG_EXIT_CODE, + ARG_TIMEOUT, }; static const struct option options[] = { @@ -73,6 +76,7 @@ static int parse_argv(int argc, char *argv[]) { { "log-color", optional_argument, NULL, ARG_LOG_COLOR }, { "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, { "exit-code", required_argument, NULL, ARG_EXIT_CODE }, + { "timeout", required_argument, NULL, ARG_TIMEOUT }, {} }; @@ -128,6 +132,13 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_TIMEOUT: + r = parse_sec(optarg, &arg_timeout); + if (r < 0) + log_error("Failed to parse shutdown timeout %s, ignoring", optarg); + + break; + case '\001': if (!arg_verb) arg_verb = optarg; @@ -211,26 +222,20 @@ static bool sync_making_progress(unsigned long long *prev_dirty) { } static void sync_with_progress(void) { + unsigned long long dirty = ULONG_LONG_MAX; unsigned checks; pid_t pid; int r; - unsigned long long dirty = ULONG_LONG_MAX; BLOCK_SIGNALS(SIGCHLD); - /* Due to the possiblity of the sync operation hanging, we fork - * a child process and monitor the progress. If the timeout - * lapses, the assumption is that that particular sync stalled. */ - pid = fork(); - if (pid < 0) { - log_error_errno(errno, "Failed to fork: %m"); - return; - } + /* Due to the possiblity of the sync operation hanging, we fork a child process and monitor the progress. If + * the timeout lapses, the assumption is that that particular sync stalled. */ - if (pid == 0) { - /* Start the sync operation here in the child */ - sync(); - _exit(EXIT_SUCCESS); + r = asynchronous_sync(&pid); + if (r < 0) { + log_error_errno(r, "Failed to fork sync(): %m"); + return; } log_info("Syncing filesystems and block devices."); @@ -279,7 +284,7 @@ int main(int argc, char *argv[]) { /* journald will die if not gone yet. The log target defaults * to console, but may have been changed by command line options. */ - log_close_console(); /* force reopen of /dev/console */ + log_set_prohibit_ipc(true); log_open(); umask(0022); @@ -328,11 +333,13 @@ int main(int argc, char *argv[]) { if (!in_container) sync_with_progress(); + disable_coredumps(); + log_info("Sending SIGTERM to remaining processes..."); - broadcast_signal(SIGTERM, true, true); + broadcast_signal(SIGTERM, true, true, arg_timeout); log_info("Sending SIGKILL to remaining processes..."); - broadcast_signal(SIGKILL, true, false); + broadcast_signal(SIGKILL, true, false, arg_timeout); need_umount = !in_container; need_swapoff = !in_container; @@ -488,15 +495,10 @@ int main(int argc, char *argv[]) { if (!in_container) { /* We cheat and exec kexec to avoid doing all its work */ - pid_t pid; - log_info("Rebooting with kexec."); - pid = fork(); - if (pid < 0) - log_error_errno(errno, "Failed to fork: %m"); - else if (pid == 0) { - + r = safe_fork("(sd-kexec)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, NULL); + if (r == 0) { const char * const args[] = { KEXEC, "-e", NULL }; @@ -505,8 +507,9 @@ int main(int argc, char *argv[]) { execv(args[0], (char * const *) args); _exit(EXIT_FAILURE); - } else - wait_for_terminate_and_warn("kexec", pid, true); + } + + /* If we are still running, then the kexec can't have worked, let's fall through */ } cmd = RB_AUTOBOOT; @@ -548,7 +551,7 @@ int main(int argc, char *argv[]) { * CAP_SYS_BOOT just exit, this will kill our * container for good. */ log_info("Exiting container."); - exit(0); + exit(EXIT_SUCCESS); } r = log_error_errno(errno, "Failed to invoke reboot(): %m"); diff --git a/src/core/slice.c b/src/core/slice.c index 5ab1e6f898..fef47b04fe 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -59,30 +59,24 @@ static void slice_set_state(Slice *t, SliceState state) { } static int slice_add_parent_slice(Slice *s) { - char *a, *dash; - Unit *parent; + Unit *u = UNIT(s), *parent; + _cleanup_free_ char *a = NULL; int r; assert(s); - if (UNIT_ISSET(UNIT(s)->slice)) + if (UNIT_ISSET(u->slice)) return 0; - if (unit_has_name(UNIT(s), SPECIAL_ROOT_SLICE)) - return 0; - - a = strdupa(UNIT(s)->id); - dash = strrchr(a, '-'); - if (dash) - strcpy(dash, ".slice"); - else - a = (char*) SPECIAL_ROOT_SLICE; + r = slice_build_parent_slice(u->id, &a); + if (r <= 0) /* 0 means root slice */ + return r; - r = manager_load_unit(UNIT(s)->manager, a, NULL, NULL, &parent); + r = manager_load_unit(u->manager, a, NULL, NULL, &parent); if (r < 0) return r; - unit_ref_set(&UNIT(s)->slice, parent); + unit_ref_set(&u->slice, parent); return 0; } diff --git a/src/core/socket.c b/src/core/socket.c index 7e3630ada7..74cdebbe81 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -53,6 +53,7 @@ #include "signal-util.h" #include "smack-util.h" #include "socket.h" +#include "socket-protocol-list.h" #include "special.h" #include "string-table.h" #include "string-util.h" @@ -655,7 +656,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { SocketExecCommand c; Socket *s = SOCKET(u); SocketPort *p; - const char *prefix2; + const char *prefix2, *str; assert(s); assert(f); @@ -680,7 +681,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { "%sTCPCongestion: %s\n" "%sRemoveOnStop: %s\n" "%sWritable: %s\n" - "%sFDName: %s\n" + "%sFileDescriptorName: %s\n" "%sSELinuxContextFromNet: %s\n", prefix, socket_state_to_string(s->state), prefix, socket_result_to_string(s->result), @@ -715,10 +716,12 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { fprintf(f, "%sAccepted: %u\n" "%sNConnections: %u\n" - "%sMaxConnections: %u\n", + "%sMaxConnections: %u\n" + "%sMaxConnectionsPerSource: %u\n", prefix, s->n_accepted, prefix, s->n_connections, - prefix, s->max_connections); + prefix, s->max_connections, + prefix, s->max_connections_per_source); if (s->priority >= 0) fprintf(f, @@ -843,6 +846,24 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->trigger_limit.interval, USEC_PER_SEC), prefix, s->trigger_limit.burst); + str = socket_protocol_to_name(s->socket_protocol); + if (str) + fprintf(f, "%sSocketProtocol: %s\n", prefix, str); + + if (!strv_isempty(s->symlinks)) { + char **q; + + fprintf(f, "%sSymlinks:", prefix); + STRV_FOREACH(q, s->symlinks) + fprintf(f, " %s", *q); + + fprintf(f, "\n"); + } + + fprintf(f, + "%sTimeoutSec: %s\n", + prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->timeout_usec, USEC_PER_SEC)); + exec_context_dump(&s->exec_context, f, prefix); kill_context_dump(&s->kill_context, f, prefix); @@ -1506,7 +1527,7 @@ static int socket_address_listen_in_cgroup( if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, pair) < 0) return log_unit_error_errno(UNIT(s), errno, "Failed to create communication channel: %m"); - r = unit_fork_helper_process(UNIT(s), &pid); + r = unit_fork_helper_process(UNIT(s), "(sd-listen)", &pid); if (r < 0) return log_unit_error_errno(UNIT(s), r, "Failed to fork off listener stub process: %m"); if (r == 0) { @@ -1533,7 +1554,7 @@ static int socket_address_listen_in_cgroup( fd = receive_one_fd(pair[0], 0); /* We synchronously wait for the helper, as it shouldn't be slow */ - r = wait_for_terminate_and_warn("listen-cgroup-helper", pid, false); + r = wait_for_terminate_and_check("(sd-listen)", pid, WAIT_LOG_ABNORMAL); if (r < 0) { safe_close(fd); return r; @@ -1923,7 +1944,7 @@ static int socket_chown(Socket *s, pid_t *_pid) { /* We have to resolve the user names out-of-process, hence * let's fork here. It's messy, but well, what can we do? */ - r = unit_fork_helper_process(UNIT(s), &pid); + r = unit_fork_helper_process(UNIT(s), "(sd-chown)", &pid); if (r < 0) return r; if (r == 0) { @@ -2780,6 +2801,23 @@ const char* socket_port_type_to_string(SocketPort *p) { } } +SocketType socket_port_type_from_string(const char *s) { + assert(s); + + if (STR_IN_SET(s, "Stream", "Datagram", "SequentialPacket", "Netlink")) + return SOCKET_SOCKET; + else if (streq(s, "Special")) + return SOCKET_SPECIAL; + else if (streq(s, "MessageQueue")) + return SOCKET_MQUEUE; + else if (streq(s, "FIFO")) + return SOCKET_FIFO; + else if (streq(s, "USBFunction")) + return SOCKET_USB_FUNCTION; + else + return _SOCKET_TYPE_INVALID; +} + _pure_ static bool socket_check_gc(Unit *u) { Socket *s = SOCKET(u); @@ -2833,7 +2871,7 @@ static int socket_accept_in_cgroup(Socket *s, SocketPort *p, int fd) { if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, pair) < 0) return log_unit_error_errno(UNIT(s), errno, "Failed to create communication channel: %m"); - r = unit_fork_helper_process(UNIT(s), &pid); + r = unit_fork_helper_process(UNIT(s), "(sd-accept)", &pid); if (r < 0) return log_unit_error_errno(UNIT(s), r, "Failed to fork off accept stub process: %m"); if (r == 0) { @@ -2860,7 +2898,7 @@ static int socket_accept_in_cgroup(Socket *s, SocketPort *p, int fd) { cfd = receive_one_fd(pair[0], 0); /* We synchronously wait for the helper, as it shouldn't be slow */ - r = wait_for_terminate_and_warn("accept-cgroup-helper", pid, false); + r = wait_for_terminate_and_check("(sd-accept)", pid, WAIT_LOG_ABNORMAL); if (r < 0) { safe_close(cfd); return r; @@ -3212,10 +3250,7 @@ char *socket_fdname(Socket *s) { * didn't specify anything specifically, use the socket unit's * name as fallback. */ - if (s->fdname) - return s->fdname; - - return UNIT(s)->id; + return s->fdname ?: UNIT(s)->id; } static int socket_control_pid(Unit *u) { @@ -3227,11 +3262,11 @@ static int socket_control_pid(Unit *u) { } static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { - [SOCKET_EXEC_START_PRE] = "StartPre", - [SOCKET_EXEC_START_CHOWN] = "StartChown", - [SOCKET_EXEC_START_POST] = "StartPost", - [SOCKET_EXEC_STOP_PRE] = "StopPre", - [SOCKET_EXEC_STOP_POST] = "StopPost" + [SOCKET_EXEC_START_PRE] = "ExecStartPre", + [SOCKET_EXEC_START_CHOWN] = "ExecStartChown", + [SOCKET_EXEC_START_POST] = "ExecStartPost", + [SOCKET_EXEC_STOP_PRE] = "ExecStopPre", + [SOCKET_EXEC_STOP_POST] = "ExecStopPost" }; DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand); @@ -3264,6 +3299,8 @@ const UnitVTable socket_vtable = { "Install\0", .private_section = "Socket", + .can_transient = true, + .init = socket_init, .done = socket_done, .load = socket_load, diff --git a/src/core/socket.h b/src/core/socket.h index e9e560e57e..9c528fb39c 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -43,8 +43,8 @@ typedef enum SocketType { SOCKET_SPECIAL, SOCKET_MQUEUE, SOCKET_USB_FUNCTION, - _SOCKET_FIFO_MAX, - _SOCKET_FIFO_INVALID = -1 + _SOCKET_TYPE_MAX, + _SOCKET_TYPE_INVALID = -1 } SocketType; typedef enum SocketResult { @@ -194,3 +194,4 @@ const char* socket_result_to_string(SocketResult i) _const_; SocketResult socket_result_from_string(const char *s) _pure_; const char* socket_port_type_to_string(SocketPort *p) _pure_; +SocketType socket_port_type_from_string(const char *p) _pure_; diff --git a/src/core/swap.c b/src/core/swap.c index 849ccbdd43..70097ff2ba 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -1309,7 +1309,7 @@ static void swap_enumerate(Manager *m) { /* Dispatch this before we dispatch SIGCHLD, so that * we always get the events from /proc/swaps before * the SIGCHLD of /sbin/swapon. */ - r = sd_event_source_set_priority(m->swap_event_source, -10); + r = sd_event_source_set_priority(m->swap_event_source, SD_EVENT_PRIORITY_NORMAL-10); if (r < 0) { log_error_errno(r, "Failed to change /proc/swaps priority: %m"); goto fail; diff --git a/src/core/timer.c b/src/core/timer.c index 03935eea94..133cbb974d 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -431,6 +431,7 @@ static void timer_enter_waiting(Timer *t, bool initial) { if (base <= 0) continue; + base = MAX(base, t->last_trigger.monotonic); break; @@ -443,6 +444,7 @@ static void timer_enter_waiting(Timer *t, bool initial) { if (base <= 0) continue; + base = MAX(base, t->last_trigger.monotonic); break; diff --git a/src/core/umount.c b/src/core/umount.c index 7f8ddb99ee..731436af27 100644 --- a/src/core/umount.c +++ b/src/core/umount.c @@ -28,6 +28,7 @@ #include "libudev.h" #include "alloc-util.h" +#include "blockdev-util.h" #include "def.h" #include "escape.h" #include "fd-util.h" @@ -35,12 +36,13 @@ #include "linux-3.13/dm-ioctl.h" #include "list.h" #include "mount-setup.h" +#include "mount-util.h" #include "path-util.h" +#include "process-util.h" #include "signal-util.h" #include "string-util.h" #include "udev-util.h" #include "umount.h" -#include "mount-util.h" #include "util.h" #include "virt.h" @@ -388,11 +390,10 @@ static int remount_with_timeout(MountPoint *m, char *options, int *n_failed) { * fork a child process and set a timeout. If the timeout * lapses, the assumption is that that particular remount * failed. */ - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - - if (pid == 0) { + r = safe_fork("(sd-remount)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { log_info("Remounting '%s' read-only in with options '%s'.", m->path, options); /* Start the mount operation here in the child */ @@ -423,11 +424,10 @@ static int umount_with_timeout(MountPoint *m, bool *changed) { * fork a child process and set a timeout. If the timeout * lapses, the assumption is that that particular umount * failed. */ - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - - if (pid == 0) { + r = safe_fork("(sd-umount)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { log_info("Unmounting '%s'.", m->path); /* Start the mount operation here in the child Using MNT_FORCE diff --git a/src/core/unit.c b/src/core/unit.c index 7af8425707..932f05baa2 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -21,6 +21,7 @@ #include <errno.h> #include <stdlib.h> #include <string.h> +#include <sys/prctl.h> #include <sys/stat.h> #include <unistd.h> @@ -629,6 +630,9 @@ void unit_free(Unit *u) { if (u->in_cgroup_empty_queue) LIST_REMOVE(cgroup_empty_queue, u->manager->cgroup_empty_queue, u); + if (u->on_console) + manager_unref_console(u->manager); + unit_release_cgroup(u); if (!MANAGER_IS_RELOADING(u->manager)) @@ -2304,6 +2308,23 @@ finish: } +static void unit_update_on_console(Unit *u) { + bool b; + + assert(u); + + b = unit_needs_console(u); + if (u->on_console == b) + return; + + u->on_console = b; + if (b) + manager_ref_console(u->manager); + else + manager_unref_console(u->manager); + +} + void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) { Manager *m; bool unexpected; @@ -2344,24 +2365,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su unit_unlink_state_files(u); } - /* Note that this doesn't apply to RemainAfterExit services exiting - * successfully, since there's no change of state in that case. Which is - * why it is handled in service_set_state() */ - if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) { - ExecContext *ec; - - ec = unit_get_exec_context(u); - if (ec && exec_context_may_touch_console(ec)) { - if (UNIT_IS_INACTIVE_OR_FAILED(ns)) { - m->n_on_console--; - - if (m->n_on_console == 0) - /* unset no_console_output flag, since the console is free */ - m->no_console_output = false; - } else - m->n_on_console++; - } - } + unit_update_on_console(u); if (u->job) { unexpected = false; @@ -2533,44 +2537,97 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su } int unit_watch_pid(Unit *u, pid_t pid) { - int q, r; + int r; assert(u); - assert(pid >= 1); + assert(pid_is_valid(pid)); - /* Watch a specific PID. We only support one or two units - * watching each PID for now, not more. */ + /* Watch a specific PID */ r = set_ensure_allocated(&u->pids, NULL); if (r < 0) return r; - r = hashmap_ensure_allocated(&u->manager->watch_pids1, NULL); + r = hashmap_ensure_allocated(&u->manager->watch_pids, NULL); if (r < 0) return r; - r = hashmap_put(u->manager->watch_pids1, PID_TO_PTR(pid), u); - if (r == -EEXIST) { - r = hashmap_ensure_allocated(&u->manager->watch_pids2, NULL); - if (r < 0) - return r; + /* First try, let's add the unit keyed by "pid". */ + r = hashmap_put(u->manager->watch_pids, PID_TO_PTR(pid), u); + if (r == -EEXIST) { + Unit **array; + bool found = false; + size_t n = 0; - r = hashmap_put(u->manager->watch_pids2, PID_TO_PTR(pid), u); - } + /* OK, the "pid" key is already assigned to a different unit. Let's see if the "-pid" key (which points + * to an array of Units rather than just a Unit), lists us already. */ - q = set_put(u->pids, PID_TO_PTR(pid)); - if (q < 0) - return q; + array = hashmap_get(u->manager->watch_pids, PID_TO_PTR(-pid)); + if (array) + for (; array[n]; n++) + if (array[n] == u) + found = true; - return r; + if (found) /* Found it already? if so, do nothing */ + r = 0; + else { + Unit **new_array; + + /* Allocate a new array */ + new_array = new(Unit*, n + 2); + if (!new_array) + return -ENOMEM; + + memcpy_safe(new_array, array, sizeof(Unit*) * n); + new_array[n] = u; + new_array[n+1] = NULL; + + /* Add or replace the old array */ + r = hashmap_replace(u->manager->watch_pids, PID_TO_PTR(-pid), new_array); + if (r < 0) { + free(new_array); + return r; + } + + free(array); + } + } else if (r < 0) + return r; + + r = set_put(u->pids, PID_TO_PTR(pid)); + if (r < 0) + return r; + + return 0; } void unit_unwatch_pid(Unit *u, pid_t pid) { + Unit **array; + assert(u); - assert(pid >= 1); + assert(pid_is_valid(pid)); + + /* First let's drop the unit in case it's keyed as "pid". */ + (void) hashmap_remove_value(u->manager->watch_pids, PID_TO_PTR(pid), u); + + /* Then, let's also drop the unit, in case it's in the array keyed by -pid */ + array = hashmap_get(u->manager->watch_pids, PID_TO_PTR(-pid)); + if (array) { + size_t n, m = 0; + + /* Let's iterate through the array, dropping our own entry */ + for (n = 0; array[n]; n++) + if (array[n] != u) + array[m++] = array[n]; + array[m] = NULL; + + if (m == 0) { + /* The array is now empty, remove the entire entry */ + assert(hashmap_remove(u->manager->watch_pids, PID_TO_PTR(-pid)) == array); + free(array); + } + } - (void) hashmap_remove_value(u->manager->watch_pids1, PID_TO_PTR(pid), u); - (void) hashmap_remove_value(u->manager->watch_pids2, PID_TO_PTR(pid), u); (void) set_remove(u->pids, PID_TO_PTR(pid)); } @@ -3041,7 +3098,7 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) { "member='NameOwnerChanged'," "arg0='", name, "'"); - return sd_bus_add_match(bus, &u->match_bus_slot, match, signal_name_owner_changed, u); + return sd_bus_add_match_async(bus, &u->match_bus_slot, match, signal_name_owner_changed, NULL, u); } int unit_watch_bus_name(Unit *u, const char *name) { @@ -4704,25 +4761,29 @@ void unit_warn_if_dir_nonempty(Unit *u, const char* where) { NULL); } -int unit_fail_if_symlink(Unit *u, const char* where) { +int unit_fail_if_noncanonical(Unit *u, const char* where) { + _cleanup_free_ char *canonical_where; int r; assert(u); assert(where); - r = is_symlink(where); + r = chase_symlinks(where, NULL, CHASE_NONEXISTENT, &canonical_where); if (r < 0) { - log_unit_debug_errno(u, r, "Failed to check symlink %s, ignoring: %m", where); + log_unit_debug_errno(u, r, "Failed to check %s for symlinks, ignoring: %m", where); return 0; } - if (r == 0) + + /* We will happily ignore a trailing slash (or any redundant slashes) */ + if (path_equal(where, canonical_where)) return 0; + /* No need to mention "." or "..", they would already have been rejected by unit_name_from_path() */ log_struct(LOG_ERR, "MESSAGE_ID=" SD_MESSAGE_OVERMOUNTING_STR, LOG_UNIT_ID(u), LOG_UNIT_INVOCATION_ID(u), - LOG_UNIT_MESSAGE(u, "Mount on symlink %s not allowed.", where), + LOG_UNIT_MESSAGE(u, "Mount path %s is not canonical (contains a symlink).", where), "WHERE=%s", where, NULL); @@ -4968,8 +5029,7 @@ void unit_set_exec_params(Unit *u, ExecParameters *p) { SET_FLAG(p->flags, EXEC_CGROUP_DELEGATE, UNIT_CGROUP_BOOL(u, delegate)); } -int unit_fork_helper_process(Unit *u, pid_t *ret) { - pid_t pid; +int unit_fork_helper_process(Unit *u, const char *name, pid_t *ret) { int r; assert(u); @@ -4980,32 +5040,24 @@ int unit_fork_helper_process(Unit *u, pid_t *ret) { (void) unit_realize_cgroup(u); - pid = fork(); - if (pid < 0) - return -errno; - - if (pid == 0) { + r = safe_fork(name, FORK_REOPEN_LOG, ret); + if (r != 0) + return r; - (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); - (void) ignore_signals(SIGPIPE, -1); + (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); + (void) ignore_signals(SIGPIPE, -1); - log_close(); - log_open(); + (void) prctl(PR_SET_PDEATHSIG, SIGTERM); - if (u->cgroup_path) { - r = cg_attach_everywhere(u->manager->cgroup_supported, u->cgroup_path, 0, NULL, NULL); - if (r < 0) { - log_unit_error_errno(u, r, "Failed to join unit cgroup %s: %m", u->cgroup_path); - _exit(EXIT_CGROUP); - } + if (u->cgroup_path) { + r = cg_attach_everywhere(u->manager->cgroup_supported, u->cgroup_path, 0, NULL, NULL); + if (r < 0) { + log_unit_error_errno(u, r, "Failed to join unit cgroup %s: %m", u->cgroup_path); + _exit(EXIT_CGROUP); } - - *ret = getpid_cached(); - return 0; } - *ret = pid; - return 1; + return 0; } static void unit_update_dependency_mask(Unit *u, UnitDependency d, Unit *other, UnitDependencyInfo di) { @@ -5301,6 +5353,28 @@ void unit_warn_leftover_processes(Unit *u) { (void) cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0, 0, NULL, log_leftover, u); } +bool unit_needs_console(Unit *u) { + ExecContext *ec; + UnitActiveState state; + + assert(u); + + state = unit_active_state(u); + + if (UNIT_IS_INACTIVE_OR_FAILED(state)) + return false; + + if (UNIT_VTABLE(u)->needs_console) + return UNIT_VTABLE(u)->needs_console(u); + + /* If this unit type doesn't implement this call, let's use a generic fallback implementation: */ + ec = unit_get_exec_context(u); + if (!ec) + return false; + + return exec_context_may_touch_console(ec); +} + static const char* const collect_mode_table[_COLLECT_MODE_MAX] = { [COLLECT_INACTIVE] = "inactive", [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed", diff --git a/src/core/unit.h b/src/core/unit.h index fdd82315ba..8c79d4ed2e 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -236,8 +236,10 @@ struct Unit { * process SIGCHLD for */ Set *pids; - /* Used in sigchld event invocation to avoid repeat events being invoked */ - uint64_t sigchldgen; + /* Used in SIGCHLD and sd_notify() message event invocation logic to avoid that we dispatch the same event + * multiple times on the same unit. */ + unsigned sigchldgen; + unsigned notifygen; /* Used during GC sweeps */ unsigned gc_marker; @@ -338,6 +340,7 @@ struct Unit { bool sent_dbus_new_signal:1; bool in_audit:1; + bool on_console:1; bool cgroup_realized:1; bool cgroup_members_mask_valid:1; @@ -506,7 +509,7 @@ struct UnitVTable { void (*notify_cgroup_empty)(Unit *u); /* Called whenever a process of this unit sends us a message */ - void (*notify_message)(Unit *u, pid_t pid, char **tags, FDSet *fds); + void (*notify_message)(Unit *u, const struct ucred *ucred, char **tags, FDSet *fds); /* Called whenever a name this Unit registered for comes or goes away. */ void (*bus_name_owner_change)(Unit *u, const char *name, const char *old_owner, const char *new_owner); @@ -539,6 +542,9 @@ struct UnitVTable { /* Returns the main PID if there is any defined, or 0. */ pid_t (*control_pid)(Unit *u); + /* Returns true if the unit currently needs access to the console */ + bool (*needs_console)(Unit *u); + /* This is called for each unit type and should be used to * enumerate existing devices and load them. However, * everything that is loaded here should still stay in @@ -760,7 +766,7 @@ static inline bool unit_supported(Unit *u) { } void unit_warn_if_dir_nonempty(Unit *u, const char* where); -int unit_fail_if_symlink(Unit *u, const char* where); +int unit_fail_if_noncanonical(Unit *u, const char* where); int unit_start_limit_test(Unit *u); @@ -782,7 +788,7 @@ bool unit_shall_confirm_spawn(Unit *u); void unit_set_exec_params(Unit *s, ExecParameters *p); -int unit_fork_helper_process(Unit *u, pid_t *ret); +int unit_fork_helper_process(Unit *u, const char *name, pid_t *ret); void unit_remove_dependencies(Unit *u, UnitDependencyMask mask); @@ -793,6 +799,8 @@ int unit_prepare_exec(Unit *u); void unit_warn_leftover_processes(Unit *u); +bool unit_needs_console(Unit *u); + /* Macros which append UNIT= or USER_UNIT= to the message */ #define log_unit_full(unit, level, error, ...) \ diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index e6063cc980..fdcea22f56 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -1126,7 +1126,7 @@ static int gather_pid_metadata( /* If this is PID 1 disable coredump collection, we'll unlikely be able to process it later on. */ if (is_pid1_crash((const char**) context)) { log_notice("Due to PID 1 having crashed coredump collection will now be turned off."); - (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0); + disable_coredumps(); } set_iovec_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]); diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index 0d420b2190..96e4a3e7e2 100644 --- a/src/coredump/coredumpctl.c +++ b/src/coredump/coredumpctl.c @@ -885,7 +885,6 @@ static int run_gdb(sd_journal *j) { _cleanup_free_ char *exe = NULL, *path = NULL; bool unlink_path = false; const char *data; - siginfo_t st; size_t len; pid_t pid; int r; @@ -928,28 +927,16 @@ static int run_gdb(sd_journal *j) { /* Don't interfere with gdb and its handling of SIGINT. */ (void) ignore_signals(SIGINT, -1); - pid = fork(); - if (pid < 0) { - r = log_error_errno(errno, "Failed to fork(): %m"); + r = safe_fork("(gdb)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); + if (r < 0) goto finish; - } - if (pid == 0) { - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - + if (r == 0) { execlp("gdb", "gdb", exe, path, NULL); - log_error_errno(errno, "Failed to invoke gdb: %m"); - _exit(1); - } - - r = wait_for_terminate(pid, &st); - if (r < 0) { - log_error_errno(r, "Failed to wait for gdb: %m"); - goto finish; + _exit(EXIT_FAILURE); } - r = st.si_code == CLD_EXITED ? st.si_status : 255; + r = wait_for_terminate_and_check("gdb", pid, WAIT_LOG_ABNORMAL); finish: (void) default_signals(SIGINT, -1); @@ -1061,7 +1048,7 @@ int main(int argc, char *argv[]) { if (r < 0) goto end; - if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) { + if (DEBUG_LOGGING) { _cleanup_free_ char *filter; filter = journal_make_match_string(j); diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index 7e61332e52..acde2a6a32 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -61,7 +61,7 @@ static int create_disk( const char *password, const char *options) { - _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *e = NULL, + _cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL, *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL; _cleanup_fclose_ FILE *f = NULL; const char *dmname; @@ -90,18 +90,14 @@ static int create_disk( if (!e) return log_oom(); - r = unit_name_build("systemd-cryptsetup", e, ".service", &n); - if (r < 0) - return log_error_errno(r, "Failed to generate unit name: %m"); - - p = strjoin(arg_dest, "/", n); - if (!p) - return log_oom(); - u = fstab_node_to_udev_node(device); if (!u) return log_oom(); + r = unit_name_build("systemd-cryptsetup", e, ".service", &n); + if (r < 0) + return log_error_errno(r, "Failed to generate unit name: %m"); + u_escaped = specifier_escape(u); if (!u_escaped) return log_oom(); @@ -110,18 +106,17 @@ static int create_disk( if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); - password_escaped = specifier_escape(password); - if (!password_escaped) - return log_oom(); - - f = fopen(p, "wxe"); - if (!f) - return log_error_errno(errno, "Failed to create unit file %s: %m", p); + if (password) { + password_escaped = specifier_escape(password); + if (!password_escaped) + return log_oom(); + } - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = generator_open_unit_file(arg_dest, NULL, n, &f); + if (r < 0) + return r; fprintf(f, - "# Automatically generated by systemd-cryptsetup-generator\n\n" "[Unit]\n" "Description=Cryptography Setup for %%I\n" "Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n" @@ -183,9 +178,11 @@ static int create_disk( if (r < 0) return r; - filtered_escaped = specifier_escape(filtered); - if (!filtered_escaped) - return log_oom(); + if (filtered) { + filtered_escaped = specifier_escape(filtered); + if (!filtered_escaped) + return log_oom(); + } fprintf(f, "\n[Service]\n" @@ -210,7 +207,7 @@ static int create_disk( r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write file %s: %m", p); + return log_error_errno(r, "Failed to write unit file %s: %m", n); if (!noauto) { r = generator_add_symlink(arg_dest, d, "wants", n); @@ -475,7 +472,8 @@ int main(int argc, char *argv[]) { if (argc > 1) arg_dest = argv[1]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 21c51022ef..7255ff418c 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -47,7 +47,7 @@ static char *arg_cipher = NULL; static unsigned arg_key_size = 0; static int arg_key_slot = CRYPT_ANY_SLOT; static unsigned arg_keyfile_size = 0; -static unsigned arg_keyfile_offset = 0; +static uint64_t arg_keyfile_offset = 0; static char *arg_hash = NULL; static char *arg_header = NULL; static unsigned arg_tries = 3; @@ -131,13 +131,22 @@ static int parse_one_option(const char *option) { } } else if ((val = startswith(option, "keyfile-offset="))) { + uint64_t off; - r = safe_atou(val, &arg_keyfile_offset); + r = safe_atou64(val, &off); if (r < 0) { log_error_errno(r, "Failed to parse %s, ignoring: %m", option); return 0; } + if ((size_t) off != off) { + /* https://gitlab.com/cryptsetup/cryptsetup/issues/359 */ + log_error("keyfile-offset= value would truncated to %zu, ignoring.", (size_t) off); + return 0; + } + + arg_keyfile_offset = off; + } else if ((val = startswith(option, "hash="))) { r = free_and_strdup(&arg_hash, val); if (r < 0) diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c index 604faa0d18..61c890d05a 100644 --- a/src/debug-generator/debug-generator.c +++ b/src/debug-generator/debug-generator.c @@ -165,7 +165,8 @@ int main(int argc, char *argv[]) { if (argc > 1) arg_dest = argv[2]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); diff --git a/src/delta/delta.c b/src/delta/delta.c index d286881698..645b0b2278 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -161,8 +161,8 @@ static int notify_override_unchanged(const char *f) { static int found_override(const char *top, const char *bottom) { _cleanup_free_ char *dest = NULL; - int k; pid_t pid; + int r; assert(top); assert(bottom); @@ -170,40 +170,35 @@ static int found_override(const char *top, const char *bottom) { if (null_or_empty_path(top) > 0) return notify_override_masked(top, bottom); - k = readlink_malloc(top, &dest); - if (k >= 0) { + r = readlink_malloc(top, &dest); + if (r >= 0) { if (equivalent(dest, bottom) > 0) return notify_override_equivalent(top, bottom); else return notify_override_redirected(top, bottom); } - k = notify_override_overridden(top, bottom); + r = notify_override_overridden(top, bottom); if (!arg_diff) - return k; + return r; putchar('\n'); fflush(stdout); - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork off diff: %m"); - else if (pid == 0) { - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - + r = safe_fork("(diff)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { execlp("diff", "diff", "-us", "--", bottom, top, NULL); log_error_errno(errno, "Failed to execute diff: %m"); _exit(EXIT_FAILURE); } - wait_for_terminate_and_warn("diff", pid, false); + (void) wait_for_terminate_and_check("diff", pid, WAIT_LOG_ABNORMAL); putchar('\n'); - return k; + return r; } static int enumerate_dir_d( @@ -392,19 +387,28 @@ static int enumerate_dir( return 0; } -static int should_skip_prefix(const char* p) { +static bool should_skip_path(const char *prefix, const char *suffix) { #if HAVE_SPLIT_USR - int r; _cleanup_free_ char *target = NULL; + const char *p; + char *dirname; - r = chase_symlinks(p, NULL, 0, &target); - if (r < 0) - return r; + dirname = strjoina(prefix, "/", suffix); - return !streq(p, target) && nulstr_contains(prefixes, target); -#else - return 0; + if (chase_symlinks(dirname, NULL, 0, &target) < 0) + return false; + + NULSTR_FOREACH(p, prefixes) { + if (path_startswith(dirname, p)) + continue; + + if (path_equal(target, strjoina(p, "/", suffix))) { + log_debug("%s redirects to %s, skipping.", dirname, target); + return true; + } + } #endif + return false; } static int process_suffix(const char *suffix, const char *onlyprefix) { @@ -434,14 +438,8 @@ static int process_suffix(const char *suffix, const char *onlyprefix) { NULSTR_FOREACH(p, prefixes) { _cleanup_free_ char *t = NULL; - int skip; - skip = should_skip_prefix(p); - if (skip < 0) { - r = skip; - goto finish; - } - if (skip) + if (should_skip_path(p, suffix)) continue; t = strjoin(p, "/", suffix); @@ -520,19 +518,12 @@ static int process_suffix_chop(const char *arg) { /* Strip prefix from the suffix */ NULSTR_FOREACH(p, prefixes) { const char *suffix; - int skip; - - skip = should_skip_prefix(p); - if (skip < 0) - return skip; - if (skip) - continue; suffix = startswith(arg, p); if (suffix) { suffix += strspn(suffix, "/"); if (*suffix) - return process_suffix(suffix, NULL); + return process_suffix(suffix, p); else return process_suffixes(arg); } diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index 207ddeb70f..262e520d56 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -23,6 +23,21 @@ #include <shadow.h> #include <unistd.h> +#ifdef HAVE_CRYPT_H +/* libxcrypt is a replacement for glibc's libcrypt, and libcrypt might be + * removed from glibc at some point. As part of the removal, defines for + * crypt(3) are dropped from unistd.h, and we must include crypt.h instead. + * + * Newer versions of glibc (v2.0+) already ship crypt.h with a definition + * of crypt(3) as well, so we simply include it if it is present. MariaDB, + * MySQL, PostgreSQL, Perl and some other wide-spread packages do it the + * same way since ages without any problems. + */ +# include <crypt.h> +#endif + +#include "sd-id128.h" + #include "alloc-util.h" #include "ask-password-api.h" #include "copy.h" diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 0091e388dc..97d824aca4 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -284,9 +284,8 @@ int main(int argc, char *argv[]) { _cleanup_(sd_device_unrefp) sd_device *dev = NULL; const char *device, *type; bool root_directory; - siginfo_t status; struct stat st; - int r; + int r, exit_status; pid_t pid; if (argc > 2) { @@ -392,12 +391,10 @@ int main(int argc, char *argv[]) { } } - pid = fork(); - if (pid < 0) { - r = log_error_errno(errno, "fork(): %m"); + r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (r < 0) goto finish; - } - if (pid == 0) { + if (r == 0) { char dash_c[STRLEN("-C") + DECIMAL_STR_MAX(int) + 1]; int progress_socket = -1; const char *cmdline[9]; @@ -405,10 +402,6 @@ int main(int argc, char *argv[]) { /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - /* Close the reading side of the progress pipe */ progress_pipe[0] = safe_close(progress_pipe[0]); @@ -455,38 +448,30 @@ int main(int argc, char *argv[]) { (void) process_progress(progress_pipe[0]); progress_pipe[0] = -1; - r = wait_for_terminate(pid, &status); - if (r < 0) { - log_error_errno(r, "waitid(): %m"); + exit_status = wait_for_terminate_and_check("fsck", pid, WAIT_LOG_ABNORMAL); + if (exit_status < 0) { + r = exit_status; goto finish; } + if (exit_status & ~1) { + log_error("fsck failed with exit status %i.", exit_status); - if (status.si_code != CLD_EXITED || (status.si_status & ~1)) { - - if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED)) - log_error("fsck terminated by signal %s.", signal_to_string(status.si_status)); - else if (status.si_code == CLD_EXITED) - log_error("fsck failed with error code %i.", status.si_status); - else - log_error("fsck failed due to unknown reason."); - - r = -EINVAL; - - if (status.si_code == CLD_EXITED && (status.si_status & FSCK_SYSTEM_SHOULD_REBOOT) && root_directory) + if ((exit_status & FSCK_SYSTEM_SHOULD_REBOOT) && root_directory) { /* System should be rebooted. */ start_target(SPECIAL_REBOOT_TARGET, "replace-irreversibly"); - else if (status.si_code == CLD_EXITED && (status.si_status & (FSCK_SYSTEM_SHOULD_REBOOT | FSCK_ERRORS_LEFT_UNCORRECTED))) + r = -EINVAL; + } else if (exit_status & (FSCK_SYSTEM_SHOULD_REBOOT | FSCK_ERRORS_LEFT_UNCORRECTED)) { /* Some other problem */ start_target(SPECIAL_EMERGENCY_TARGET, "replace"); - else { + r = -EINVAL; + } else { log_warning("Ignoring error."); r = 0; } - } else r = 0; - if (status.si_code == CLD_EXITED && (status.si_status & FSCK_ERROR_CORRECTED)) + if (exit_status & FSCK_ERROR_CORRECTED) (void) touch("/run/systemd/quotacheck"); finish: diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 22c4ae9861..f392f89099 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -102,7 +102,7 @@ static int add_swap( struct mntent *me, MountpointFlags flags) { - _cleanup_free_ char *name = NULL, *unit = NULL; + _cleanup_free_ char *name = NULL; _cleanup_fclose_ FILE *f = NULL; int r; @@ -123,19 +123,9 @@ static int add_swap( if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); - unit = strjoin(arg_dest, "/", name); - if (!unit) - return log_oom(); - - f = fopen(unit, "wxe"); - if (!f) - return log_error_errno(errno, - errno == EEXIST ? - "Failed to create swap unit file %s, as it already exists. Duplicate entry in /etc/fstab?" : - "Failed to create unit file %s: %m", - unit); - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = generator_open_unit_file(arg_dest, "/etc/fstab", name, &f); + if (r < 0) + return r; fputs("# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" @@ -153,7 +143,7 @@ static int add_swap( r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write unit file %s: %m", unit); + return log_error_errno(r, "Failed to write unit file %s: %m", name); /* use what as where, to have a nicer error message */ r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL); @@ -323,10 +313,9 @@ static int add_mount( _cleanup_free_ char *name = NULL, - *automount_name = NULL, *automount_unit = NULL, + *automount_name = NULL, *filtered = NULL, *where_escaped = NULL; - const char *unit; _cleanup_fclose_ FILE *f = NULL; int r; @@ -363,20 +352,11 @@ static int add_mount( if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); - unit = strjoina(dest, "/", name); - - f = fopen(unit, "wxe"); - if (!f) - return log_error_errno(errno, - errno == EEXIST ? - "Failed to create mount unit file %s, as it already exists. Duplicate entry in /etc/fstab?" : - "Failed to create unit file %s: %m", - unit); - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = generator_open_unit_file(dest, "/etc/fstab", name, &f); + if (r < 0) + return r; fprintf(f, - "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=%s\n" "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n", @@ -461,7 +441,7 @@ static int add_mount( r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write unit file %s: %m", unit); + return log_error_errno(r, "Failed to write unit file %s: %m", name); if (flags & MAKEFS) { r = generator_hook_up_mkfs(dest, what, where, fstype); @@ -487,19 +467,13 @@ static int add_mount( if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); - automount_unit = strjoin(dest, "/", automount_name); - if (!automount_unit) - return log_oom(); - fclose(f); - f = fopen(automount_unit, "wxe"); - if (!f) - return log_error_errno(errno, "Failed to create unit file %s: %m", automount_unit); - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = generator_open_unit_file(dest, "/etc/fstab", automount_name, &f); + if (r < 0) + return r; fprintf(f, - "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=%s\n" "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n", @@ -534,7 +508,7 @@ static int add_mount( r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write unit file %s: %m", automount_unit); + return log_error_errno(r, "Failed to write unit file %s: %m", automount_name); r = generator_add_symlink(dest, post, (flags & NOFAIL) ? "wants" : "requires", automount_name); @@ -917,7 +891,8 @@ int main(int argc, char *argv[]) { if (argc > 3) arg_dest_late = argv[3]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); diff --git a/src/fuzz/fuzz-dhcp-server.c b/src/fuzz/fuzz-dhcp-server.c new file mode 100644 index 0000000000..ba903c7158 --- /dev/null +++ b/src/fuzz/fuzz-dhcp-server.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright 2018 Jonathan Rudenberg + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "fuzz.h" + +#include "sd-dhcp-server.c" + +/* stub out network so that the server doesn't send */ +ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { + return len; +} + +ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) { + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL; + struct in_addr address = {.s_addr = htobe32(UINT32_C(10) << 24 | UINT32_C(1))}; + static const uint8_t chaddr[] = {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3}; + uint8_t *client_id; + DHCPLease *lease; + int pool_offset; + + if (size < sizeof(DHCPMessage)) + return 0; + + assert_se(sd_dhcp_server_new(&server, 1) >= 0); + server->fd = open("/dev/null", O_RDWR|O_CLOEXEC|O_NOCTTY); + assert_se(server->fd >= 0); + assert_se(sd_dhcp_server_configure_pool(server, &address, 24, 0, 0) >= 0); + + /* add a lease to the pool to expose additional code paths */ + client_id = malloc(2); + assert_se(client_id); + client_id[0] = 2; + client_id[1] = 2; + lease = new0(DHCPLease, 1); + assert_se(lease); + lease->client_id.length = 2; + lease->client_id.data = client_id; + lease->address = htobe32(UINT32_C(10) << 24 | UINT32_C(2)); + lease->gateway = htobe32(UINT32_C(10) << 24 | UINT32_C(1)); + lease->expiration = UINT64_MAX; + memcpy(lease->chaddr, chaddr, 16); + pool_offset = get_pool_offset(server, lease->address); + server->bound_leases[pool_offset] = lease; + assert_se(hashmap_put(server->leases_by_client_id, &lease->client_id, lease) >= 0); + + (void) dhcp_server_handle_message(server, (DHCPMessage*)data, size); + + return 0; +} diff --git a/src/fuzz/fuzz-dns-packet.c b/src/fuzz/fuzz-dns-packet.c new file mode 100644 index 0000000000..0f25081b22 --- /dev/null +++ b/src/fuzz/fuzz-dns-packet.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright 2018 Jonathan Rudenberg + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "fuzz.h" +#include "resolved-dns-packet.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; + + if (size > DNS_PACKET_SIZE_MAX) + return 0; + + assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, 0, DNS_PACKET_SIZE_MAX) >= 0); + p->size = 0; /* by default append starts after the header, undo that */ + assert_se(dns_packet_append_blob(p, data, size, NULL) >= 0); + if (size < DNS_PACKET_HEADER_SIZE) { + /* make sure we pad the packet back up to the minimum header size */ + assert_se(p->allocated >= DNS_PACKET_HEADER_SIZE); + memzero(DNS_PACKET_DATA(p) + size, DNS_PACKET_HEADER_SIZE - size); + p->size = DNS_PACKET_HEADER_SIZE; + } + (void) dns_packet_extract(p); + + return 0; +} diff --git a/src/fuzz/fuzz-dns-packet.options b/src/fuzz/fuzz-dns-packet.options new file mode 100644 index 0000000000..0824b19fab --- /dev/null +++ b/src/fuzz/fuzz-dns-packet.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/src/fuzz/fuzz-dns-server.options b/src/fuzz/fuzz-dns-server.options new file mode 100644 index 0000000000..5c330e5cec --- /dev/null +++ b/src/fuzz/fuzz-dns-server.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 600 diff --git a/src/fuzz/fuzz-main.c b/src/fuzz/fuzz-main.c new file mode 100644 index 0000000000..45e46907e2 --- /dev/null +++ b/src/fuzz/fuzz-main.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright 2018 Jonathan Rudenberg + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "alloc-util.h" +#include "log.h" +#include "fileio.h" +#include "fuzz.h" + +/* This is a test driver for the systemd fuzzers that provides main function + * for regression testing outside of oss-fuzz (https://github.com/google/oss-fuzz) + * + * It reads files named on the command line and passes them one by one into the + * fuzzer that it is compiled into. */ + +int main(int argc, char **argv) { + int i, r; + size_t size; + char *name; + + log_set_max_level(LOG_DEBUG); + for (i = 1; i < argc; i++) { + _cleanup_free_ char *buf = NULL; + + name = argv[i]; + r = read_full_file(name, &buf, &size); + if (r < 0) { + log_error_errno(r, "Failed to open '%s': %m", name); + return EXIT_FAILURE; + } + printf("%s... ", name); + fflush(stdout); + (void) LLVMFuzzerTestOneInput((uint8_t*)buf, size); + printf("ok\n"); + } + return EXIT_SUCCESS; +} diff --git a/src/fuzz/fuzz.h b/src/fuzz/fuzz.h new file mode 100644 index 0000000000..5293c5762f --- /dev/null +++ b/src/fuzz/fuzz.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright 2018 Jonathan Rudenberg + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <stddef.h> +#include <stdint.h> + +/* The entry point into the fuzzer */ +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build new file mode 100644 index 0000000000..09a8c8a11d --- /dev/null +++ b/src/fuzz/meson.build @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# Copyright 2018 Jonathan Rudenberg +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see <http://www.gnu.org/licenses/>. + +fuzzers += [ + [['src/fuzz/fuzz-dns-packet.c', + dns_type_headers], + [libsystemd_resolve_core, + libshared], + [libgcrypt, + libgpg_error, + libm]], + [['src/fuzz/fuzz-dhcp-server.c', + ], + [libsystemd_network, + libshared], + []] +] diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c index 3f62a81abc..f475aef66c 100644 --- a/src/getty-generator/getty-generator.c +++ b/src/getty-generator/getty-generator.c @@ -138,7 +138,8 @@ int main(int argc, char *argv[]) { if (argc > 1) arg_dest = argv[1]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 9e8b956d5c..cbdbc5afe2 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -28,6 +28,7 @@ #include "alloc-util.h" #include "blkid-util.h" +#include "blockdev-util.h" #include "btrfs-util.h" #include "dirent-util.h" #include "dissect-image.h" @@ -712,7 +713,8 @@ int main(int argc, char *argv[]) { if (argc > 1) arg_dest = argv[3]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); diff --git a/src/hibernate-resume/hibernate-resume-generator.c b/src/hibernate-resume/hibernate-resume-generator.c index 01222db516..a81386ef63 100644 --- a/src/hibernate-resume/hibernate-resume-generator.c +++ b/src/hibernate-resume/hibernate-resume-generator.c @@ -86,7 +86,8 @@ int main(int argc, char *argv[]) { if (argc > 1) arg_dest = argv[1]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 5feaa60c99..1c8c76934c 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -680,9 +680,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { if (r < 0) return log_error_errno(r, "Failed to register object: %m"); - r = sd_bus_request_name(bus, "org.freedesktop.hostname1", 0); + r = sd_bus_request_name_async(bus, NULL, "org.freedesktop.hostname1", 0, NULL, NULL); if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); + return log_error_errno(r, "Failed to request name: %m"); r = sd_bus_attach_event(bus, event, 0); if (r < 0) diff --git a/src/import/curl-util.c b/src/import/curl-util.c index 7069c95a9f..62bbaa500d 100644 --- a/src/import/curl-util.c +++ b/src/import/curl-util.c @@ -21,6 +21,7 @@ #include "alloc-util.h" #include "curl-util.h" #include "fd-util.h" +#include "locale-util.h" #include "string-util.h" static void curl_glue_check_finished(CurlGlue *g) { @@ -414,8 +415,8 @@ int curl_header_strdup(const void *contents, size_t sz, const char *field, char } int curl_parse_http_time(const char *t, usec_t *ret) { + _cleanup_(freelocalep) locale_t loc = (locale_t) 0; const char *e; - locale_t loc; struct tm tm; time_t v; @@ -434,7 +435,6 @@ int curl_parse_http_time(const char *t, usec_t *ret) { if (!e || *e != 0) /* ANSI C */ e = strptime_l(t, "%a %b %d %H:%M:%S %Y", &tm, loc); - freelocale(loc); if (!e || *e != 0) return -EINVAL; diff --git a/src/import/export.c b/src/import/export.c index 753d1399f5..0f32b90051 100644 --- a/src/import/export.c +++ b/src/import/export.c @@ -21,6 +21,7 @@ #include <getopt.h> #include "sd-event.h" +#include "sd-id128.h" #include "alloc-util.h" #include "export-raw.h" diff --git a/src/import/import-common.c b/src/import/import-common.c index 2f989a171c..c24a0b0c86 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -27,6 +27,7 @@ #include "capability-util.h" #include "fd-util.h" #include "import-common.h" +#include "process-util.h" #include "signal-util.h" #include "util.h" @@ -82,11 +83,10 @@ int import_fork_tar_x(const char *path, pid_t *ret) { if (pipe2(pipefd, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to create pipe for tar: %m"); - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork off tar: %m"); - - if (pid == 0) { + r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { int null_fd; uint64_t retain = (1ULL << CAP_CHOWN) | @@ -98,10 +98,6 @@ int import_fork_tar_x(const char *path, pid_t *ret) { /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - pipefd[1] = safe_close(pipefd[1]); r = move_fd(pipefd[0], STDIN_FILENO, false); @@ -156,20 +152,15 @@ int import_fork_tar_c(const char *path, pid_t *ret) { if (pipe2(pipefd, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to create pipe for tar: %m"); - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork off tar: %m"); - - if (pid == 0) { + r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { int null_fd; uint64_t retain = (1ULL << CAP_DAC_OVERRIDE); /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - pipefd[0] = safe_close(pipefd[0]); r = move_fd(pipefd[1], STDOUT_FILENO, false); diff --git a/src/import/import-compress.c b/src/import/import-compress.c index cb5b9821c3..acb47fef14 100644 --- a/src/import/import-compress.c +++ b/src/import/import-compress.c @@ -70,7 +70,7 @@ int import_uncompress_detect(ImportCompress *c, const void *data, size_t size) { if (memcmp(data, xz_signature, sizeof(xz_signature)) == 0) { lzma_ret xzr; - xzr = lzma_stream_decoder(&c->xz, UINT64_MAX, LZMA_TELL_UNSUPPORTED_CHECK); + xzr = lzma_stream_decoder(&c->xz, UINT64_MAX, LZMA_TELL_UNSUPPORTED_CHECK | LZMA_CONCATENATED); if (xzr != LZMA_OK) return -EIO; diff --git a/src/import/import-tar.c b/src/import/import-tar.c index c5014499ac..09c7654adc 100644 --- a/src/import/import-tar.c +++ b/src/import/import-tar.c @@ -190,7 +190,7 @@ static int tar_import_finish(TarImport *i) { i->tar_fd = safe_close(i->tar_fd); if (i->tar_pid > 0) { - r = wait_for_terminate_and_warn("tar", i->tar_pid, true); + r = wait_for_terminate_and_check("tar", i->tar_pid, WAIT_LOG); i->tar_pid = 0; if (r < 0) return r; diff --git a/src/import/import.c b/src/import/import.c index cc454ee15b..454e64e3cb 100644 --- a/src/import/import.c +++ b/src/import/import.c @@ -21,6 +21,7 @@ #include <getopt.h> #include "sd-event.h" +#include "sd-id128.h" #include "alloc-util.h" #include "fd-util.h" diff --git a/src/import/importd.c b/src/import/importd.c index 9c7694c0ad..98ee1a2fab 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -371,10 +371,10 @@ static int transfer_start(Transfer *t) { if (pipe2(pipefd, O_CLOEXEC) < 0) return -errno; - t->pid = fork(); - if (t->pid < 0) - return -errno; - if (t->pid == 0) { + r = safe_fork("(sd-transfer)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &t->pid); + if (r < 0) + return r; + if (r == 0) { const char *cmd[] = { NULL, /* systemd-import, systemd-export or systemd-pull */ NULL, /* tar, raw */ @@ -393,10 +393,6 @@ static int transfer_start(Transfer *t) { /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - pipefd[0] = safe_close(pipefd[0]); if (dup2(pipefd[1], STDERR_FILENO) != STDERR_FILENO) { @@ -1153,9 +1149,9 @@ static int manager_add_bus_objects(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to add transfer enumerator: %m"); - r = sd_bus_request_name(m->bus, "org.freedesktop.import1", 0); + r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.import1", 0, NULL, NULL); if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); + return log_error_errno(r, "Failed to request name: %m"); r = sd_bus_attach_event(m->bus, m->event, 0); if (r < 0) diff --git a/src/import/pull-common.c b/src/import/pull-common.c index c2a3a6aa8b..ecdcbd2dc2 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -463,10 +463,10 @@ int pull_verify(PullJob *main_job, gpg_home_created = true; - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork off gpg: %m"); - if (pid == 0) { + r = safe_fork("(gpg)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { const char *cmd[] = { "gpg", "--no-options", @@ -487,10 +487,6 @@ int pull_verify(PullJob *main_job, /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - gpg_pipe[1] = safe_close(gpg_pipe[1]); r = move_fd(gpg_pipe[0], STDIN_FILENO, false); @@ -546,11 +542,11 @@ int pull_verify(PullJob *main_job, gpg_pipe[1] = safe_close(gpg_pipe[1]); - r = wait_for_terminate_and_warn("gpg", pid, true); + r = wait_for_terminate_and_check("gpg", pid, WAIT_LOG_ABNORMAL); pid = 0; if (r < 0) goto finish; - if (r > 0) { + if (r != EXIT_SUCCESS) { log_error("DOWNLOAD INVALID: Signature verification failed."); r = -EBADMSG; } else { diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c index ed91511245..6ee63bdad5 100644 --- a/src/import/pull-tar.c +++ b/src/import/pull-tar.c @@ -333,11 +333,11 @@ static void tar_pull_job_on_finished(PullJob *j) { goto finish; if (i->tar_pid > 0) { - r = wait_for_terminate_and_warn("tar", i->tar_pid, true); + r = wait_for_terminate_and_check("tar", i->tar_pid, WAIT_LOG); i->tar_pid = 0; if (r < 0) goto finish; - if (r > 0) { + if (r != EXIT_SUCCESS) { r = -EIO; goto finish; } diff --git a/src/import/pull.c b/src/import/pull.c index 46e0fd5acb..325f7e3d50 100644 --- a/src/import/pull.c +++ b/src/import/pull.c @@ -21,6 +21,7 @@ #include <getopt.h> #include "sd-event.h" +#include "sd-id128.h" #include "alloc-util.h" #include "hostname-util.h" diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c index 5488999727..c1af13d15b 100644 --- a/src/initctl/initctl.c +++ b/src/initctl/initctl.c @@ -38,6 +38,7 @@ #include "log.h" #include "special.h" #include "util.h" +#include "process-util.h" #define SERVER_FD_MAX 16 #define TIMEOUT_MSEC ((int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)) diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c index 82c70cfbe3..5a437ce031 100644 --- a/src/journal-remote/journal-gatewayd.c +++ b/src/journal-remote/journal-gatewayd.c @@ -226,7 +226,8 @@ static ssize_t request_reader_entries( return MHD_CONTENT_READER_END_WITH_ERROR; } - r = output_journal(m->tmp, m->journal, m->mode, 0, OUTPUT_FULL_WIDTH, NULL, NULL); + r = output_journal(m->tmp, m->journal, m->mode, 0, OUTPUT_FULL_WIDTH, + NULL, NULL, NULL); if (r < 0) { log_error_errno(r, "Failed to serialize item: %m"); return MHD_CONTENT_READER_END_WITH_ERROR; diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index e44989e1ba..66d5369a54 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -43,6 +43,7 @@ #include "journald-native.h" #include "macro.h" #include "parse-util.h" +#include "process-util.h" #include "signal-util.h" #include "socket-util.h" #include "stat-util.h" @@ -81,27 +82,20 @@ static bool arg_trust_all = false; **********************************************************************/ static int spawn_child(const char* child, char** argv) { - int fd[2]; - pid_t parent_pid, child_pid; - int r; + pid_t child_pid; + int fd[2], r; if (pipe(fd) < 0) return log_error_errno(errno, "Failed to create pager pipe: %m"); - parent_pid = getpid_cached(); - - child_pid = fork(); - if (child_pid < 0) { - r = log_error_errno(errno, "Failed to fork: %m"); + r = safe_fork("(remote)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &child_pid); + if (r < 0) { safe_close_pair(fd); return r; } /* In the child */ - if (child_pid == 0) { - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); + if (r == 0) { r = dup2(fd[1], STDOUT_FILENO); if (r < 0) { @@ -111,15 +105,6 @@ static int spawn_child(const char* child, char** argv) { safe_close_pair(fd); - /* Make sure the child goes away when the parent dies */ - if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) - _exit(EXIT_FAILURE); - - /* Check whether our parent died before we were able - * to set the death signal */ - if (getppid() != parent_pid) - _exit(EXIT_SUCCESS); - execvp(child, argv); log_error_errno(errno, "Failed to exec child %s: %m", child); _exit(EXIT_FAILURE); diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c index 69718aae87..0b74ca98a7 100644 --- a/src/journal-remote/journal-upload.c +++ b/src/journal-remote/journal-upload.c @@ -37,6 +37,7 @@ #include "log.h" #include "mkdir.h" #include "parse-util.h" +#include "process-util.h" #include "sigbus.h" #include "signal-util.h" #include "string-util.h" @@ -248,7 +249,7 @@ int start_upload(Uploader *u, easy_setopt(curl, CURLOPT_HTTPHEADER, u->header, LOG_ERR, return -EXFULL); - if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) + if (DEBUG_LOGGING) /* enable verbose for easier tracing */ easy_setopt(curl, CURLOPT_VERBOSE, 1L, LOG_WARNING, ); diff --git a/src/journal/generate-audit_type-list.sh b/src/journal/generate-audit_type-list.sh index 18cbe0599c..2445a02668 100755 --- a/src/journal/generate-audit_type-list.sh +++ b/src/journal/generate-audit_type-list.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu cpp="$1" shift diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 7fef403391..3353b3a0d8 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -147,6 +147,8 @@ static void journal_file_set_offline_internal(JournalFile *f) { static void * journal_file_set_offline_thread(void *arg) { JournalFile *f = arg; + (void) pthread_setname_np(pthread_self(), "journal-offline"); + journal_file_set_offline_internal(f); return NULL; @@ -245,11 +247,25 @@ int journal_file_set_offline(JournalFile *f, bool wait) { if (wait) /* Without using a thread if waiting. */ journal_file_set_offline_internal(f); else { + sigset_t ss, saved_ss; + int k; + + if (sigfillset(&ss) < 0) + return -errno; + + r = pthread_sigmask(SIG_BLOCK, &ss, &saved_ss); + if (r > 0) + return -r; + r = pthread_create(&f->offline_thread, NULL, journal_file_set_offline_thread, f); + + k = pthread_sigmask(SIG_SETMASK, &saved_ss, NULL); if (r > 0) { f->offline_state = OFFLINE_JOINED; return -r; } + if (k > 0) + return -k; } return 0; @@ -3237,11 +3253,8 @@ int journal_file_open( if (!IN_SET((flags & O_ACCMODE), O_RDONLY, O_RDWR)) return -EINVAL; - if (fname) { - if (!endswith(fname, ".journal") && - !endswith(fname, ".journal~")) - return -EINVAL; - } + if (fname && (flags & O_CREAT) && !endswith(fname, ".journal")) + return -EINVAL; f = new0(JournalFile, 1); if (!f) diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index a78aa07032..73329ba024 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -416,10 +416,9 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve if (shutdown(fd, SHUT_RD) < 0) return -errno; - fd_inc_sndbuf(fd, SNDBUF_SIZE); + (void) fd_inc_sndbuf(fd, SNDBUF_SIZE); - if (!identifier) - identifier = ""; + identifier = strempty(identifier); l = strlen(identifier); header = alloca(l + 1 + 1 + 2 + 2 + 2 + 2 + 2); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 956d85aff2..17782688d9 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -34,6 +34,11 @@ #include <sys/stat.h> #include <unistd.h> +#if HAVE_PCRE2 +# define PCRE2_CODE_UNIT_WIDTH 8 +# include <pcre2.h> +#endif + #include "sd-bus.h" #include "sd-journal.h" @@ -76,6 +81,34 @@ #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE) +#if HAVE_PCRE2 +DEFINE_TRIVIAL_CLEANUP_FUNC(pcre2_match_data*, pcre2_match_data_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(pcre2_code*, pcre2_code_free); + +static int pattern_compile(const char *pattern, unsigned flags, pcre2_code **out) { + int errorcode, r; + PCRE2_SIZE erroroffset; + pcre2_code *p; + + p = pcre2_compile((PCRE2_SPTR8) pattern, + PCRE2_ZERO_TERMINATED, flags, &errorcode, &erroroffset, NULL); + if (!p) { + unsigned char buf[LINE_MAX]; + + r = pcre2_get_error_message(errorcode, buf, sizeof buf); + + log_error("Bad pattern \"%s\": %s", + pattern, + r < 0 ? "unknown error" : (char*) buf); + return -EINVAL; + } + + *out = p; + return 0; +} + +#endif + enum { /* Special values for arg_lines */ ARG_LINES_DEFAULT = -2, @@ -126,6 +159,12 @@ static uint64_t arg_vacuum_n_files = 0; static usec_t arg_vacuum_time = 0; static char **arg_output_fields = NULL; +#if HAVE_PCRE2 +static const char *arg_pattern = NULL; +static pcre2_code *arg_compiled_pattern = NULL; +static int arg_case_sensitive = -1; /* -1 means be smart */ +#endif + static enum { ACTION_SHOW, ACTION_NEW_ID128, @@ -280,67 +319,69 @@ static void help(void) { printf("%s [OPTIONS...] [MATCHES...]\n\n" "Query the journal.\n\n" "Options:\n" - " --system Show the system journal\n" - " --user Show the user journal for the current user\n" - " -M --machine=CONTAINER Operate on local container\n" - " -S --since=DATE Show entries not older than the specified date\n" - " -U --until=DATE Show entries not newer than the specified date\n" - " -c --cursor=CURSOR Show entries starting at the specified cursor\n" - " --after-cursor=CURSOR Show entries after the specified cursor\n" - " --show-cursor Print the cursor after all the entries\n" - " -b --boot[=ID] Show current boot or the specified boot\n" - " --list-boots Show terse information about recorded boots\n" - " -k --dmesg Show kernel message log from the current boot\n" - " -u --unit=UNIT Show logs from the specified unit\n" - " --user-unit=UNIT Show logs from the specified user unit\n" - " -t --identifier=STRING Show entries with the specified syslog identifier\n" - " -p --priority=RANGE Show entries with the specified priority\n" - " -e --pager-end Immediately jump to the end in the pager\n" - " -f --follow Follow the journal\n" - " -n --lines[=INTEGER] Number of journal entries to show\n" - " --no-tail Show all lines, even in follow mode\n" - " -r --reverse Show the newest entries first\n" - " -o --output=STRING Change journal output mode (short, short-precise,\n" - " short-iso, short-iso-precise, short-full,\n" - " short-monotonic, short-unix, verbose, export,\n" - " json, json-pretty, json-sse, cat)\n" - " --output-fields=LIST Select fields to print in verbose/export/json modes\n" - " --utc Express time in Coordinated Universal Time (UTC)\n" - " -x --catalog Add message explanations where available\n" - " --no-full Ellipsize fields\n" - " -a --all Show all fields, including long and unprintable\n" - " -q --quiet Do not show info messages and privilege warning\n" - " --no-pager Do not pipe output into a pager\n" - " --no-hostname Suppress output of hostname field\n" - " -m --merge Show entries from all available journals\n" - " -D --directory=PATH Show journal files from directory\n" - " --file=PATH Show journal file\n" - " --root=ROOT Operate on files below a root directory\n" + " --system Show the system journal\n" + " --user Show the user journal for the current user\n" + " -M --machine=CONTAINER Operate on local container\n" + " -S --since=DATE Show entries not older than the specified date\n" + " -U --until=DATE Show entries not newer than the specified date\n" + " -c --cursor=CURSOR Show entries starting at the specified cursor\n" + " --after-cursor=CURSOR Show entries after the specified cursor\n" + " --show-cursor Print the cursor after all the entries\n" + " -b --boot[=ID] Show current boot or the specified boot\n" + " --list-boots Show terse information about recorded boots\n" + " -k --dmesg Show kernel message log from the current boot\n" + " -u --unit=UNIT Show logs from the specified unit\n" + " --user-unit=UNIT Show logs from the specified user unit\n" + " -t --identifier=STRING Show entries with the specified syslog identifier\n" + " -p --priority=RANGE Show entries with the specified priority\n" + " -g --grep=PATTERN Show entries with MESSSAGE matching PATTERN\n" + " --case-sensitive[=BOOL] Force case sensitive or insenstive matching\n" + " -e --pager-end Immediately jump to the end in the pager\n" + " -f --follow Follow the journal\n" + " -n --lines[=INTEGER] Number of journal entries to show\n" + " --no-tail Show all lines, even in follow mode\n" + " -r --reverse Show the newest entries first\n" + " -o --output=STRING Change journal output mode (short, short-precise,\n" + " short-iso, short-iso-precise, short-full,\n" + " short-monotonic, short-unix, verbose, export,\n" + " json, json-pretty, json-sse, cat)\n" + " --output-fields=LIST Select fields to print in verbose/export/json modes\n" + " --utc Express time in Coordinated Universal Time (UTC)\n" + " -x --catalog Add message explanations where available\n" + " --no-full Ellipsize fields\n" + " -a --all Show all fields, including long and unprintable\n" + " -q --quiet Do not show info messages and privilege warning\n" + " --no-pager Do not pipe output into a pager\n" + " --no-hostname Suppress output of hostname field\n" + " -m --merge Show entries from all available journals\n" + " -D --directory=PATH Show journal files from directory\n" + " --file=PATH Show journal file\n" + " --root=ROOT Operate on files below a root directory\n" #if HAVE_GCRYPT - " --interval=TIME Time interval for changing the FSS sealing key\n" - " --verify-key=KEY Specify FSS verification key\n" - " --force Override of the FSS key pair with --setup-keys\n" + " --interval=TIME Time interval for changing the FSS sealing key\n" + " --verify-key=KEY Specify FSS verification key\n" + " --force Override of the FSS key pair with --setup-keys\n" #endif "\nCommands:\n" - " -h --help Show this help text\n" - " --version Show package version\n" - " -N --fields List all field names currently used\n" - " -F --field=FIELD List all values that a specified field takes\n" - " --disk-usage Show total disk usage of all journal files\n" - " --vacuum-size=BYTES Reduce disk usage below specified size\n" - " --vacuum-files=INT Leave only the specified number of journal files\n" - " --vacuum-time=TIME Remove journal files older than specified time\n" - " --verify Verify journal file consistency\n" - " --sync Synchronize unwritten journal messages to disk\n" - " --flush Flush all journal data from /run into /var\n" - " --rotate Request immediate rotation of the journal files\n" - " --header Show journal header information\n" - " --list-catalog Show all message IDs in the catalog\n" - " --dump-catalog Show entries in the message catalog\n" - " --update-catalog Update the message catalog database\n" - " --new-id128 Generate a new 128-bit ID\n" + " -h --help Show this help text\n" + " --version Show package version\n" + " -N --fields List all field names currently used\n" + " -F --field=FIELD List all values that a specified field takes\n" + " --disk-usage Show total disk usage of all journal files\n" + " --vacuum-size=BYTES Reduce disk usage below specified size\n" + " --vacuum-files=INT Leave only the specified number of journal files\n" + " --vacuum-time=TIME Remove journal files older than specified time\n" + " --verify Verify journal file consistency\n" + " --sync Synchronize unwritten journal messages to disk\n" + " --flush Flush all journal data from /run into /var\n" + " --rotate Request immediate rotation of the journal files\n" + " --header Show journal header information\n" + " --list-catalog Show all message IDs in the catalog\n" + " --dump-catalog Show entries in the message catalog\n" + " --update-catalog Update the message catalog database\n" + " --new-id128 Generate a new 128-bit ID\n" #if HAVE_GCRYPT - " --setup-keys Generate a new FSS key pair\n" + " --setup-keys Generate a new FSS key pair\n" #endif , program_invocation_short_name); } @@ -372,6 +413,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_DUMP_CATALOG, ARG_UPDATE_CATALOG, ARG_FORCE, + ARG_CASE_SENSITIVE, ARG_UTC, ARG_SYNC, ARG_FLUSH, @@ -411,6 +453,8 @@ static int parse_argv(int argc, char *argv[]) { { "header", no_argument, NULL, ARG_HEADER }, { "identifier", required_argument, NULL, 't' }, { "priority", required_argument, NULL, 'p' }, + { "grep", required_argument, NULL, 'g' }, + { "case-sensitive", optional_argument, NULL, ARG_CASE_SENSITIVE }, { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS }, { "interval", required_argument, NULL, ARG_INTERVAL }, { "verify", no_argument, NULL, ARG_VERIFY }, @@ -762,6 +806,27 @@ static int parse_argv(int argc, char *argv[]) { break; } +#if HAVE_PCRE2 + case 'g': + arg_pattern = optarg; + break; + + case ARG_CASE_SENSITIVE: + if (optarg) { + r = parse_boolean(optarg); + if (r < 0) + return log_error_errno(r, "Bad --case-sensitive= argument \"%s\": %m", optarg); + arg_case_sensitive = r; + } else + arg_case_sensitive = true; + + break; +#else + case 'g': + case ARG_CASE_SENSITIVE: + return log_error("Compiled without pattern matching support"); +#endif + case 'S': r = parse_timestamp(optarg, &arg_since); if (r < 0) { @@ -917,6 +982,42 @@ static int parse_argv(int argc, char *argv[]) { arg_system_units = strv_free(arg_system_units); } + +#if HAVE_PCRE2 + if (arg_pattern) { + unsigned flags; + + if (arg_case_sensitive >= 0) + flags = !arg_case_sensitive * PCRE2_CASELESS; + else { + _cleanup_(pcre2_match_data_freep) pcre2_match_data *md = NULL; + bool has_case; + _cleanup_(pcre2_code_freep) pcre2_code *cs = NULL; + + md = pcre2_match_data_create(1, NULL); + if (!md) + return log_oom(); + + r = pattern_compile("[[:upper:]]", 0, &cs); + if (r < 0) + return r; + + r = pcre2_match(cs, (PCRE2_SPTR8) arg_pattern, PCRE2_ZERO_TERMINATED, 0, 0, md, NULL); + has_case = r >= 0; + + flags = !has_case * PCRE2_CASELESS; + } + + log_debug("Doing case %s matching based on %s", + flags & PCRE2_CASELESS ? "insensitive" : "sensitive", + arg_case_sensitive >= 0 ? "request" : "pattern casing"); + + r = pattern_compile(arg_pattern, flags, &arg_compiled_pattern); + if (r < 0) + return r; + } +#endif + return 1; } @@ -2257,7 +2358,7 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; - if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) { + if (DEBUG_LOGGING) { _cleanup_free_ char *filter; filter = journal_make_match_string(j); @@ -2415,6 +2516,7 @@ int main(int argc, char *argv[]) { for (;;) { while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) { int flags; + size_t highlight[2] = {}; if (need_seek) { if (!arg_reverse) @@ -2468,6 +2570,58 @@ int main(int argc, char *argv[]) { } } +#if HAVE_PCRE2 + if (arg_compiled_pattern) { + _cleanup_(pcre2_match_data_freep) pcre2_match_data *md = NULL; + const void *message; + size_t len; + PCRE2_SIZE *ovec; + + md = pcre2_match_data_create(1, NULL); + if (!md) + return log_oom(); + + r = sd_journal_get_data(j, "MESSAGE", &message, &len); + if (r < 0) { + if (r == -ENOENT) { + need_seek = true; + continue; + } + + log_error_errno(r, "Failed to get MESSAGE field: %m"); + goto finish; + } + + assert_se(message = startswith(message, "MESSAGE=")); + + r = pcre2_match(arg_compiled_pattern, + message, + len - strlen("MESSAGE="), + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + md, + NULL); + if (r == PCRE2_ERROR_NOMATCH) { + need_seek = true; + continue; + } + if (r < 0) { + unsigned char buf[LINE_MAX]; + int r2; + + r2 = pcre2_get_error_message(r, buf, sizeof buf); + log_error("Pattern matching failed: %s", + r2 < 0 ? "unknown error" : (char*) buf); + r = -EINVAL; + goto finish; + } + + ovec = pcre2_get_ovector_pointer(md); + highlight[0] = ovec[0]; + highlight[1] = ovec[1]; + } +#endif + flags = arg_all * OUTPUT_SHOW_ALL | arg_full * OUTPUT_FULL_WIDTH | @@ -2476,7 +2630,8 @@ int main(int argc, char *argv[]) { arg_utc * OUTPUT_UTC | arg_no_hostname * OUTPUT_NO_HOSTNAME; - r = output_journal(stdout, j, arg_output, 0, flags, arg_output_fields, &ellipsized); + r = output_journal(stdout, j, arg_output, 0, flags, + arg_output_fields, highlight, &ellipsized); need_seek = true; if (r == -EADDRNOTAVAIL) break; @@ -2527,5 +2682,10 @@ finish: free(arg_root); free(arg_verify_key); +#if HAVE_PCRE2 + if (arg_compiled_pattern) + pcre2_code_free(arg_compiled_pattern); +#endif + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c index 65fb6ab63a..cee873215d 100644 --- a/src/journal/journald-native.c +++ b/src/journal/journald-native.c @@ -425,7 +425,7 @@ void server_process_native_file( * https://github.com/systemd/systemd/issues/1822 */ if (vfs.f_flag & ST_MANDLOCK) { - log_error("Received file descriptor from file system with mandatory locking enable, refusing."); + log_error("Received file descriptor from file system with mandatory locking enabled, refusing."); return; } diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 48375f9c3e..5cd58e8a77 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -133,7 +133,7 @@ static int determine_path_usage(Server *s, const char *path, uint64_t *ret_used, } static void cache_space_invalidate(JournalStorageSpace *space) { - memset(space, 0, sizeof(*space)); + zero(*space); } static int cache_space_refresh(Server *s, JournalStorage *storage) { @@ -241,6 +241,13 @@ void server_space_usage_message(Server *s, JournalStorage *storage) { NULL); } +static bool uid_for_system_journal(uid_t uid) { + + /* Returns true if the specified UID shall get its data stored in the system journal*/ + + return uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY; +} + static void server_add_acls(JournalFile *f, uid_t uid) { #if HAVE_ACL int r; @@ -248,7 +255,7 @@ static void server_add_acls(JournalFile *f, uid_t uid) { assert(f); #if HAVE_ACL - if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY) + if (uid_for_system_journal(uid)) return; r = add_acls_for_user(f->fd, uid); @@ -406,7 +413,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) { if (s->runtime_journal) return s->runtime_journal; - if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY) + if (uid_for_system_journal(uid)) return s->system_journal; r = sd_id128_get_machine(&machine); @@ -457,13 +464,14 @@ static int do_rotate( return -EINVAL; r = journal_file_rotate(f, s->compress, seal, s->deferred_closes); - if (r < 0) + if (r < 0) { if (*f) - log_error_errno(r, "Failed to rotate %s: %m", (*f)->path); + return log_error_errno(r, "Failed to rotate %s: %m", (*f)->path); else - log_error_errno(r, "Failed to create new %s journal: %m", name); - else - server_add_acls(*f, uid); + return log_error_errno(r, "Failed to create new %s journal: %m", name); + } + + server_add_acls(*f, uid); return r; } @@ -1489,7 +1497,8 @@ static int server_open_hostname(Server *s) { assert(s); - s->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY); + s->hostname_fd = open("/proc/sys/kernel/hostname", + O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); if (s->hostname_fd < 0) return log_error_errno(errno, "Failed to open /proc/sys/kernel/hostname: %m"); diff --git a/src/journal/journald.c b/src/journal/journald.c index 6d670e2f4f..10a6955769 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -28,6 +28,7 @@ #include "journald-kmsg.h" #include "journald-server.h" #include "journald-syslog.h" +#include "process-util.h" #include "sigbus.h" int main(int argc, char *argv[]) { @@ -39,7 +40,8 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_set_facility(LOG_SYSLOG); log_parse_environment(); log_open(); diff --git a/src/journal/meson.build b/src/journal/meson.build index edb2a1a30e..a23f6a712c 100644 --- a/src/journal/meson.build +++ b/src/journal/meson.build @@ -15,7 +15,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with systemd; If not, see <http://www.gnu.org/licenses/>. -journal_internal_sources = files(''' +journal_client_sources = files(''' audit-type.c audit-type.h catalog.c @@ -38,14 +38,12 @@ journal_internal_sources = files(''' '''.split()) if conf.get('HAVE_GCRYPT') == 1 - journal_internal_sources += files(''' + journal_client_sources += files(''' journal-authenticate.c journal-authenticate.h fsprg.c fsprg.h '''.split()) - - journal_internal_sources += gcrypt_util_sources endif ############################################################ @@ -71,7 +69,13 @@ audit_type_to_name = custom_target( command : [awk, '-f', '@INPUT0@', '@INPUT1@'], capture : true) -journal_internal_sources += [audit_type_to_name] +journal_client_sources += [audit_type_to_name] + +libjournal_client = static_library( + 'journal-client', + journal_client_sources, + include_directories : includes, + c_args : ['-fvisibility=default']) ############################################################ diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 8a1b161d8f..6da7bf8e81 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -48,6 +48,7 @@ #include "lookup3.h" #include "missing.h" #include "path-util.h" +#include "process-util.h" #include "replace-var.h" #include "stat-util.h" #include "stdio-util.h" diff --git a/src/journal/test-compress-benchmark.c b/src/journal/test-compress-benchmark.c index 409a876054..1f77197549 100644 --- a/src/journal/test-compress-benchmark.c +++ b/src/journal/test-compress-benchmark.c @@ -23,6 +23,7 @@ #include "env-util.h" #include "macro.h" #include "parse-util.h" +#include "process-util.h" #include "random-util.h" #include "string-util.h" #include "util.h" diff --git a/src/libsystemd-network/arp-util.c b/src/libsystemd-network/arp-util.c index 67409cc918..89e68c7ac7 100644 --- a/src/libsystemd-network/arp-util.c +++ b/src/libsystemd-network/arp-util.c @@ -24,6 +24,7 @@ #include "arp-util.h" #include "fd-util.h" +#include "unaligned.h" #include "util.h" int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) { @@ -48,12 +49,12 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 1, 0), /* protocol == reply ? */ BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ /* Sender Hardware Address must be different from our own */ - BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((uint32_t *) eth_mac))), /* A <- 4 bytes of client's MAC */ + BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_ne32(ð_mac->ether_addr_octet[0])),/* A <- 4 bytes of client's MAC */ BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_sha)), /* A <- 4 bytes of SHA */ BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 6), /* A == 0 ? */ - BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((uint16_t *) (((char *) eth_mac) + 4)))), /* A <- remainder of client's MAC */ + BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_ne16(ð_mac->ether_addr_octet[4])),/* A <- remainder of client's MAC */ BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, arp_sha) + 4), /* A <- remainder of SHA */ BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index ac5cc47efd..65c182f48b 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -34,6 +34,8 @@ struct sd_dhcp_route { struct in_addr dst_addr; struct in_addr gw_addr; unsigned char dst_prefixlen; + + uint8_t option; }; struct sd_dhcp_raw_option { diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c index 010090aef1..602bf08a60 100644 --- a/src/libsystemd-network/dhcp-network.c +++ b/src/libsystemd-network/dhcp-network.c @@ -32,6 +32,7 @@ #include "dhcp-internal.h" #include "fd-util.h" #include "socket-util.h" +#include "unaligned.h" static int _bind_raw_socket(int ifindex, union sockaddr_union *link, uint32_t xid, const uint8_t *mac_addr, @@ -70,13 +71,13 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link, BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), /* client identifier == xid ? */ BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ - BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) eth_mac))), /* A <- 4 bytes of client's MAC */ + BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_be32(ð_mac->ether_addr_octet[0])), /* A <- 4 bytes of client's MAC */ BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */ BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */ BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ - BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) (((char *) eth_mac) + 4)))), /* A <- remainder of client's MAC */ + BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_be16(ð_mac->ether_addr_octet[4])), /* A <- remainder of client's MAC */ BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4), /* A <- remainder of MAC from dhcp.chaddr */ BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h index cb5b359cbe..13844a86c6 100644 --- a/src/libsystemd-network/dhcp6-internal.h +++ b/src/libsystemd-network/dhcp6-internal.h @@ -29,25 +29,65 @@ #include "macro.h" #include "sparse-endian.h" +/* Common option header */ +typedef struct DHCP6Option { + be16_t code; + be16_t len; + uint8_t data[]; +} _packed_ DHCP6Option; + +/* Address option */ +struct iaaddr { + struct in6_addr address; + be32_t lifetime_preferred; + be32_t lifetime_valid; +} _packed_; + +/* Prefix Delegation Prefix option */ +struct iapdprefix { + be32_t lifetime_preferred; + be32_t lifetime_valid; + uint8_t prefixlen; + struct in6_addr address; +} _packed_; + typedef struct DHCP6Address DHCP6Address; struct DHCP6Address { LIST_FIELDS(DHCP6Address, addresses); - struct { - struct in6_addr address; - be32_t lifetime_preferred; - be32_t lifetime_valid; - } iaaddr _packed_; + union { + struct iaaddr iaaddr; + struct iapdprefix iapdprefix; + }; }; +/* Non-temporary Address option */ +struct ia_na { + be32_t id; + be32_t lifetime_t1; + be32_t lifetime_t2; +} _packed_; + +/* Prefix Delegation option */ +struct ia_pd { + be32_t id; + be32_t lifetime_t1; + be32_t lifetime_t2; +} _packed_; + +/* Temporary Address option */ +struct ia_ta { + be32_t id; +} _packed_; + struct DHCP6IA { uint16_t type; - struct { - be32_t id; - be32_t lifetime_t1; - be32_t lifetime_t2; - } _packed_; + union { + struct ia_na ia_na; + struct ia_pd ia_pd; + struct ia_ta ia_ta; + }; sd_event_source *timeout_t1; sd_event_source *timeout_t2; @@ -62,11 +102,12 @@ typedef struct DHCP6IA DHCP6IA; int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, size_t optlen, const void *optval); int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia); +int dhcp6_option_append_pd(uint8_t *buf, size_t len, DHCP6IA *pd); int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn); int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen, uint8_t **optvalue); -int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, - DHCP6IA *ia); +int dhcp6_option_parse_status(DHCP6Option *option); +int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia); int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen, struct in6_addr **addrs, size_t count, size_t *allocated); diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h index a3f00d4a5d..45e0e82427 100644 --- a/src/libsystemd-network/dhcp6-lease-internal.h +++ b/src/libsystemd-network/dhcp6-lease-internal.h @@ -36,8 +36,10 @@ struct sd_dhcp6_lease { bool rapid_commit; DHCP6IA ia; + DHCP6IA pd; DHCP6Address *addr_iter; + DHCP6Address *prefix_iter; struct in6_addr *dns; size_t dns_count; diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c index f346bda5fc..df96ad739d 100644 --- a/src/libsystemd-network/dhcp6-option.c +++ b/src/libsystemd-network/dhcp6-option.c @@ -26,6 +26,7 @@ #include "alloc-util.h" #include "dhcp6-internal.h" +#include "dhcp6-lease-internal.h" #include "dhcp6-protocol.h" #include "dns-domain.h" #include "sparse-endian.h" @@ -33,14 +34,27 @@ #include "unaligned.h" #include "util.h" -#define DHCP6_OPTION_IA_NA_LEN 12 -#define DHCP6_OPTION_IA_TA_LEN 4 +typedef struct DHCP6StatusOption { + struct DHCP6Option option; + be16_t status; + char msg[]; +} _packed_ DHCP6StatusOption; -typedef struct DHCP6Option { - be16_t code; - be16_t len; - uint8_t data[]; -} _packed_ DHCP6Option; +typedef struct DHCP6AddressOption { + struct DHCP6Option option; + struct iaaddr iaaddr; + uint8_t options[]; +} _packed_ DHCP6AddressOption; + +typedef struct DHCP6PDPrefixOption { + struct DHCP6Option option; + struct iapdprefix iapdprefix; + uint8_t options[]; +} _packed_ DHCP6PDPrefixOption; + +#define DHCP6_OPTION_IA_NA_LEN (sizeof(struct ia_na)) +#define DHCP6_OPTION_IA_PD_LEN (sizeof(struct ia_pd)) +#define DHCP6_OPTION_IA_TA_LEN (sizeof(struct ia_ta)) static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode, size_t optlen) { @@ -83,7 +97,7 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { uint16_t len; uint8_t *ia_hdr; - size_t ia_buflen, ia_addrlen = 0; + size_t iaid_offset, ia_buflen, ia_addrlen = 0; DHCP6Address *addr; int r; @@ -92,10 +106,12 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { switch (ia->type) { case SD_DHCP6_OPTION_IA_NA: len = DHCP6_OPTION_IA_NA_LEN; + iaid_offset = offsetof(DHCP6IA, ia_na); break; case SD_DHCP6_OPTION_IA_TA: len = DHCP6_OPTION_IA_TA_LEN; + iaid_offset = offsetof(DHCP6IA, ia_ta); break; default: @@ -111,7 +127,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { *buf += sizeof(DHCP6Option); *buflen -= sizeof(DHCP6Option); - memcpy(*buf, &ia->id, len); + memcpy(*buf, (char*) ia + iaid_offset, len); *buf += len; *buflen -= len; @@ -164,6 +180,42 @@ int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) { return r; } +int dhcp6_option_append_pd(uint8_t *buf, size_t len, DHCP6IA *pd) { + DHCP6Option *option = (DHCP6Option *)buf; + size_t i = sizeof(*option) + sizeof(pd->ia_pd); + DHCP6Address *prefix; + + assert_return(buf, -EINVAL); + assert_return(pd, -EINVAL); + assert_return(pd->type == SD_DHCP6_OPTION_IA_PD, -EINVAL); + + if (len < i) + return -ENOBUFS; + + option->code = htobe16(SD_DHCP6_OPTION_IA_PD); + + memcpy(&option->data, &pd->ia_pd, sizeof(pd->ia_pd)); + + LIST_FOREACH(addresses, prefix, pd->addresses) { + DHCP6PDPrefixOption *prefix_opt; + + if (len < i + sizeof(*prefix_opt)) + return -ENOBUFS; + + prefix_opt = (DHCP6PDPrefixOption *)&buf[i]; + prefix_opt->option.code = htobe16(SD_DHCP6_OPTION_IA_PD_PREFIX); + prefix_opt->option.len = htobe16(sizeof(prefix_opt->iapdprefix)); + + memcpy(&prefix_opt->iapdprefix, &prefix->iapdprefix, + sizeof(struct iapdprefix)); + + i += sizeof(*prefix_opt); + } + + option->len = htobe16(i - sizeof(*option)); + + return i; +} static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen) { DHCP6Option *option = (DHCP6Option*) *buf; @@ -210,35 +262,147 @@ int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, return 0; } -int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, - DHCP6IA *ia) { +int dhcp6_option_parse_status(DHCP6Option *option) { + DHCP6StatusOption *statusopt = (DHCP6StatusOption *)option; + + if (be16toh(option->len) + sizeof(DHCP6Option) < sizeof(*statusopt)) + return -ENOBUFS; + + return be16toh(statusopt->status); +} + +static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, + uint32_t *lifetime_valid) { + DHCP6AddressOption *addr_option = (DHCP6AddressOption *)option; + DHCP6Address *addr; + uint32_t lt_valid, lt_pref; int r; - uint16_t opt, status; - size_t optlen; + + if (be16toh(option->len) + sizeof(DHCP6Option) < sizeof(*addr_option)) + return -ENOBUFS; + + lt_valid = be32toh(addr_option->iaaddr.lifetime_valid); + lt_pref = be32toh(addr_option->iaaddr.lifetime_preferred); + + if (lt_valid == 0 || lt_pref > lt_valid) { + log_dhcp6_client(client, "Valid lifetime of an IA address is zero or preferred lifetime %d > valid lifetime %d", + lt_pref, lt_valid); + + return 0; + } + + if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*addr_option)) { + r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options); + if (r != 0) + return r < 0 ? r: 0; + } + + addr = new0(DHCP6Address, 1); + if (!addr) + return -ENOMEM; + + LIST_INIT(addresses, addr); + memcpy(&addr->iaaddr, option->data, sizeof(addr->iaaddr)); + + LIST_PREPEND(addresses, ia->addresses, addr); + + *lifetime_valid = be32toh(addr->iaaddr.lifetime_valid); + + return 0; +} + +static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, + uint32_t *lifetime_valid) { + DHCP6PDPrefixOption *pdprefix_option = (DHCP6PDPrefixOption *)option; + DHCP6Address *prefix; + uint32_t lt_valid, lt_pref; + int r; + + if (be16toh(option->len) + sizeof(DHCP6Option) < sizeof(*pdprefix_option)) + return -ENOBUFS; + + lt_valid = be32toh(pdprefix_option->iapdprefix.lifetime_valid); + lt_pref = be32toh(pdprefix_option->iapdprefix.lifetime_preferred); + + if (lt_valid == 0 || lt_pref > lt_valid) { + log_dhcp6_client(client, "Valid lifetieme of a PD prefix is zero or preferred lifetime %d > valid lifetime %d", + lt_pref, lt_valid); + + return 0; + } + + if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*pdprefix_option)) { + r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options); + if (r != 0) + return r < 0 ? r: 0; + } + + prefix = new0(DHCP6Address, 1); + if (!prefix) + return -ENOMEM; + + LIST_INIT(addresses, prefix); + memcpy(&prefix->iapdprefix, option->data, sizeof(prefix->iapdprefix)); + + LIST_PREPEND(addresses, ia->addresses, prefix); + + *lifetime_valid = be32toh(prefix->iapdprefix.lifetime_valid); + + return 0; +} + +int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) { + uint16_t iatype, optlen; + size_t i, len; + int r = 0, status; + uint16_t opt; size_t iaaddr_offset; - DHCP6Address *addr; - uint32_t lt_t1, lt_t2, lt_valid, lt_pref, lt_min = ~0; + uint32_t lt_t1, lt_t2, lt_valid = 0, lt_min = UINT32_MAX; assert_return(ia, -EINVAL); assert_return(!ia->addresses, -EINVAL); + iatype = be16toh(iaoption->code); + len = be16toh(iaoption->len); + switch (iatype) { case SD_DHCP6_OPTION_IA_NA: - if (*buflen < DHCP6_OPTION_IA_NA_LEN + sizeof(DHCP6Option) + - sizeof(addr->iaaddr)) { + if (len < DHCP6_OPTION_IA_NA_LEN) { r = -ENOBUFS; goto error; } iaaddr_offset = DHCP6_OPTION_IA_NA_LEN; - memcpy(&ia->id, *buf, iaaddr_offset); + memcpy(&ia->ia_na, iaoption->data, sizeof(ia->ia_na)); - lt_t1 = be32toh(ia->lifetime_t1); - lt_t2 = be32toh(ia->lifetime_t2); + lt_t1 = be32toh(ia->ia_na.lifetime_t1); + lt_t2 = be32toh(ia->ia_na.lifetime_t2); if (lt_t1 && lt_t2 && lt_t1 > lt_t2) { - log_dhcp6_client(client, "IA T1 %ds > T2 %ds", + log_dhcp6_client(client, "IA NA T1 %ds > T2 %ds", + lt_t1, lt_t2); + r = -EINVAL; + goto error; + } + + break; + + case SD_DHCP6_OPTION_IA_PD: + + if (len < sizeof(ia->ia_pd)) { + r = -ENOBUFS; + goto error; + } + + iaaddr_offset = sizeof(ia->ia_pd); + memcpy(&ia->ia_pd, iaoption->data, sizeof(ia->ia_pd)); + + lt_t1 = be32toh(ia->ia_pd.lifetime_t1); + lt_t2 = be32toh(ia->ia_pd.lifetime_t2); + + if (lt_t1 && lt_t2 && lt_t1 > lt_t2) { + log_dhcp6_client(client, "IA PD T1 %ds > T2 %ds", lt_t1, lt_t2); r = -EINVAL; goto error; @@ -247,17 +411,13 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, break; case SD_DHCP6_OPTION_IA_TA: - if (*buflen < DHCP6_OPTION_IA_TA_LEN + sizeof(DHCP6Option) + - sizeof(addr->iaaddr)) { + if (len < DHCP6_OPTION_IA_TA_LEN) { r = -ENOBUFS; goto error; } iaaddr_offset = DHCP6_OPTION_IA_TA_LEN; - memcpy(&ia->id, *buf, iaaddr_offset); - - ia->lifetime_t1 = 0; - ia->lifetime_t2 = 0; + memcpy(&ia->ia_ta.id, iaoption->data, sizeof(ia->ia_ta)); break; @@ -267,48 +427,63 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, } ia->type = iatype; + i = iaaddr_offset; - *buflen -= iaaddr_offset; - *buf += iaaddr_offset; + while (i < len) { + DHCP6Option *option = (DHCP6Option *)&iaoption->data[i]; - while ((r = option_parse_hdr(buf, buflen, &opt, &optlen)) >= 0) { + if (len < i + sizeof(*option) || len < i + sizeof(*option) + be16toh(option->len)) { + r = -ENOBUFS; + goto error; + } + + opt = be16toh(option->code); + optlen = be16toh(option->len); switch (opt) { case SD_DHCP6_OPTION_IAADDR: - addr = new0(DHCP6Address, 1); - if (!addr) { - r = -ENOMEM; + if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_NA, SD_DHCP6_OPTION_IA_TA)) { + log_dhcp6_client(client, "IA Address option not in IA NA or TA option"); + r = -EINVAL; goto error; } - LIST_INIT(addresses, addr); + r = dhcp6_option_parse_address(option, ia, <_valid); + if (r < 0) + goto error; + + if (lt_valid < lt_min) + lt_min = lt_valid; - memcpy(&addr->iaaddr, *buf, sizeof(addr->iaaddr)); + break; - lt_valid = be32toh(addr->iaaddr.lifetime_valid); - lt_pref = be32toh(addr->iaaddr.lifetime_valid); + case SD_DHCP6_OPTION_IA_PD_PREFIX: - if (!lt_valid || lt_pref > lt_valid) { - log_dhcp6_client(client, "IA preferred %ds > valid %ds", - lt_pref, lt_valid); - free(addr); - } else { - LIST_PREPEND(addresses, ia->addresses, addr); - if (lt_valid < lt_min) - lt_min = lt_valid; + if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_PD)) { + log_dhcp6_client(client, "IA PD Prefix option not in IA PD option"); + r = -EINVAL; + goto error; } + r = dhcp6_option_parse_pdprefix(option, ia, <_valid); + if (r < 0) + goto error; + + if (lt_valid < lt_min) + lt_min = lt_valid; + break; case SD_DHCP6_OPTION_STATUS_CODE: - if (optlen < sizeof(status)) - break; - status = (*buf)[0] << 8 | (*buf)[1]; + status = dhcp6_option_parse_status(option); if (status) { log_dhcp6_client(client, "IA status %d", status); + + dhcp6_lease_free_ia(ia); + r = -EINVAL; goto error; } @@ -320,30 +495,41 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, break; } - *buflen -= optlen; - *buf += optlen; + i += sizeof(*option) + optlen; } - if (r == -ENOMSG) - r = 0; + switch(iatype) { + case SD_DHCP6_OPTION_IA_NA: + if (!ia->ia_na.lifetime_t1 && !ia->ia_na.lifetime_t2) { + lt_t1 = lt_min / 2; + lt_t2 = lt_min / 10 * 8; + ia->ia_na.lifetime_t1 = htobe32(lt_t1); + ia->ia_na.lifetime_t2 = htobe32(lt_t2); - if (!ia->lifetime_t1 && !ia->lifetime_t2) { - lt_t1 = lt_min / 2; - lt_t2 = lt_min / 10 * 8; - ia->lifetime_t1 = htobe32(lt_t1); - ia->lifetime_t2 = htobe32(lt_t2); + log_dhcp6_client(client, "Computed IA NA T1 %ds and T2 %ds as both were zero", + lt_t1, lt_t2); + } - log_dhcp6_client(client, "Computed IA T1 %ds and T2 %ds as both were zero", - lt_t1, lt_t2); - } + break; - if (*buflen) - r = -ENOMSG; + case SD_DHCP6_OPTION_IA_PD: + if (!ia->ia_pd.lifetime_t1 && !ia->ia_pd.lifetime_t2) { + lt_t1 = lt_min / 2; + lt_t2 = lt_min / 10 * 8; + ia->ia_pd.lifetime_t1 = htobe32(lt_t1); + ia->ia_pd.lifetime_t2 = htobe32(lt_t2); -error: - *buf += *buflen; - *buflen = 0; + log_dhcp6_client(client, "Computed IA PD T1 %ds and T2 %ds as both were zero", + lt_t1, lt_t2); + } + break; + + default: + break; + } + +error: return r; } diff --git a/src/libsystemd-network/dhcp6-protocol.h b/src/libsystemd-network/dhcp6-protocol.h index 7bbf183996..5f7e809ba1 100644 --- a/src/libsystemd-network/dhcp6-protocol.h +++ b/src/libsystemd-network/dhcp6-protocol.h @@ -34,6 +34,7 @@ struct DHCP6Message { } _packed_; be32_t transaction_id; }; + uint8_t options[]; } _packed_; typedef struct DHCP6Message DHCP6Message; diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index e48b7d22dd..94386e4860 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -22,6 +22,7 @@ #include <linux/if.h> #include <netinet/ether.h> +#include "sd-id128.h" #include "sd-ndisc.h" #include "alloc-util.h" @@ -116,7 +117,8 @@ bool net_match_config(const struct ether_addr *match_mac, char * const *match_names, Condition *match_host, Condition *match_virt, - Condition *match_kernel, + Condition *match_kernel_cmdline, + Condition *match_kernel_version, Condition *match_arch, const struct ether_addr *dev_mac, const char *dev_path, @@ -131,7 +133,10 @@ bool net_match_config(const struct ether_addr *match_mac, if (match_virt && condition_test(match_virt) <= 0) return false; - if (match_kernel && condition_test(match_kernel) <= 0) + if (match_kernel_cmdline && condition_test(match_kernel_cmdline) <= 0) + return false; + + if (match_kernel_version && condition_test(match_kernel_version) <= 0) return false; if (match_arch && condition_test(match_arch) <= 0) diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index a54adac602..4e69f1a598 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -37,7 +37,8 @@ bool net_match_config(const struct ether_addr *match_mac, char * const *match_name, Condition *match_host, Condition *match_virt, - Condition *match_kernel, + Condition *match_kernel_cmdline, + Condition *match_kernel_version, Condition *match_arch, const struct ether_addr *dev_mac, const char *dev_path, diff --git a/src/libsystemd-network/radv-internal.h b/src/libsystemd-network/radv-internal.h index 441939b717..837e7f2603 100644 --- a/src/libsystemd-network/radv-internal.h +++ b/src/libsystemd-network/radv-internal.h @@ -93,6 +93,9 @@ struct sd_radv_prefix { } _packed_ opt; LIST_FIELDS(struct sd_radv_prefix, prefix); + + usec_t valid_until; + usec_t preferred_until; }; #define log_radv_full(level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__) diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 78b8e058b4..2e88e39878 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -471,6 +471,7 @@ static int lease_parse_routes( struct sd_dhcp_route *route = *routes + *routes_size; int r; + route->option = SD_DHCP_OPTION_STATIC_ROUTE; r = in4_addr_default_prefixlen((struct in_addr*) option, &route->dst_prefixlen); if (r < 0) { log_debug("Failed to determine destination prefix length from class based IP, ignoring"); @@ -514,6 +515,7 @@ static int lease_parse_classless_routes( return -ENOMEM; route = *routes + *routes_size; + route->option = SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE; dst_octets = (*option == 0 ? 0 : ((*option - 1) / 8) + 1); route->dst_prefixlen = *option; diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 63fb355e85..907b72391b 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -28,6 +28,7 @@ #include "dhcp-server-internal.h" #include "fd-util.h" #include "in-addr-util.h" +#include "sd-id128.h" #include "siphash24.h" #include "string-util.h" #include "unaligned.h" diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 1c12e5430f..ec3484383b 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -54,6 +54,8 @@ struct sd_dhcp6_client { size_t mac_addr_len; uint16_t arp_type; DHCP6IA ia_na; + DHCP6IA ia_pd; + bool prefix_delegation; be32_t transaction_id; usec_t transaction_start; struct sd_dhcp6_lease *lease; @@ -230,7 +232,8 @@ int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) { assert_return(client, -EINVAL); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); - client->ia_na.id = htobe32(iaid); + client->ia_na.ia_na.id = htobe32(iaid); + client->ia_pd.ia_pd.id = htobe32(iaid); return 0; } @@ -279,6 +282,7 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option) case SD_DHCP6_OPTION_DOMAIN_LIST: case SD_DHCP6_OPTION_SNTP_SERVERS: case SD_DHCP6_OPTION_NTP_SERVER: + case SD_DHCP6_OPTION_RAPID_COMMIT: break; default: @@ -298,6 +302,14 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option) return 0; } +int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client, bool delegation) { + assert_return(client, -EINVAL); + + client->prefix_delegation = delegation; + + return 0; +} + int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) { assert_return(client, -EINVAL); @@ -336,8 +348,6 @@ static int client_reset(sd_dhcp6_client *client) { client->receive_message = sd_event_source_unref(client->receive_message); - client->fd = safe_close(client->fd); - client->transaction_id = 0; client->transaction_start = 0; @@ -413,6 +423,15 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } + if (client->prefix_delegation) { + r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd); + if (r < 0) + return r; + + opt += r; + optlen -= r; + } + break; case DHCP6_STATE_REQUEST: @@ -439,6 +458,15 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } + if (client->prefix_delegation) { + r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd); + if (r < 0) + return r; + + opt += r; + optlen -= r; + } + break; case DHCP6_STATE_REBIND: @@ -454,6 +482,15 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } + if (client->prefix_delegation) { + r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd); + if (r < 0) + return r; + + opt += r; + optlen -= r; + } + break; case DHCP6_STATE_STOPPED: @@ -709,16 +746,20 @@ error: static int client_ensure_iaid(sd_dhcp6_client *client) { int r; + be32_t iaid; assert(client); - if (client->ia_na.id) + if (client->ia_na.ia_na.id) return 0; - r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->ia_na.id); + r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &iaid); if (r < 0) return r; + client->ia_na.ia_na.id = iaid; + client->ia_pd.ia_pd.id = iaid; + return 0; } @@ -727,23 +768,35 @@ static int client_parse_message( DHCP6Message *message, size_t len, sd_dhcp6_lease *lease) { + size_t pos = 0; int r; - uint8_t *optval, *option, *id = NULL; - uint16_t optcode, status; - size_t optlen, id_len; bool clientid = false; - be32_t iaid_lease; + uint8_t *id = NULL; + size_t id_len; + uint32_t lt_t1 = ~0, lt_t2 = ~0; assert(client); assert(message); assert(len >= sizeof(DHCP6Message)); assert(lease); - option = (uint8_t *)message + sizeof(DHCP6Message); len -= sizeof(DHCP6Message); - while ((r = dhcp6_option_parse(&option, &len, &optcode, &optlen, - &optval)) >= 0) { + while (pos < len) { + DHCP6Option *option = (DHCP6Option *)&message->options[pos]; + uint16_t optcode, optlen; + int status; + uint8_t *optval; + be32_t iaid_lease; + + if (len < offsetof(DHCP6Option, data) || + len < offsetof(DHCP6Option, data) + be16toh(option->len)) + return -ENOBUFS; + + optcode = be16toh(option->code); + optlen = be16toh(option->len); + optval = option->data; + switch (optcode) { case SD_DHCP6_OPTION_CLIENTID: if (clientid) { @@ -781,21 +834,21 @@ static int client_parse_message( if (optlen != 1) return -EINVAL; - r = dhcp6_lease_set_preference(lease, *optval); + r = dhcp6_lease_set_preference(lease, optval[0]); if (r < 0) return r; break; case SD_DHCP6_OPTION_STATUS_CODE: - if (optlen < 2) - return -EINVAL; - - status = optval[0] << 8 | optval[1]; + status = dhcp6_option_parse_status(option); if (status) { log_dhcp6_client(client, "%s Status %s", dhcp6_message_type_to_string(message->type), dhcp6_message_status_to_string(status)); + dhcp6_lease_free_ia(&lease->ia); + dhcp6_lease_free_ia(&lease->pd); + return -EINVAL; } @@ -808,8 +861,35 @@ static int client_parse_message( break; } - r = dhcp6_option_parse_ia(&optval, &optlen, optcode, - &lease->ia); + r = dhcp6_option_parse_ia(option, &lease->ia); + if (r < 0 && r != -ENOMSG) + return r; + + r = dhcp6_lease_get_iaid(lease, &iaid_lease); + if (r < 0) + return r; + + if (client->ia_na.ia_na.id != iaid_lease) { + log_dhcp6_client(client, "%s has wrong IAID for IA NA", + dhcp6_message_type_to_string(message->type)); + return -EINVAL; + } + + if (lease->ia.addresses) { + lt_t1 = MIN(lt_t1, be32toh(lease->ia.ia_na.lifetime_t1)); + lt_t2 = MIN(lt_t2, be32toh(lease->ia.ia_na.lifetime_t1)); + } + + break; + + case SD_DHCP6_OPTION_IA_PD: + if (client->state == DHCP6_STATE_INFORMATION_REQUEST) { + log_dhcp6_client(client, "Information request ignoring IA PD option"); + + break; + } + + r = dhcp6_option_parse_ia(option, &lease->pd); if (r < 0 && r != -ENOMSG) return r; @@ -817,12 +897,17 @@ static int client_parse_message( if (r < 0) return r; - if (client->ia_na.id != iaid_lease) { - log_dhcp6_client(client, "%s has wrong IAID", + if (client->ia_pd.ia_pd.id != iaid_lease) { + log_dhcp6_client(client, "%s has wrong IAID for IA PD", dhcp6_message_type_to_string(message->type)); return -EINVAL; } + if (lease->pd.addresses) { + lt_t1 = MIN(lt_t1, be32toh(lease->pd.ia_pd.lifetime_t1)); + lt_t2 = MIN(lt_t2, be32toh(lease->pd.ia_pd.lifetime_t2)); + } + break; case SD_DHCP6_OPTION_RAPID_COMMIT: @@ -861,12 +946,10 @@ static int client_parse_message( break; } + pos += sizeof(*option) + optlen; } - if (r == -ENOMSG) - r = 0; - - if (r < 0 || !clientid) { + if (!clientid) { log_dhcp6_client(client, "%s has incomplete options", dhcp6_message_type_to_string(message->type)); return -EINVAL; @@ -877,6 +960,17 @@ static int client_parse_message( if (r < 0) log_dhcp6_client(client, "%s has no server id", dhcp6_message_type_to_string(message->type)); + return r; + } + + if (lease->ia.addresses) { + lease->ia.ia_na.lifetime_t1 = htobe32(lt_t1); + lease->ia.ia_na.lifetime_t2 = htobe32(lt_t2); + } + + if (lease->pd.addresses) { + lease->pd.ia_pd.lifetime_t1 = htobe32(lt_t1); + lease->pd.ia_pd.lifetime_t2 = htobe32(lt_t2); } return r; @@ -1092,6 +1186,24 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { if (r < 0) return r; + if (!client->receive_message) { + r = sd_event_add_io(client->event, &client->receive_message, + client->fd, EPOLLIN, client_receive_message, + client); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->receive_message, + client->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(client->receive_message, + "dhcp6-receive-message"); + if (r < 0) + goto error; + } + switch (state) { case DHCP6_STATE_STOPPED: if (client->state == DHCP6_STATE_INFORMATION_REQUEST) { @@ -1117,17 +1229,17 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { case DHCP6_STATE_BOUND: - if (client->lease->ia.lifetime_t1 == 0xffffffff || - client->lease->ia.lifetime_t2 == 0xffffffff) { + if (client->lease->ia.ia_na.lifetime_t1 == 0xffffffff || + client->lease->ia.ia_na.lifetime_t2 == 0xffffffff) { log_dhcp6_client(client, "Infinite T1 0x%08x or T2 0x%08x", - be32toh(client->lease->ia.lifetime_t1), - be32toh(client->lease->ia.lifetime_t2)); + be32toh(client->lease->ia.ia_na.lifetime_t1), + be32toh(client->lease->ia.ia_na.lifetime_t2)); return 0; } - timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t1) * USEC_PER_SEC); + timeout = client_timeout_compute_random(be32toh(client->lease->ia.ia_na.lifetime_t1) * USEC_PER_SEC); log_dhcp6_client(client, "T1 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); @@ -1138,18 +1250,18 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { 10 * USEC_PER_SEC, client_timeout_t1, client); if (r < 0) - return r; + goto error; r = sd_event_source_set_priority(client->lease->ia.timeout_t1, client->event_priority); if (r < 0) - return r; + goto error; r = sd_event_source_set_description(client->lease->ia.timeout_t1, "dhcp6-t1-timeout"); if (r < 0) - return r; + goto error; - timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t2) * USEC_PER_SEC); + timeout = client_timeout_compute_random(be32toh(client->lease->ia.ia_na.lifetime_t2) * USEC_PER_SEC); log_dhcp6_client(client, "T2 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); @@ -1160,16 +1272,16 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { 10 * USEC_PER_SEC, client_timeout_t2, client); if (r < 0) - return r; + goto error; r = sd_event_source_set_priority(client->lease->ia.timeout_t2, client->event_priority); if (r < 0) - return r; + goto error; r = sd_event_source_set_description(client->lease->ia.timeout_t2, "dhcp6-t2-timeout"); if (r < 0) - return r; + goto error; client->state = state; @@ -1183,18 +1295,22 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { clock_boottime_or_monotonic(), 0, 0, client_timeout_resend, client); if (r < 0) - return r; + goto error; r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); if (r < 0) - return r; + goto error; r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timeout"); if (r < 0) - return r; + goto error; return 0; + + error: + client_reset(client); + return r; } int sd_dhcp6_client_stop(sd_dhcp6_client *client) { @@ -1202,6 +1318,8 @@ int sd_dhcp6_client_stop(sd_dhcp6_client *client) { client_stop(client, SD_DHCP6_CLIENT_EVENT_STOP); + client->fd = safe_close(client->fd); + return 0; } @@ -1235,32 +1353,18 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { if (r < 0) return r; - r = dhcp6_network_bind_udp_socket(client->ifindex, &client->local_address); - if (r < 0) { - _cleanup_free_ char *p = NULL; - - (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &client->local_address, &p); - return log_dhcp6_client_errno(client, r, - "Failed to bind to UDP socket at address %s: %m", strna(p)); - } - - client->fd = r; - - r = sd_event_add_io(client->event, &client->receive_message, - client->fd, EPOLLIN, client_receive_message, - client); - if (r < 0) - goto error; + if (client->fd < 0) { + r = dhcp6_network_bind_udp_socket(client->ifindex, &client->local_address); + if (r < 0) { + _cleanup_free_ char *p = NULL; - r = sd_event_source_set_priority(client->receive_message, - client->event_priority); - if (r < 0) - goto error; + (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &client->local_address, &p); + return log_dhcp6_client_errno(client, r, + "Failed to bind to UDP socket at address %s: %m", strna(p)); + } - r = sd_event_source_set_description(client->receive_message, - "dhcp6-receive-message"); - if (r < 0) - goto error; + client->fd = r; + } if (client->information_request) state = DHCP6_STATE_INFORMATION_REQUEST; @@ -1270,10 +1374,6 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { "Managed"); return client_start(client, state); - -error: - client_reset(client); - return r; } int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int64_t priority) { @@ -1333,6 +1433,8 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) { client_reset(client); + client->fd = safe_close(client->fd); + sd_dhcp6_client_detach_event(client); free(client->req_opts); @@ -1352,6 +1454,7 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) { client->n_ref = 1; client->ia_na.type = SD_DHCP6_OPTION_IA_NA; + client->ia_pd.type = SD_DHCP6_OPTION_IA_PD; client->ifindex = -1; client->fd = -1; diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index 6f604e072f..1f3a782f8c 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -49,7 +49,7 @@ int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) { valid = t; } - t = be32toh(ia->lifetime_t2); + t = be32toh(ia->ia_na.lifetime_t2); if (t > valid) return -EINVAL; @@ -144,7 +144,7 @@ int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) { assert_return(lease, -EINVAL); assert_return(iaid, -EINVAL); - *iaid = lease->ia.id; + *iaid = lease->ia.ia_na.id; return 0; } @@ -176,6 +176,37 @@ void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease) { lease->addr_iter = lease->ia.addresses; } +int sd_dhcp6_lease_get_pd(sd_dhcp6_lease *lease, struct in6_addr *prefix, + uint8_t *prefix_len, + uint32_t *lifetime_preferred, + uint32_t *lifetime_valid) { + assert_return(lease, -EINVAL); + assert_return(prefix, -EINVAL); + assert_return(prefix_len, -EINVAL); + assert_return(lifetime_preferred, -EINVAL); + assert_return(lifetime_valid, -EINVAL); + + if (!lease->prefix_iter) + return -ENOMSG; + + memcpy(prefix, &lease->prefix_iter->iapdprefix.address, + sizeof(struct in6_addr)); + *prefix_len = lease->prefix_iter->iapdprefix.prefixlen; + *lifetime_preferred = + be32toh(lease->prefix_iter->iapdprefix.lifetime_preferred); + *lifetime_valid = + be32toh(lease->prefix_iter->iapdprefix.lifetime_valid); + + lease->prefix_iter = lease->prefix_iter->addresses_next; + + return 0; +} + +void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease *lease) { + if (lease) + lease->prefix_iter = lease->pd.addresses; +} + int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) { int r; @@ -382,6 +413,7 @@ sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) { free(lease->serverid); dhcp6_lease_free_ia(&lease->ia); + dhcp6_lease_free_ia(&lease->pd); free(lease->dns); diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index 23e2f5211d..f3d09eb30a 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include <string.h> +#include "sd-id128.h" #include "sd-ipv4acd.h" #include "sd-ipv4ll.h" diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c index 46704acdef..f30d6164ea 100644 --- a/src/libsystemd-network/sd-radv.c +++ b/src/libsystemd-network/sd-radv.c @@ -21,7 +21,6 @@ #include <netinet/icmp6.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <linux/in6.h> #include "sd-radv.h" @@ -169,6 +168,12 @@ static int radv_send(sd_radv *ra, const struct in6_addr *dst, .msg_namelen = sizeof(dst_addr), .msg_iov = iov, }; + usec_t time_now; + int r; + + r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) + return r; if (dst && !in_addr_is_null(AF_INET6, (union in_addr_union*) dst)) dst_addr.sin6_addr = *dst; @@ -198,6 +203,18 @@ static int radv_send(sd_radv *ra, const struct in6_addr *dst, } LIST_FOREACH(prefix, p, ra->prefixes) { + if (p->valid_until) { + + if (time_now > p->valid_until) + p->opt.valid_lifetime = 0; + else + p->opt.valid_lifetime = htobe32((p->valid_until - time_now) / USEC_PER_SEC); + + if (time_now > p->preferred_until) + p->opt.preferred_lifetime = 0; + else + p->opt.preferred_lifetime = htobe32((p->preferred_until - time_now) / USEC_PER_SEC); + } iov[msg.msg_iovlen].iov_base = &p->opt; iov[msg.msg_iovlen].iov_len = sizeof(p->opt); msg.msg_iovlen++; @@ -446,9 +463,6 @@ _public_ int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu) { assert_return(ra, -EINVAL); assert_return(mtu >= 1280, -EINVAL); - if (ra->state != SD_RADV_STATE_IDLE) - return -EBUSY; - ra->mtu = mtu; return 0; @@ -518,9 +532,13 @@ _public_ int sd_radv_set_preference(sd_radv *ra, unsigned preference) { return r; } -_public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) { +_public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, bool dynamic) { sd_radv_prefix *cur; + int r; _cleanup_free_ char *addr_p = NULL; + char time_string_preferred[FORMAT_TIMESPAN_MAX]; + char time_string_valid[FORMAT_TIMESPAN_MAX]; + usec_t time_now, valid, preferred, valid_until, preferred_until; assert_return(ra, -EINVAL); @@ -528,7 +546,6 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) { return -EINVAL; LIST_FOREACH(prefix, cur, ra->prefixes) { - int r; r = in_addr_prefix_intersect(AF_INET6, (union in_addr_union*) &cur->opt.in6_addr, @@ -539,12 +556,15 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) { _cleanup_free_ char *addr_cur = NULL; (void) in_addr_to_string(AF_INET6, - (union in_addr_union*) &cur->opt.in6_addr, - &addr_cur); - (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &p->opt.in6_addr, &addr_p); + if (dynamic && cur->opt.prefixlen == p->opt.prefixlen) + goto update; + + (void) in_addr_to_string(AF_INET6, + (union in_addr_union*) &cur->opt.in6_addr, + &addr_cur); log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u", addr_cur, cur->opt.prefixlen, addr_p, p->opt.prefixlen); @@ -560,11 +580,69 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) { ra->n_prefixes++; (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &p->opt.in6_addr, &addr_p); - log_radv("Added prefix %s/%d", addr_p, p->opt.prefixlen); + + if (!dynamic) { + log_radv("Added prefix %s/%d", addr_p, p->opt.prefixlen); + return 0; + } + + cur = p; + + update: + r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) + return r; + + valid = be32toh(p->opt.valid_lifetime) * USEC_PER_SEC; + valid_until = usec_add(valid, time_now); + if (valid_until == USEC_INFINITY) + return -EOVERFLOW; + + preferred = be32toh(p->opt.preferred_lifetime) * USEC_PER_SEC; + preferred_until = usec_add(preferred, time_now); + if (preferred_until == USEC_INFINITY) + return -EOVERFLOW; + + cur->valid_until = valid_until; + cur->preferred_until = preferred_until; + + log_radv("%s prefix %s/%u preferred %s valid %s", + cur? "Updated": "Added", + addr_p, p->opt.prefixlen, + format_timespan(time_string_preferred, FORMAT_TIMESPAN_MAX, + preferred, USEC_PER_SEC), + format_timespan(time_string_valid, FORMAT_TIMESPAN_MAX, + valid, USEC_PER_SEC)); return 0; } +_public_ sd_radv_prefix *sd_radv_remove_prefix(sd_radv *ra, + struct in6_addr *prefix, + uint8_t prefixlen) { + sd_radv_prefix *cur, *next; + + assert_return(ra, NULL); + assert_return(prefix, NULL); + + LIST_FOREACH_SAFE(prefix, cur, next, ra->prefixes) { + if (prefixlen != cur->opt.prefixlen) + continue; + + if (!in_addr_equal(AF_INET6, + (union in_addr_union *)prefix, + (union in_addr_union *)&cur->opt.in6_addr)) + continue; + + LIST_REMOVE(prefix, ra->prefixes, cur); + ra->n_prefixes--; + + break; + } + + return cur; +} + _public_ int sd_radv_set_rdnss(sd_radv *ra, uint32_t lifetime, const struct in6_addr *dns, size_t n_dns) { _cleanup_free_ struct sd_radv_opt_dns *opt_rdnss = NULL; diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index a0418ecdb9..aae49fa467 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -156,6 +156,138 @@ static int test_option(sd_event *e) { return 0; } +static int test_option_status(sd_event *e) { + uint8_t option1[] = { + /* IA NA */ + 0x00, 0x03, 0x00, 0x12, 0x1a, 0x1d, 0x1a, 0x1d, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, + /* status option */ + 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01, + }; + static const uint8_t option2[] = { + /* IA NA */ + 0x00, 0x03, 0x00, 0x2e, 0x1a, 0x1d, 0x1a, 0x1d, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, + /* IA Addr */ + 0x00, 0x05, 0x00, 0x1e, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d, + /* status option */ + 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01, + }; + static const uint8_t option3[] = { + /* IA NA */ + 0x00, 0x03, 0x00, 0x34, 0x1a, 0x1d, 0x1a, 0x1d, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, + /* IA Addr */ + 0x00, 0x05, 0x00, 0x24, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d, + /* status option */ + 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 'f', 'o', + 'o', 'b', 'a', 'r', + }; + static const uint8_t option4[] = { + /* IA PD */ + 0x00, 0x19, 0x00, 0x2f, 0x1a, 0x1d, 0x1a, 0x1d, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, + /* IA PD Prefix */ + 0x00, 0x1a, 0x00, 0x1f, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, + 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + /* status option */ + 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00, + }; + static const uint8_t option5[] = { + /* IA PD */ + 0x00, 0x19, 0x00, 0x52, 0x1a, 0x1d, 0x1a, 0x1d, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, + /* IA PD Prefix #1 */ + 0x00, 0x1a, 0x00, 0x1f, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, + 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + /* status option */ + 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00, + /* IA PD Prefix #2 */ + 0x00, 0x1a, 0x00, 0x1f, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x0l, 0xd0, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00, + }; + DHCP6Option *option; + DHCP6IA ia, pd; + int r = 0; + + if (verbose) + printf("* %s\n", __FUNCTION__); + + zero(ia); + option = (DHCP6Option *)option1; + assert_se(sizeof(option1) == sizeof(DHCP6Option) + be16toh(option->len)); + + r = dhcp6_option_parse_ia(option, &ia); + assert_se(r == -EINVAL); + assert_se(ia.addresses == NULL); + + option->len = htobe16(17); + r = dhcp6_option_parse_ia(option, &ia); + assert_se(r == -ENOBUFS); + assert_se(ia.addresses == NULL); + + option->len = htobe16(sizeof(DHCP6Option)); + r = dhcp6_option_parse_ia(option, &ia); + assert_se(r == -ENOBUFS); + assert_se(ia.addresses == NULL); + + zero(ia); + option = (DHCP6Option *)option2; + assert_se(sizeof(option2) == sizeof(DHCP6Option) + be16toh(option->len)); + + r = dhcp6_option_parse_ia(option, &ia); + assert_se(r >= 0); + assert_se(ia.addresses == NULL); + + zero(ia); + option = (DHCP6Option *)option3; + assert_se(sizeof(option3) == sizeof(DHCP6Option) + be16toh(option->len)); + + r = dhcp6_option_parse_ia(option, &ia); + assert_se(r >= 0); + assert_se(ia.addresses != NULL); + dhcp6_lease_free_ia(&ia); + + zero(pd); + option = (DHCP6Option *)option4; + assert_se(sizeof(option4) == sizeof(DHCP6Option) + be16toh(option->len)); + + r = dhcp6_option_parse_ia(option, &pd); + assert_se(r == 0); + assert_se(pd.addresses != NULL); + assert_se(memcmp(&pd.ia_pd.id, &option4[4], 4) == 0); + assert_se(memcmp(&pd.ia_pd.lifetime_t1, &option4[8], 4) == 0); + assert_se(memcmp(&pd.ia_pd.lifetime_t2, &option4[12], 4) == 0); + dhcp6_lease_free_ia(&pd); + + zero(pd); + option = (DHCP6Option *)option5; + assert_se(sizeof(option5) == sizeof(DHCP6Option) + be16toh(option->len)); + + r = dhcp6_option_parse_ia(option, &pd); + assert_se(r == 0); + assert_se(pd.addresses != NULL); + dhcp6_lease_free_ia(&pd); + + return 0; +} + static uint8_t msg_advertise[198] = { 0x02, 0x0f, 0xb4, 0xe5, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b, 0xf3, 0x30, @@ -217,14 +349,13 @@ static uint8_t fqdn_wire[16] = { static int test_advertise_option(sd_event *e) { _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL; DHCP6Message *advertise = (DHCP6Message *)msg_advertise; - uint8_t *optval, *opt = msg_advertise + sizeof(DHCP6Message); - uint16_t optcode; - size_t optlen, len = sizeof(msg_advertise) - sizeof(DHCP6Message); + size_t len = sizeof(msg_advertise) - sizeof(DHCP6Message), pos = 0; be32_t val; uint8_t preference = 255; struct in6_addr addr; uint32_t lt_pref, lt_valid; int r; + uint8_t *opt; bool opt_clientid = false; struct in6_addr *addrs; char **domains; @@ -232,14 +363,19 @@ static int test_advertise_option(sd_event *e) { if (verbose) printf("* %s\n", __FUNCTION__); + assert_se(len >= sizeof(DHCP6Message)); + assert_se(dhcp6_lease_new(&lease) >= 0); assert_se(advertise->type == DHCP6_ADVERTISE); assert_se((be32toh(advertise->transaction_id) & 0x00ffffff) == 0x0fb4e5); - while ((r = dhcp6_option_parse(&opt, &len, &optcode, &optlen, - &optval)) >= 0) { + while (pos < len) { + DHCP6Option *option = (DHCP6Option *)&advertise->options[pos]; + const uint16_t optcode = be16toh(option->code); + const uint16_t optlen = be16toh(option->len); + uint8_t *optval = option->data; switch(optcode) { case SD_DHCP6_OPTION_CLIENTID: @@ -261,9 +397,7 @@ static int test_advertise_option(sd_event *e) { val = htobe32(120); assert_se(!memcmp(optval + 8, &val, sizeof(val))); - assert_se(dhcp6_option_parse_ia(&optval, &optlen, - optcode, - &lease->ia) >= 0); + assert_se(dhcp6_option_parse_ia(option, &lease->ia) >= 0); break; @@ -309,11 +443,11 @@ static int test_advertise_option(sd_event *e) { default: break; } - } + pos += sizeof(*option) + optlen; + } - assert_se(r == -ENOMSG); - + assert_se(pos == len); assert_se(opt_clientid); sd_dhcp6_lease_reset_address_iter(lease); @@ -415,15 +549,11 @@ static int test_client_send_reply(DHCP6Message *request) { return 0; } -static int test_client_verify_request(DHCP6Message *request, uint8_t *option, - size_t len) { +static int test_client_verify_request(DHCP6Message *request, size_t len) { _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL; - uint8_t *optval; - uint16_t optcode; - size_t optlen; + size_t pos = 0; bool found_clientid = false, found_iana = false, found_serverid = false, found_elapsed_time = false, found_fqdn = false; - int r; struct in6_addr addr; be32_t val; uint32_t lt_pref, lt_valid; @@ -432,8 +562,14 @@ static int test_client_verify_request(DHCP6Message *request, uint8_t *option, assert_se(dhcp6_lease_new(&lease) >= 0); - while ((r = dhcp6_option_parse(&option, &len, - &optcode, &optlen, &optval)) >= 0) { + len -= sizeof(DHCP6Message); + + while (pos < len) { + DHCP6Option *option = (DHCP6Option *)&request->options[pos]; + uint16_t optcode = be16toh(option->code); + uint16_t optlen = be16toh(option->len); + uint8_t *optval = option->data; + switch(optcode) { case SD_DHCP6_OPTION_CLIENTID: assert_se(!found_clientid); @@ -458,8 +594,7 @@ static int test_client_verify_request(DHCP6Message *request, uint8_t *option, val = htobe32(120); assert_se(!memcmp(optval + 8, &val, sizeof(val))); - assert_se(!dhcp6_option_parse_ia(&optval, &optlen, - optcode, &lease->ia)); + assert_se(!dhcp6_option_parse_ia(option, &lease->ia)); break; @@ -489,9 +624,10 @@ static int test_client_verify_request(DHCP6Message *request, uint8_t *option, assert_se(!memcmp(optval + 1, fqdn_wire, sizeof(fqdn_wire))); break; } + + pos += sizeof(*option) + optlen; } - assert_se(r == -ENOMSG); assert_se(found_clientid && found_iana && found_serverid && found_elapsed_time); @@ -526,19 +662,21 @@ static int test_client_send_advertise(DHCP6Message *solicit) { return 0; } -static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option, - size_t len) { - uint8_t *optval; - uint16_t optcode; - size_t optlen; +static int test_client_verify_solicit(DHCP6Message *solicit, size_t len) { bool found_clientid = false, found_iana = false, found_elapsed_time = false, found_fqdn = false; - int r; + size_t pos = 0; assert_se(solicit->type == DHCP6_SOLICIT); - while ((r = dhcp6_option_parse(&option, &len, - &optcode, &optlen, &optval)) >= 0) { + len -= sizeof(DHCP6Message); + + while (pos < len) { + DHCP6Option *option = (DHCP6Option *)&solicit->options[pos]; + uint16_t optcode = be16toh(option->code); + uint16_t optlen = be16toh(option->len); + uint8_t *optval = option->data; + switch(optcode) { case SD_DHCP6_OPTION_CLIENTID: assert_se(!found_clientid); @@ -578,9 +716,11 @@ static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option, break; } + + pos += sizeof(*option) + optlen; } - assert_se(r == -ENOMSG); + assert_se(pos == len); assert_se(found_clientid && found_iana && found_elapsed_time); return 0; @@ -623,17 +763,15 @@ static void test_client_information_cb(sd_dhcp6_client *client, int event, assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0); assert_se(sd_dhcp6_client_start(client) >= 0); + } static int test_client_verify_information_request(DHCP6Message *information_request, - uint8_t *option, size_t len) { + size_t len) { _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL; - uint8_t *optval; - uint16_t optcode; - size_t optlen; + size_t pos = 0; bool found_clientid = false, found_elapsed_time = false; - int r; struct in6_addr addr; uint32_t lt_pref, lt_valid; @@ -641,8 +779,14 @@ static int test_client_verify_information_request(DHCP6Message *information_requ assert_se(dhcp6_lease_new(&lease) >= 0); - while ((r = dhcp6_option_parse(&option, &len, - &optcode, &optlen, &optval)) >= 0) { + len -= sizeof(DHCP6Message); + + while (pos < len) { + DHCP6Option *option = (DHCP6Option *)&information_request->options[pos]; + uint16_t optcode = be16toh(option->code); + uint16_t optlen = be16toh(option->len); + uint8_t *optval = option->data; + switch(optcode) { case SD_DHCP6_OPTION_CLIENTID: assert_se(!found_clientid); @@ -671,9 +815,11 @@ static int test_client_verify_information_request(DHCP6Message *information_requ break; } + + pos += sizeof(*option) + optlen; } - assert_se(r == -ENOMSG); + assert_se(pos == len); assert_se(found_clientid && found_elapsed_time); sd_dhcp6_lease_reset_address_iter(lease); @@ -689,7 +835,6 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, struct in6_addr mcast = IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT; DHCP6Message *message; - uint8_t *option; assert_se(s == test_dhcp_fd[0]); assert_se(server_address); @@ -699,21 +844,19 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, assert_se(IN6_ARE_ADDR_EQUAL(server_address, &mcast)); message = (DHCP6Message *)packet; - option = (uint8_t *)(message + 1); - len -= sizeof(DHCP6Message); assert_se(message->transaction_id & 0x00ffffff); if (test_client_message_num == 0) { - test_client_verify_information_request(message, option, len); + test_client_verify_information_request(message, len); test_client_send_reply(message); test_client_message_num++; } else if (test_client_message_num == 1) { - test_client_verify_solicit(message, option, len); + test_client_verify_solicit(message, len); test_client_send_advertise(message); test_client_message_num++; } else if (test_client_message_num == 2) { - test_client_verify_request(message, option, len); + test_client_verify_request(message, len); test_client_send_reply(message); test_client_message_num++; } @@ -789,6 +932,7 @@ int main(int argc, char *argv[]) { test_client_basic(e); test_option(e); + test_option_status(e); test_advertise_option(e); test_client_solicit(e); diff --git a/src/libsystemd-network/test-lldp.c b/src/libsystemd-network/test-lldp.c index c62689373f..b91797cb66 100644 --- a/src/libsystemd-network/test-lldp.c +++ b/src/libsystemd-network/test-lldp.c @@ -20,6 +20,7 @@ ***/ #include <arpa/inet.h> +#include <errno.h> #include <net/ethernet.h> #include <stdio.h> #include <string.h> diff --git a/src/libsystemd-network/test-ndisc-ra.c b/src/libsystemd-network/test-ndisc-ra.c index c1a8d5a00d..1fc8ca9eba 100644 --- a/src/libsystemd-network/test-ndisc-ra.c +++ b/src/libsystemd-network/test-ndisc-ra.c @@ -342,8 +342,8 @@ static void test_ra(void) { if (prefix[i].preferred) assert_se(sd_radv_prefix_set_preferred_lifetime(p, prefix[i].preferred) >= 0); - assert_se((sd_radv_add_prefix(ra, p) >= 0) == prefix[i].succesful); - assert_se(sd_radv_add_prefix(ra, p) < 0); + assert_se((sd_radv_add_prefix(ra, p, false) >= 0) == prefix[i].succesful); + assert_se(sd_radv_add_prefix(ra, p, false) < 0); p = sd_radv_prefix_unref(p); assert_se(!p); diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 1a29b03e85..00aeefbe19 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -530,3 +530,22 @@ global: sd_bus_message_new; sd_bus_message_seal; } LIBSYSTEMD_234; + +LIBSYSTEMD_237 { +global: + sd_bus_set_watch_bind; + sd_bus_get_watch_bind; + sd_bus_request_name_async; + sd_bus_release_name_async; + sd_bus_add_match_async; + sd_bus_match_signal; + sd_bus_match_signal_async; + sd_bus_is_ready; + sd_bus_set_connected_signal; + sd_bus_get_connected_signal; + sd_bus_set_sender; + sd_bus_get_sender; + sd_bus_message_set_sender; + sd_event_source_get_io_fd_own; + sd_event_source_set_io_fd_own; +} LIBSYSTEMD_236; diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index 4abf50b111..706e090762 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -17,9 +17,7 @@ sd_login_c = files('sd-login/sd-login.c') -libsystemd_internal_sources = files(''' - sd-bus/bus-bloom.c - sd-bus/bus-bloom.h +libsystemd_sources = files(''' sd-bus/bus-common-errors.c sd-bus/bus-common-errors.h sd-bus/bus-container.c @@ -74,6 +72,7 @@ libsystemd_internal_sources = files(''' sd-id128/id128-util.c sd-id128/id128-util.h sd-id128/sd-id128.c + sd-netlink/generic-netlink.c sd-netlink/local-addresses.c sd-netlink/local-addresses.h sd-netlink/netlink-internal.h @@ -93,14 +92,15 @@ libsystemd_internal_sources = files(''' sd-utf8/sd-utf8.c '''.split()) + sd_login_c -libsystemd_internal = static_library( +libsystemd_static = static_library( 'systemd', - libsystemd_internal_sources, + libsystemd_sources, install : false, include_directories : includes, link_with : libbasic, dependencies : [threads, - librt]) + librt], + c_args : ['-fvisibility=default']) libsystemd_sym = 'src/libsystemd/libsystemd.sym' diff --git a/src/libsystemd/sd-bus/bus-bloom.c b/src/libsystemd/sd-bus/bus-bloom.c deleted file mode 100644 index ebda6516e2..0000000000 --- a/src/libsystemd/sd-bus/bus-bloom.c +++ /dev/null @@ -1,157 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "bus-bloom.h" -#include "siphash24.h" -#include "util.h" - -static inline void set_bit(uint64_t filter[], unsigned long b) { - filter[b >> 6] |= 1ULL << (b & 63); -} - -static const sd_id128_t hash_keys[] = { - SD_ID128_ARRAY(b9,66,0b,f0,46,70,47,c1,88,75,c4,9c,54,b9,bd,15), - SD_ID128_ARRAY(aa,a1,54,a2,e0,71,4b,39,bf,e1,dd,2e,9f,c5,4a,3b), - SD_ID128_ARRAY(63,fd,ae,be,cd,82,48,12,a1,6e,41,26,cb,fa,a0,c8), - SD_ID128_ARRAY(23,be,45,29,32,d2,46,2d,82,03,52,28,fe,37,17,f5), - SD_ID128_ARRAY(56,3b,bf,ee,5a,4f,43,39,af,aa,94,08,df,f0,fc,10), - SD_ID128_ARRAY(31,80,c8,73,c7,ea,46,d3,aa,25,75,0f,9e,4c,09,29), - SD_ID128_ARRAY(7d,f7,18,4b,7b,a4,44,d5,85,3c,06,e0,65,53,96,6d), - SD_ID128_ARRAY(f2,77,e9,6f,93,b5,4e,71,9a,0c,34,88,39,25,bf,35), -}; - -static void bloom_add_data( - uint64_t filter[], /* The filter bits */ - size_t size, /* Size of the filter in bytes */ - unsigned k, /* Number of hash functions */ - const void *data, /* Data to hash */ - size_t n) { /* Size of data to hash in bytes */ - - uint64_t h; - uint64_t m; - unsigned w, i, c = 0; - unsigned hash_index; - - assert(size > 0); - assert(k > 0); - - /* Determine bits in filter */ - m = size * 8; - - /* Determine how many bytes we need to generate a bit index 0..m for this filter */ - w = (u64log2(m) + 7) / 8; - - assert(w <= sizeof(uint64_t)); - - /* Make sure we have enough hash keys to generate m * k bits - * of hash value. Note that SipHash24 generates 64 bits of - * hash value for each 128 bits of hash key. */ - assert(k * w <= ELEMENTSOF(hash_keys) * 8); - - for (i = 0, hash_index = 0; i < k; i++) { - uint64_t p = 0; - unsigned d; - - for (d = 0; d < w; d++) { - if (c <= 0) { - h = siphash24(data, n, hash_keys[hash_index++].bytes); - c += 8; - } - - p = (p << 8ULL) | (uint64_t) ((uint8_t *)&h)[8 - c]; - c--; - } - - p &= m - 1; - set_bit(filter, p); - } - - /* log_debug("bloom: adding <%.*s>", (int) n, (char*) data); */ -} - -void bloom_add_pair(uint64_t filter[], size_t size, unsigned k, const char *a, const char *b) { - size_t n; - char *c; - - assert(filter); - assert(a); - assert(b); - - n = strlen(a) + 1 + strlen(b); - c = alloca(n + 1); - strcpy(stpcpy(stpcpy(c, a), ":"), b); - - bloom_add_data(filter, size, k, c, n); -} - -void bloom_add_prefixes(uint64_t filter[], size_t size, unsigned k, const char *a, const char *b, char sep) { - size_t n; - char *c, *p; - - assert(filter); - assert(a); - assert(b); - - n = strlen(a) + 1 + strlen(b); - c = alloca(n + 1); - - p = stpcpy(stpcpy(c, a), ":"); - strcpy(p, b); - - bloom_add_data(filter, size, k, c, n); - - for (;;) { - char *e; - - e = strrchr(p, sep); - if (!e) - break; - - *(e + 1) = 0; - bloom_add_data(filter, size, k, c, e - c + 1); - - if (e == p) - break; - - *e = 0; - bloom_add_data(filter, size, k, c, e - c); - } -} - -bool bloom_validate_parameters(size_t size, unsigned k) { - uint64_t m; - unsigned w; - - if (size <= 0) - return false; - - if (k <= 0) - return false; - - m = size * 8; - w = (u64log2(m) + 7) / 8; - if (w > sizeof(uint64_t)) - return false; - - if (k * w > ELEMENTSOF(hash_keys) * 8) - return false; - - return true; -} diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c index 8f6d34838e..16156d8823 100644 --- a/src/libsystemd/sd-bus/bus-container.c +++ b/src/libsystemd/sd-bus/bus-container.c @@ -31,9 +31,8 @@ int bus_container_connect_socket(sd_bus *b) { _cleanup_close_pair_ int pair[2] = { -1, -1 }; _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1; - pid_t child; - siginfo_t si; int r, error_buf = 0; + pid_t child; ssize_t n; assert(b); @@ -62,11 +61,10 @@ int bus_container_connect_socket(sd_bus *b) { if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0) return -errno; - child = fork(); - if (child < 0) - return -errno; - - if (child == 0) { + r = safe_fork("(sd-buscntr)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child); + if (r < 0) + return r; + if (r == 0) { pid_t grandchild; pair[0] = safe_close(pair[0]); @@ -82,11 +80,10 @@ int bus_container_connect_socket(sd_bus *b) { * comes from a process from within the container, and * not outside of it */ - grandchild = fork(); - if (grandchild < 0) + r = safe_fork("(sd-buscntr2)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &grandchild); + if (r < 0) _exit(EXIT_FAILURE); - - if (grandchild == 0) { + if (r == 0) { r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size); if (r < 0) { @@ -99,21 +96,20 @@ int bus_container_connect_socket(sd_bus *b) { _exit(EXIT_SUCCESS); } - r = wait_for_terminate(grandchild, &si); + r = wait_for_terminate_and_check("(sd-buscntr2)", grandchild, 0); if (r < 0) _exit(EXIT_FAILURE); - if (si.si_code != CLD_EXITED) - _exit(EXIT_FAILURE); - - _exit(si.si_status); + _exit(r); } pair[1] = safe_close(pair[1]); - r = wait_for_terminate(child, &si); + r = wait_for_terminate_and_check("(sd-buscntr)", child, 0); if (r < 0) return r; + if (r != EXIT_SUCCESS) + return -EPROTO; n = read(pair[0], &error_buf, sizeof(error_buf)); if (n < 0) @@ -133,11 +129,5 @@ int bus_container_connect_socket(sd_bus *b) { return -error_buf; } - if (si.si_code != CLD_EXITED) - return -EIO; - - if (si.si_status != EXIT_SUCCESS) - return -EIO; - return bus_socket_start_auth(b); } diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 12478e7cc6..9dd5274bf6 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -28,12 +28,12 @@ #include "sd-bus.h" #include "alloc-util.h" -#include "bus-bloom.h" #include "bus-control.h" #include "bus-internal.h" #include "bus-message.h" #include "bus-util.h" #include "capability-util.h" +#include "process-util.h" #include "stdio-util.h" #include "string-util.h" #include "strv.h" @@ -43,6 +43,7 @@ _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) { int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(unique, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -57,13 +58,31 @@ _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) { return 0; } -static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) { - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; - uint32_t ret, param = 0; - int r; +static int validate_request_name_parameters( + sd_bus *bus, + const char *name, + uint64_t flags, + uint32_t *ret_param) { + + uint32_t param = 0; assert(bus); assert(name); + assert(ret_param); + + assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL); + assert_return(service_name_is_valid(name), -EINVAL); + assert_return(name[0] != ':', -EINVAL); + + if (!bus->bus_client) + return -EINVAL; + + /* Don't allow requesting the special driver and local names */ + if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local")) + return -EINVAL; + + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT) param |= BUS_NAME_ALLOW_REPLACEMENT; @@ -72,6 +91,29 @@ static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) if (!(flags & SD_BUS_NAME_QUEUE)) param |= BUS_NAME_DO_NOT_QUEUE; + *ret_param = param; + + return 0; +} + +_public_ int sd_bus_request_name( + sd_bus *bus, + const char *name, + uint64_t flags) { + + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + uint32_t ret, param = 0; + int r; + + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(name, -EINVAL); + assert_return(!bus_pid_changed(bus), -ECHILD); + + r = validate_request_name_parameters(bus, name, flags, ¶m); + if (r < 0) + return r; + r = sd_bus_call_method( bus, "org.freedesktop.DBus", @@ -90,46 +132,145 @@ static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) if (r < 0) return r; - if (ret == BUS_NAME_ALREADY_OWNER) + switch (ret) { + + case BUS_NAME_ALREADY_OWNER: return -EALREADY; - else if (ret == BUS_NAME_EXISTS) + + case BUS_NAME_EXISTS: return -EEXIST; - else if (ret == BUS_NAME_IN_QUEUE) + + case BUS_NAME_IN_QUEUE: return 0; - else if (ret == BUS_NAME_PRIMARY_OWNER) + + case BUS_NAME_PRIMARY_OWNER: return 1; + } return -EIO; } -_public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) { +static int default_request_name_handler( + sd_bus_message *m, + void *userdata, + sd_bus_error *ret_error) { + + uint32_t ret; + int r; + + assert(m); + + if (sd_bus_message_is_method_error(m, NULL)) { + log_debug_errno(sd_bus_message_get_errno(m), + "Unable to request name, failing connection: %s", + sd_bus_message_get_error(m)->message); + + bus_enter_closing(sd_bus_message_get_bus(m)); + return 1; + } + + r = sd_bus_message_read(m, "u", &ret); + if (r < 0) + return r; + + switch (ret) { + + case BUS_NAME_ALREADY_OWNER: + log_debug("Already owner of requested service name, ignoring."); + return 1; + + case BUS_NAME_IN_QUEUE: + log_debug("In queue for requested service name."); + return 1; + + case BUS_NAME_PRIMARY_OWNER: + log_debug("Successfully acquired requested service name."); + return 1; + + case BUS_NAME_EXISTS: + log_debug("Requested service name already owned, failing connection."); + bus_enter_closing(sd_bus_message_get_bus(m)); + return 1; + } + + log_debug("Unexpected response from RequestName(), failing connection."); + bus_enter_closing(sd_bus_message_get_bus(m)); + return 1; +} + +_public_ int sd_bus_request_name_async( + sd_bus *bus, + sd_bus_slot **ret_slot, + const char *name, + uint64_t flags, + sd_bus_message_handler_t callback, + void *userdata) { + + uint32_t param = 0; + int r; + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(name, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); - assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL); + + r = validate_request_name_parameters(bus, name, flags, ¶m); + if (r < 0) + return r; + + return sd_bus_call_method_async( + bus, + ret_slot, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "RequestName", + callback ?: default_request_name_handler, + userdata, + "su", + name, + param); +} + +static int validate_release_name_parameters( + sd_bus *bus, + const char *name) { + + assert(bus); + assert(name); + assert_return(service_name_is_valid(name), -EINVAL); assert_return(name[0] != ':', -EINVAL); if (!bus->bus_client) return -EINVAL; - /* Don't allow requesting the special driver and local names */ + /* Don't allow releasing the special driver and local names */ if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local")) return -EINVAL; if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; - return bus_request_name_dbus1(bus, name, flags); + return 0; } -static int bus_release_name_dbus1(sd_bus *bus, const char *name) { +_public_ int sd_bus_release_name( + sd_bus *bus, + const char *name) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; uint32_t ret; int r; - assert(bus); - assert(name); + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(name, -EINVAL); + assert_return(!bus_pid_changed(bus), -ECHILD); + + r = validate_release_name_parameters(bus, name); + if (r < 0) + return r; r = sd_bus_call_method( bus, @@ -147,41 +288,112 @@ static int bus_release_name_dbus1(sd_bus *bus, const char *name) { r = sd_bus_message_read(reply, "u", &ret); if (r < 0) return r; - if (ret == BUS_NAME_NON_EXISTENT) + + switch (ret) { + + case BUS_NAME_NON_EXISTENT: return -ESRCH; - if (ret == BUS_NAME_NOT_OWNER) + + case BUS_NAME_NOT_OWNER: return -EADDRINUSE; - if (ret == BUS_NAME_RELEASED) + + case BUS_NAME_RELEASED: return 0; + } + + return -EIO; +} + +static int default_release_name_handler( + sd_bus_message *m, + void *userdata, + sd_bus_error *ret_error) { + + uint32_t ret; + int r; + + assert(m); + + if (sd_bus_message_is_method_error(m, NULL)) { + log_debug_errno(sd_bus_message_get_errno(m), + "Unable to release name, failing connection: %s", + sd_bus_message_get_error(m)->message); + + bus_enter_closing(sd_bus_message_get_bus(m)); + return 1; + } - return -EINVAL; + r = sd_bus_message_read(m, "u", &ret); + if (r < 0) + return r; + + switch (ret) { + + case BUS_NAME_NON_EXISTENT: + log_debug("Name asked to release is not taken currently, ignoring."); + return 1; + + case BUS_NAME_NOT_OWNER: + log_debug("Name asked to release is owned by somebody else, ignoring."); + return 1; + + case BUS_NAME_RELEASED: + log_debug("Name successfully released."); + return 1; + } + + log_debug("Unexpected response from ReleaseName(), failing connection."); + bus_enter_closing(sd_bus_message_get_bus(m)); + return 1; } -_public_ int sd_bus_release_name(sd_bus *bus, const char *name) { +_public_ int sd_bus_release_name_async( + sd_bus *bus, + sd_bus_slot **ret_slot, + const char *name, + sd_bus_message_handler_t callback, + void *userdata) { + + int r; + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(name, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); - assert_return(service_name_is_valid(name), -EINVAL); - assert_return(name[0] != ':', -EINVAL); - if (!bus->bus_client) - return -EINVAL; - - /* Don't allow releasing the special driver and local names */ - if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local")) - return -EINVAL; - - if (!BUS_IS_OPEN(bus->state)) - return -ENOTCONN; + r = validate_release_name_parameters(bus, name); + if (r < 0) + return r; - return bus_release_name_dbus1(bus, name); + return sd_bus_call_method_async( + bus, + ret_slot, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "ReleaseName", + callback ?: default_release_name_handler, + userdata, + "s", + name); } -static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) { +_public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_strv_free_ char **x = NULL, **y = NULL; int r; + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(acquired || activatable, -EINVAL); + assert_return(!bus_pid_changed(bus), -ECHILD); + + if (!bus->bus_client) + return -EINVAL; + + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + if (acquired) { r = sd_bus_call_method( bus, @@ -231,21 +443,7 @@ static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatab return 0; } -_public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) { - assert_return(bus, -EINVAL); - assert_return(acquired || activatable, -EINVAL); - assert_return(!bus_pid_changed(bus), -ECHILD); - - if (!bus->bus_client) - return -EINVAL; - - if (!BUS_IS_OPEN(bus->state)) - return -ENOTCONN; - - return bus_list_names_dbus1(bus, acquired, activatable); -} - -static int bus_get_name_creds_dbus1( +_public_ int sd_bus_get_name_creds( sd_bus *bus, const char *name, uint64_t mask, @@ -257,6 +455,31 @@ static int bus_get_name_creds_dbus1( pid_t pid = 0; int r; + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(name, -EINVAL); + assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP); + assert_return(mask == 0 || creds, -EINVAL); + assert_return(!bus_pid_changed(bus), -ECHILD); + assert_return(service_name_is_valid(name), -EINVAL); + + if (!bus->bus_client) + return -EINVAL; + + /* Turn off augmenting if this isn't a local connection. If the connection is not local, then /proc is not + * going to match. */ + if (!bus->is_local) + mask &= ~SD_BUS_CREDS_AUGMENT; + + if (streq(name, "org.freedesktop.DBus.Local")) + return -EINVAL; + + if (streq(name, "org.freedesktop.DBus")) + return sd_bus_get_owner_creds(bus, mask, creds); + + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + /* Only query the owner if the caller wants to know it or if * the caller just wants to check whether a name exists */ if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) { @@ -519,51 +742,29 @@ static int bus_get_name_creds_dbus1( return 0; } -_public_ int sd_bus_get_name_creds( - sd_bus *bus, - const char *name, - uint64_t mask, - sd_bus_creds **creds) { +_public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) { + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL; + bool do_label, do_groups; + pid_t pid = 0; + int r; assert_return(bus, -EINVAL); - assert_return(name, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP); - assert_return(mask == 0 || creds, -EINVAL); + assert_return(ret, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); - assert_return(service_name_is_valid(name), -EINVAL); - - if (!bus->bus_client) - return -EINVAL; - - /* Turn off augmenting if this isn't a local connection. If the connection is not local, then /proc is not - * going to match. */ - if (!bus->is_local) - mask &= ~SD_BUS_CREDS_AUGMENT; - - if (streq(name, "org.freedesktop.DBus.Local")) - return -EINVAL; - - if (streq(name, "org.freedesktop.DBus")) - return sd_bus_get_owner_creds(bus, mask, creds); if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; - return bus_get_name_creds_dbus1(bus, name, mask, creds); -} - -static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) { - _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL; - pid_t pid = 0; - bool do_label; - int r; - - assert(bus); + if (!bus->is_local) + mask &= ~SD_BUS_CREDS_AUGMENT; do_label = bus->label && (mask & SD_BUS_CREDS_SELINUX_CONTEXT); + do_groups = bus->n_groups != (size_t) -1 && (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS); /* Avoid allocating anything if we have no chance of returning useful data */ - if (!bus->ucred_valid && !do_label) + if (!bus->ucred_valid && !do_label && !do_groups) return -ENODATA; c = bus_creds_new(); @@ -571,17 +772,17 @@ static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds ** return -ENOMEM; if (bus->ucred_valid) { - if (bus->ucred.pid > 0) { + if (pid_is_valid(bus->ucred.pid)) { pid = c->pid = bus->ucred.pid; c->mask |= SD_BUS_CREDS_PID & mask; } - if (bus->ucred.uid != UID_INVALID) { + if (uid_is_valid(bus->ucred.uid)) { c->euid = bus->ucred.uid; c->mask |= SD_BUS_CREDS_EUID & mask; } - if (bus->ucred.gid != GID_INVALID) { + if (gid_is_valid(bus->ucred.gid)) { c->egid = bus->ucred.gid; c->mask |= SD_BUS_CREDS_EGID & mask; } @@ -595,6 +796,16 @@ static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds ** c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT; } + if (do_groups) { + c->supplementary_gids = newdup(gid_t, bus->groups, bus->n_groups); + if (!c->supplementary_gids) + return -ENOMEM; + + c->n_supplementary_gids = bus->n_groups; + + c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS; + } + r = bus_creds_add_more(c, mask, pid, 0); if (r < 0) return r; @@ -604,36 +815,23 @@ static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds ** return 0; } -_public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) { - assert_return(bus, -EINVAL); - assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP); - assert_return(ret, -EINVAL); - assert_return(!bus_pid_changed(bus), -ECHILD); - - if (!BUS_IS_OPEN(bus->state)) - return -ENOTCONN; - - if (!bus->is_local) - mask &= ~SD_BUS_CREDS_AUGMENT; - - return bus_get_owner_creds_dbus1(bus, mask, ret); -} - -#define internal_match(bus, m) \ - ((bus)->hello_flags & KDBUS_HELLO_MONITOR \ +#define append_eavesdrop(bus, m) \ + ((bus)->is_monitor \ ? (isempty(m) ? "eavesdrop='true'" : strjoina((m), ",eavesdrop='true'")) \ : (m)) -static int bus_add_match_internal_dbus1( +int bus_add_match_internal( sd_bus *bus, const char *match) { const char *e; assert(bus); - assert(match); - e = internal_match(bus, match); + if (!bus->bus_client) + return -EINVAL; + + e = append_eavesdrop(bus, match); return sd_bus_call_method( bus, @@ -646,22 +844,36 @@ static int bus_add_match_internal_dbus1( "s", e); } - -int bus_add_match_internal( +int bus_add_match_internal_async( sd_bus *bus, + sd_bus_slot **ret_slot, const char *match, - struct bus_match_component *components, - unsigned n_components) { + sd_bus_message_handler_t callback, + void *userdata) { + + const char *e; assert(bus); if (!bus->bus_client) return -EINVAL; - return bus_add_match_internal_dbus1(bus, match); + e = append_eavesdrop(bus, match); + + return sd_bus_call_method_async( + bus, + ret_slot, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "AddMatch", + callback, + userdata, + "s", + e); } -static int bus_remove_match_internal_dbus1( +int bus_remove_match_internal( sd_bus *bus, const char *match) { @@ -670,10 +882,16 @@ static int bus_remove_match_internal_dbus1( assert(bus); assert(match); - e = internal_match(bus, match); + if (!bus->bus_client) + return -EINVAL; - return sd_bus_call_method( + e = append_eavesdrop(bus, match); + + /* Fire and forget */ + + return sd_bus_call_method_async( bus, + NULL, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", @@ -684,24 +902,13 @@ static int bus_remove_match_internal_dbus1( e); } -int bus_remove_match_internal( - sd_bus *bus, - const char *match) { - - assert(bus); - - if (!bus->bus_client) - return -EINVAL; - - return bus_remove_match_internal_dbus1(bus, match); -} - _public_ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL; const char *mid; int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(name, -EINVAL); assert_return(machine, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); diff --git a/src/libsystemd/sd-bus/bus-control.h b/src/libsystemd/sd-bus/bus-control.h index c9d434c607..3d9acebaf6 100644 --- a/src/libsystemd/sd-bus/bus-control.h +++ b/src/libsystemd/sd-bus/bus-control.h @@ -22,7 +22,7 @@ #include "sd-bus.h" -#include "bus-match.h" +int bus_add_match_internal(sd_bus *bus, const char *match); +int bus_add_match_internal_async(sd_bus *bus, sd_bus_slot **ret, const char *match, sd_bus_message_handler_t callback, void *userdata); -int bus_add_match_internal(sd_bus *bus, const char *match, struct bus_match_component *components, unsigned n_components); int bus_remove_match_internal(sd_bus *bus, const char *match); diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index 9d3b596429..8da6640ca0 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -36,6 +36,7 @@ _public_ int sd_bus_emit_signal( int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); if (!BUS_IS_OPEN(bus->state)) @@ -73,6 +74,7 @@ _public_ int sd_bus_call_method_async( int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); if (!BUS_IS_OPEN(bus->state)) @@ -615,3 +617,71 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) return 0; } + +#define make_expression(sender, path, interface, member) \ + strjoina( \ + "type='signal'", \ + sender ? ",sender='" : "", \ + sender ?: "", \ + sender ? "'" : "", \ + path ? ",path='" : "", \ + path ?: "", \ + path ? "'" : "", \ + interface ? ",interface='" : "", \ + interface ?: "", \ + interface ? "'" : "", \ + member ? ",member='" : "", \ + member ?: "", \ + member ? "'" : "" \ + ) + +_public_ int sd_bus_match_signal( + sd_bus *bus, + sd_bus_slot **ret, + const char *sender, + const char *path, + const char *interface, + const char *member, + sd_bus_message_handler_t callback, + void *userdata) { + + const char *expression; + + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(!bus_pid_changed(bus), -ECHILD); + assert_return(!sender || service_name_is_valid(sender), -EINVAL); + assert_return(!path || object_path_is_valid(path), -EINVAL); + assert_return(!interface || interface_name_is_valid(interface), -EINVAL); + assert_return(!member || member_name_is_valid(member), -EINVAL); + + expression = make_expression(sender, path, interface, member); + + return sd_bus_add_match(bus, ret, expression, callback, userdata); +} + +_public_ int sd_bus_match_signal_async( + sd_bus *bus, + sd_bus_slot **ret, + const char *sender, + const char *path, + const char *interface, + const char *member, + sd_bus_message_handler_t callback, + sd_bus_message_handler_t install_callback, + void *userdata) { + + const char *expression; + + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(!bus_pid_changed(bus), -ECHILD); + assert_return(!sender || service_name_is_valid(sender), -EINVAL); + assert_return(!path || object_path_is_valid(path), -EINVAL); + assert_return(!interface || interface_name_is_valid(interface), -EINVAL); + assert_return(!member || member_name_is_valid(member), -EINVAL); + + expression = make_expression(sender, path, interface, member); + + return sd_bus_add_match_async(bus, ret, expression, callback, install_callback, userdata); +} diff --git a/src/libsystemd/sd-bus/bus-gvariant.c b/src/libsystemd/sd-bus/bus-gvariant.c index 6a990a02c0..e6ab984d1f 100644 --- a/src/libsystemd/sd-bus/bus-gvariant.c +++ b/src/libsystemd/sd-bus/bus-gvariant.c @@ -18,6 +18,11 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> +#include <string.h> + +#include "sd-bus.h" + #include "bus-gvariant.h" #include "bus-signature.h" #include "bus-type.h" diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c index 3c381b0ffe..05a022fbf3 100644 --- a/src/libsystemd/sd-bus/bus-internal.c +++ b/src/libsystemd/sd-bus/bus-internal.c @@ -362,13 +362,18 @@ int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) { } else return r; - log_debug("Failed to process message [type=%s sender=%s path=%s interface=%s member=%s signature=%s]: %s", + log_debug("Failed to process message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s: %s", bus_message_type_to_string(m->header->type), - strna(m->sender), - strna(m->path), - strna(m->interface), - strna(m->member), + strna(sd_bus_message_get_sender(m)), + strna(sd_bus_message_get_destination(m)), + strna(sd_bus_message_get_path(m)), + strna(sd_bus_message_get_interface(m)), + strna(sd_bus_message_get_member(m)), + BUS_MESSAGE_COOKIE(m), + m->reply_cookie, strna(m->root_container.signature), + strna(m->error.name), + strna(m->error.message), bus_error_message(error, r)); return 1; diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 378c408ea3..1b55cdafed 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -38,7 +38,7 @@ struct reply_callback { sd_bus_message_handler_t callback; - usec_t timeout; + usec_t timeout_usec; /* this is a relative timeout until we reach the BUS_HELLO state, and an absolute one right after */ uint64_t cookie; unsigned prioq_idx; }; @@ -53,6 +53,9 @@ struct filter_callback { struct match_callback { sd_bus_message_handler_t callback; + sd_bus_message_handler_t install_callback; + + sd_bus_slot *install_slot; /* The AddMatch() call */ unsigned last_iteration; @@ -157,12 +160,14 @@ struct sd_bus_slot { enum bus_state { BUS_UNSET, - BUS_OPENING, - BUS_AUTHENTICATING, - BUS_HELLO, + BUS_WATCH_BIND, /* waiting for the socket to appear via inotify */ + BUS_OPENING, /* the kernel's connect() is still not ready */ + BUS_AUTHENTICATING, /* we are currently in the "SASL" authorization phase of dbus */ + BUS_HELLO, /* we are waiting for the Hello() response */ BUS_RUNNING, BUS_CLOSING, - BUS_CLOSED + BUS_CLOSED, + _BUS_STATE_MAX, }; static inline bool BUS_IS_OPEN(enum bus_state state) { @@ -188,6 +193,7 @@ struct sd_bus { enum bus_state state; int input_fd, output_fd; + int inotify_fd; int message_version; int message_endian; @@ -210,6 +216,11 @@ struct sd_bus { bool exited:1; bool exit_triggered:1; bool is_local:1; + bool watch_bind:1; + bool is_monitor:1; + bool accept_fd:1; + bool attach_timestamp:1; + bool connected_signal:1; int use_memfd; @@ -261,6 +272,8 @@ struct sd_bus { struct ucred ucred; char *label; + gid_t *groups; + size_t n_groups; uint64_t creds_mask; @@ -284,13 +297,11 @@ struct sd_bus { pid_t original_pid; - uint64_t hello_flags; - uint64_t attach_flags; - sd_event_source *input_io_event_source; sd_event_source *output_io_event_source; sd_event_source *time_event_source; sd_event_source *quit_event_source; + sd_event_source *inotify_event_source; sd_event *event; int event_priority; @@ -305,11 +316,15 @@ struct sd_bus { char *cgroup_root; char *description; + char *patch_sender; sd_bus_track *track_queue; LIST_HEAD(sd_bus_slot, slots); LIST_HEAD(sd_bus_track, tracks); + + int *inotify_watches; + size_t n_inotify_watches; }; /* For method calls we time-out at 25s, like in the D-Bus reference implementation */ @@ -353,6 +368,8 @@ const char *bus_message_type_to_string(uint8_t u) _pure_; #define error_name_is_valid interface_name_is_valid +sd_bus *bus_resolve(sd_bus *bus); + int bus_ensure_running(sd_bus *bus); int bus_start_running(sd_bus *bus); int bus_next_address(sd_bus *bus); @@ -365,6 +382,12 @@ bool bus_pid_changed(sd_bus *bus); char *bus_address_escape(const char *v); +int bus_attach_io_events(sd_bus *b); +int bus_attach_inotify_event(sd_bus *b); + +void bus_close_inotify_fd(sd_bus *b); +void bus_close_io_fds(sd_bus *b); + #define OBJECT_PATH_FOREACH_PREFIX(prefix, path) \ for (char *_slash = ({ strcpy((prefix), (path)); streq((prefix), "/") ? NULL : strrchr((prefix), '/'); }) ; \ _slash && !(_slash[(_slash) == (prefix)] = 0); \ @@ -381,8 +404,6 @@ int bus_set_address_user(sd_bus *bus); int bus_set_address_system_remote(sd_bus *b, const char *host); int bus_set_address_system_machine(sd_bus *b, const char *machine); -int bus_remove_match_by_string(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata); - int bus_get_root_path(sd_bus *bus); int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error); @@ -393,64 +414,6 @@ int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error); return sd_bus_error_set_errno(error, r); \ } while (false) -/** - * enum kdbus_attach_flags - flags for metadata attachments - * @KDBUS_ATTACH_TIMESTAMP: Timestamp - * @KDBUS_ATTACH_CREDS: Credentials - * @KDBUS_ATTACH_PIDS: PIDs - * @KDBUS_ATTACH_AUXGROUPS: Auxiliary groups - * @KDBUS_ATTACH_NAMES: Well-known names - * @KDBUS_ATTACH_TID_COMM: The "comm" process identifier of the TID - * @KDBUS_ATTACH_PID_COMM: The "comm" process identifier of the PID - * @KDBUS_ATTACH_EXE: The path of the executable - * @KDBUS_ATTACH_CMDLINE: The process command line - * @KDBUS_ATTACH_CGROUP: The croup membership - * @KDBUS_ATTACH_CAPS: The process capabilities - * @KDBUS_ATTACH_SECLABEL: The security label - * @KDBUS_ATTACH_AUDIT: The audit IDs - * @KDBUS_ATTACH_CONN_DESCRIPTION: The human-readable connection name - * @_KDBUS_ATTACH_ALL: All of the above - * @_KDBUS_ATTACH_ANY: Wildcard match to enable any kind of - * metatdata. - */ -enum kdbus_attach_flags { - KDBUS_ATTACH_TIMESTAMP = 1ULL << 0, - KDBUS_ATTACH_CREDS = 1ULL << 1, - KDBUS_ATTACH_PIDS = 1ULL << 2, - KDBUS_ATTACH_AUXGROUPS = 1ULL << 3, - KDBUS_ATTACH_NAMES = 1ULL << 4, - KDBUS_ATTACH_TID_COMM = 1ULL << 5, - KDBUS_ATTACH_PID_COMM = 1ULL << 6, - KDBUS_ATTACH_EXE = 1ULL << 7, - KDBUS_ATTACH_CMDLINE = 1ULL << 8, - KDBUS_ATTACH_CGROUP = 1ULL << 9, - KDBUS_ATTACH_CAPS = 1ULL << 10, - KDBUS_ATTACH_SECLABEL = 1ULL << 11, - KDBUS_ATTACH_AUDIT = 1ULL << 12, - KDBUS_ATTACH_CONN_DESCRIPTION = 1ULL << 13, - _KDBUS_ATTACH_ALL = (1ULL << 14) - 1, - _KDBUS_ATTACH_ANY = ~0ULL -}; +void bus_enter_closing(sd_bus *bus); -/** - * enum kdbus_hello_flags - flags for struct kdbus_cmd_hello - * @KDBUS_HELLO_ACCEPT_FD: The connection allows the reception of - * any passed file descriptors - * @KDBUS_HELLO_ACTIVATOR: Special-purpose connection which registers - * a well-know name for a process to be started - * when traffic arrives - * @KDBUS_HELLO_POLICY_HOLDER: Special-purpose connection which registers - * policy entries for a name. The provided name - * is not activated and not registered with the - * name database, it only allows unprivileged - * connections to acquire a name, talk or discover - * a service - * @KDBUS_HELLO_MONITOR: Special-purpose connection to monitor - * bus traffic - */ -enum kdbus_hello_flags { - KDBUS_HELLO_ACCEPT_FD = 1ULL << 0, - KDBUS_HELLO_ACTIVATOR = 1ULL << 1, - KDBUS_HELLO_POLICY_HOLDER = 1ULL << 2, - KDBUS_HELLO_MONITOR = 1ULL << 3, -}; +void bus_set_state(sd_bus *bus, enum bus_state state); diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index c6179b4d95..b27b9d7d86 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -66,49 +66,3 @@ void bus_flush_memfd(sd_bus *b) { for (i = 0; i < b->n_memfd_cache; i++) close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped); } - -uint64_t attach_flags_to_kdbus(uint64_t mask) { - uint64_t m = 0; - - if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID| - SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) - m |= KDBUS_ATTACH_CREDS; - - if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID|SD_BUS_CREDS_PPID)) - m |= KDBUS_ATTACH_PIDS; - - if (mask & SD_BUS_CREDS_COMM) - m |= KDBUS_ATTACH_PID_COMM; - - if (mask & SD_BUS_CREDS_TID_COMM) - m |= KDBUS_ATTACH_TID_COMM; - - if (mask & SD_BUS_CREDS_EXE) - m |= KDBUS_ATTACH_EXE; - - if (mask & SD_BUS_CREDS_CMDLINE) - m |= KDBUS_ATTACH_CMDLINE; - - if (mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID)) - m |= KDBUS_ATTACH_CGROUP; - - if (mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) - m |= KDBUS_ATTACH_CAPS; - - if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) - m |= KDBUS_ATTACH_SECLABEL; - - if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) - m |= KDBUS_ATTACH_AUDIT; - - if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) - m |= KDBUS_ATTACH_NAMES; - - if (mask & SD_BUS_CREDS_DESCRIPTION) - m |= KDBUS_ATTACH_CONN_DESCRIPTION; - - if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) - m |= KDBUS_ATTACH_AUXGROUPS; - - return m; -} diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h index d9f80935fe..fa78e5c80d 100644 --- a/src/libsystemd/sd-bus/bus-kernel.h +++ b/src/libsystemd/sd-bus/bus-kernel.h @@ -41,5 +41,3 @@ struct memfd_cache { void close_and_munmap(int fd, void *address, size_t size); void bus_flush_memfd(sd_bus *bus); - -uint64_t attach_flags_to_kdbus(uint64_t sd_bus_flags); diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index 219cff1f6e..95a87da08b 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -127,7 +127,6 @@ static void message_free(sd_bus_message *m) { if (m->iovec != m->iovec_fixed) free(m->iovec); - m->destination_ptr = mfree(m->destination_ptr); message_reset_containers(m); free(m->root_container.signature); free(m->root_container.offsets); @@ -1321,7 +1320,9 @@ static void *message_extend_body( m->n_body_parts <= 0 || m->body_end->sealed || (padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size) || - (force_inline && m->body_end->size > MEMFD_MIN_SIZE); /* if this must be an inlined extension, let's create a new part if the previous part is large enough to be inlined */ + (force_inline && m->body_end->size > MEMFD_MIN_SIZE); + /* If this must be an inlined extension, let's create a new part if + * the previous part is large enough to be inlined. */ if (add_new_part) { if (padding > 0) { @@ -1368,7 +1369,7 @@ static void *message_extend_body( } } else /* Return something that is not NULL and is aligned */ - p = (uint8_t *) NULL + align; + p = (uint8_t*) align; m->body_size = end_body; message_extend_containers(m, added); @@ -4779,7 +4780,7 @@ _public_ int sd_bus_message_read_array( if (sz == 0) /* Zero length array, let's return some aligned * pointer that is not NULL */ - p = (uint8_t*) NULL + align; + p = (uint8_t*) align; else { r = message_peek_body(m, &m->rindex, align, sz, &p); if (r < 0) @@ -5488,6 +5489,15 @@ _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *desti return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination); } +_public_ int sd_bus_message_set_sender(sd_bus_message *m, const char *sender) { + assert_return(m, -EINVAL); + assert_return(sender, -EINVAL); + assert_return(!m->sealed, -EPERM); + assert_return(!m->sender, -EEXIST); + + return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender); +} + int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) { size_t total; void *p, *e; diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h index 1e4b20926d..88998700d6 100644 --- a/src/libsystemd/sd-bus/bus-message.h +++ b/src/libsystemd/sd-bus/bus-message.h @@ -136,10 +136,6 @@ struct sd_bus_message { usec_t timeout; - char sender_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1]; - char destination_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1]; - char *destination_ptr; - size_t header_offsets[_BUS_MESSAGE_HEADER_MAX]; unsigned n_header_offsets; }; diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index 121197bbcb..6e00255b20 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -1369,7 +1369,7 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) { assert(bus); assert(m); - if (bus->hello_flags & KDBUS_HELLO_MONITOR) + if (bus->is_monitor) return 0; if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL) @@ -1547,6 +1547,7 @@ static int bus_add_object( int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(callback, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -1650,6 +1651,7 @@ static int add_object_vtable_internal( int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(interface_name_is_valid(interface), -EINVAL); assert_return(vtable, -EINVAL); @@ -1859,6 +1861,7 @@ _public_ int sd_bus_add_node_enumerator( int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(callback, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2110,6 +2113,7 @@ _public_ int sd_bus_emit_properties_changed_strv( int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(interface_name_is_valid(interface), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2156,6 +2160,7 @@ _public_ int sd_bus_emit_properties_changed( char **names; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(interface_name_is_valid(interface), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2340,6 +2345,7 @@ _public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) { */ assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2510,6 +2516,7 @@ _public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) { */ assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2663,6 +2670,7 @@ _public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, ch int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2729,6 +2737,7 @@ _public_ int sd_bus_emit_interfaces_added(sd_bus *bus, const char *path, const c char **interfaces; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2746,6 +2755,7 @@ _public_ int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2780,6 +2790,7 @@ _public_ int sd_bus_emit_interfaces_removed(sd_bus *bus, const char *path, const char **interfaces; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2797,6 +2808,7 @@ _public_ int sd_bus_add_object_manager(sd_bus *bus, sd_bus_slot **slot, const ch int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(object_path_is_valid(path), -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); diff --git a/src/libsystemd/sd-bus/bus-signature.c b/src/libsystemd/sd-bus/bus-signature.c index d16461f4ae..f3cd9bd0fa 100644 --- a/src/libsystemd/sd-bus/bus-signature.c +++ b/src/libsystemd/sd-bus/bus-signature.c @@ -20,6 +20,8 @@ #include <util.h> +#include "sd-bus.h" + #include "bus-signature.h" #include "bus-type.h" diff --git a/src/libsystemd/sd-bus/bus-slot.c b/src/libsystemd/sd-bus/bus-slot.c index 756761c3ed..9a56371715 100644 --- a/src/libsystemd/sd-bus/bus-slot.c +++ b/src/libsystemd/sd-bus/bus-slot.c @@ -81,7 +81,7 @@ void bus_slot_disconnect(sd_bus_slot *slot) { if (slot->reply_callback.cookie != 0) ordered_hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie); - if (slot->reply_callback.timeout != 0) + if (slot->reply_callback.timeout_usec != 0) prioq_remove(slot->bus->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx); break; @@ -94,12 +94,17 @@ void bus_slot_disconnect(sd_bus_slot *slot) { case BUS_MATCH_CALLBACK: if (slot->match_added) - bus_remove_match_internal(slot->bus, slot->match_callback.match_string); + (void) bus_remove_match_internal(slot->bus, slot->match_callback.match_string); + + if (slot->match_callback.install_slot) { + bus_slot_disconnect(slot->match_callback.install_slot); + slot->match_callback.install_slot = sd_bus_slot_unref(slot->match_callback.install_slot); + } slot->bus->match_callbacks_modified = true; bus_match_remove(&slot->bus->match_callbacks, &slot->match_callback); - free(slot->match_callback.match_string); + slot->match_callback.match_string = mfree(slot->match_callback.match_string); break; @@ -174,7 +179,7 @@ void bus_slot_disconnect(sd_bus_slot *slot) { } } - free(slot->node_vtable.interface); + slot->node_vtable.interface = mfree(slot->node_vtable.interface); if (slot->node_vtable.node) { LIST_REMOVE(vtables, slot->node_vtable.node->vtables, &slot->node_vtable); diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index 07a9c8affd..2fe86b61c4 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -32,9 +32,13 @@ #include "bus-socket.h" #include "fd-util.h" #include "format-util.h" +#include "fs-util.h" #include "hexdecoct.h" +#include "io-util.h" #include "macro.h" #include "missing.h" +#include "path-util.h" +#include "process-util.h" #include "selinux-util.h" #include "signal-util.h" #include "stdio-util.h" @@ -188,7 +192,7 @@ static int bus_socket_auth_verify_client(sd_bus *b) { if (!e) return 0; - if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) { + if (b->accept_fd) { f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2); if (!f) return 0; @@ -475,7 +479,7 @@ static int bus_socket_auth_verify_server(sd_bus *b) { r = bus_socket_auth_write_ok(b); } } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) { - if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD)) + if (b->auth == _BUS_AUTH_INVALID || !b->accept_fd) r = bus_socket_auth_write(b, "ERROR\r\n"); else { b->can_fds = true; @@ -592,8 +596,8 @@ void bus_socket_setup(sd_bus *b) { assert(b); /* Increase the buffers to 8 MB */ - fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE); - fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE); + (void) fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE); + (void) fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE); b->message_version = 1; b->message_endian = 0; @@ -603,16 +607,24 @@ static void bus_get_peercred(sd_bus *b) { int r; assert(b); + assert(!b->ucred_valid); + assert(!b->label); + assert(b->n_groups == (size_t) -1); /* Get the peer for socketpair() sockets */ b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0; /* Get the SELinux context of the peer */ - if (mac_selinux_use()) { - r = getpeersec(b->input_fd, &b->label); - if (r < 0 && r != -EOPNOTSUPP) - log_debug_errno(r, "Failed to determine peer security context: %m"); - } + r = getpeersec(b->input_fd, &b->label); + if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT)) + log_debug_errno(r, "Failed to determine peer security context: %m"); + + /* Get the list of auxiliary groups of the peer */ + r = getpeergroups(b->input_fd, &b->groups); + if (r >= 0) + b->n_groups = (size_t) r; + else if (!IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT)) + log_debug_errno(r, "Failed to determine peer's group list: %m"); } static int bus_socket_start_auth_client(sd_bus *b) { @@ -641,7 +653,7 @@ static int bus_socket_start_auth_client(sd_bus *b) { if (!b->auth_buffer) return -ENOMEM; - if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) + if (b->accept_fd) auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n"; else auth_suffix = "\r\nBEGIN\r\n"; @@ -661,15 +673,15 @@ int bus_socket_start_auth(sd_bus *b) { bus_get_peercred(b); - b->state = BUS_AUTHENTICATING; + bus_set_state(b, BUS_AUTHENTICATING); b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_AUTH_TIMEOUT; if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0) - b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD; + b->accept_fd = false; if (b->output_fd != b->input_fd) if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0) - b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD; + b->accept_fd = false; if (b->is_server) return bus_socket_read_auth(b); @@ -677,30 +689,249 @@ int bus_socket_start_auth(sd_bus *b) { return bus_socket_start_auth_client(b); } +static int bus_socket_inotify_setup(sd_bus *b) { + _cleanup_free_ int *new_watches = NULL; + _cleanup_free_ char *absolute = NULL; + size_t n_allocated = 0, n = 0, done = 0, i; + unsigned max_follow = 32; + const char *p; + int wd, r; + + assert(b); + assert(b->watch_bind); + assert(b->sockaddr.sa.sa_family == AF_UNIX); + assert(b->sockaddr.un.sun_path[0] != 0); + + /* Sets up an inotify fd in case watch_bind is enabled: wait until the configured AF_UNIX file system socket + * appears before connecting to it. The implemented is pretty simplistic: we just subscribe to relevant changes + * to all prefix components of the path, and every time we get an event for that we try to reconnect again, + * without actually caring what precisely the event we got told us. If we still can't connect we re-subscribe + * to all relevant changes of anything in the path, so that our watches include any possibly newly created path + * components. */ + + if (b->inotify_fd < 0) { + b->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); + if (b->inotify_fd < 0) + return -errno; + } + + /* Make sure the path is NUL terminated */ + p = strndupa(b->sockaddr.un.sun_path, sizeof(b->sockaddr.un.sun_path)); + + /* Make sure the path is absolute */ + r = path_make_absolute_cwd(p, &absolute); + if (r < 0) + goto fail; + + /* Watch all parent directories, and don't mind any prefix that doesn't exist yet. For the innermost directory + * that exists we want to know when files are created or moved into it. For all parents of it we just care if + * they are removed or renamed. */ + + if (!GREEDY_REALLOC(new_watches, n_allocated, n + 1)) { + r = -ENOMEM; + goto fail; + } + + /* Start with the top-level directory, which is a bit simpler than the rest, since it can't be a symlink, and + * always exists */ + wd = inotify_add_watch(b->inotify_fd, "/", IN_CREATE|IN_MOVED_TO); + if (wd < 0) { + r = log_debug_errno(errno, "Failed to add inotify watch on /: %m"); + goto fail; + } else + new_watches[n++] = wd; + + for (;;) { + _cleanup_free_ char *component = NULL, *prefix = NULL, *destination = NULL; + size_t n_slashes, n_component; + char *c = NULL; + + n_slashes = strspn(absolute + done, "/"); + n_component = n_slashes + strcspn(absolute + done + n_slashes, "/"); + + if (n_component == 0) /* The end */ + break; + + component = strndup(absolute + done, n_component); + if (!component) { + r = -ENOMEM; + goto fail; + } + + /* A trailing slash? That's a directory, and not a socket then */ + if (path_equal(component, "/")) { + r = -EISDIR; + goto fail; + } + + /* A single dot? Let's eat this up */ + if (path_equal(component, "/.")) { + done += n_component; + continue; + } + + prefix = strndup(absolute, done + n_component); + if (!prefix) { + r = -ENOMEM; + goto fail; + } + + if (!GREEDY_REALLOC(new_watches, n_allocated, n + 1)) { + r = -ENOMEM; + goto fail; + } + + wd = inotify_add_watch(b->inotify_fd, prefix, IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO|IN_DONT_FOLLOW); + log_debug("Added inotify watch for %s on bus %s: %i", prefix, strna(b->description), wd); + + if (wd < 0) { + if (IN_SET(errno, ENOENT, ELOOP)) + break; /* This component doesn't exist yet, or the path contains a cyclic symlink right now */ + + r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", isempty(prefix) ? "/" : prefix); + goto fail; + } else + new_watches[n++] = wd; + + /* Check if this is possibly a symlink. If so, let's follow it and watch it too. */ + r = readlink_malloc(prefix, &destination); + if (r == -EINVAL) { /* not a symlink */ + done += n_component; + continue; + } + if (r < 0) + goto fail; + + if (isempty(destination)) { /* Empty symlink target? Yuck! */ + r = -EINVAL; + goto fail; + } + + if (max_follow <= 0) { /* Let's make sure we don't follow symlinks forever */ + r = -ELOOP; + goto fail; + } + + if (path_is_absolute(destination)) { + /* For absolute symlinks we build the new path and start anew */ + c = strjoin(destination, absolute + done + n_component); + done = 0; + } else { + _cleanup_free_ char *t = NULL; + + /* For relative symlinks we replace the last component, and try again */ + t = strndup(absolute, done); + if (!t) + return -ENOMEM; + + c = strjoin(t, "/", destination, absolute + done + n_component); + } + if (!c) { + r = -ENOMEM; + goto fail; + } + + free(absolute); + absolute = c; + + max_follow--; + } + + /* And now, let's remove all watches from the previous iteration we don't need anymore */ + for (i = 0; i < b->n_inotify_watches; i++) { + bool found = false; + size_t j; + + for (j = 0; j < n; j++) + if (new_watches[j] == b->inotify_watches[i]) { + found = true; + break; + } + + if (found) + continue; + + (void) inotify_rm_watch(b->inotify_fd, b->inotify_watches[i]); + } + + free_and_replace(b->inotify_watches, new_watches); + b->n_inotify_watches = n; + + return 0; + +fail: + bus_close_inotify_fd(b); + return r; +} + int bus_socket_connect(sd_bus *b) { + bool inotify_done = false; int r; assert(b); - assert(b->input_fd < 0); - assert(b->output_fd < 0); - assert(b->sockaddr.sa.sa_family != AF_UNSPEC); - b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); - if (b->input_fd < 0) - return -errno; + for (;;) { + assert(b->input_fd < 0); + assert(b->output_fd < 0); + assert(b->sockaddr.sa.sa_family != AF_UNSPEC); - b->output_fd = b->input_fd; + b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (b->input_fd < 0) + return -errno; - bus_socket_setup(b); + b->output_fd = b->input_fd; + bus_socket_setup(b); - r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size); - if (r < 0) { - if (errno == EINPROGRESS) - return 1; + if (connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size) < 0) { + if (errno == EINPROGRESS) { - return -errno; + /* If we have any inotify watches open, close them now, we don't need them anymore, as + * we have successfully initiated a connection */ + bus_close_inotify_fd(b); + + /* Note that very likely we are already in BUS_OPENING state here, as we enter it when + * we start parsing the address string. The only reason we set the state explicitly + * here, is to undo BUS_WATCH_BIND, in case we did the inotify magic. */ + bus_set_state(b, BUS_OPENING); + return 1; + } + + if (IN_SET(errno, ENOENT, ECONNREFUSED) && /* ENOENT → unix socket doesn't exist at all; ECONNREFUSED → unix socket stale */ + b->watch_bind && + b->sockaddr.sa.sa_family == AF_UNIX && + b->sockaddr.un.sun_path[0] != 0) { + + /* This connection attempt failed, let's release the socket for now, and start with a + * fresh one when reconnecting. */ + bus_close_io_fds(b); + + if (inotify_done) { + /* inotify set up already, don't do it again, just return now, and remember + * that we are waiting for inotify events now. */ + bus_set_state(b, BUS_WATCH_BIND); + return 1; + } + + /* This is a file system socket, and the inotify logic is enabled. Let's create the necessary inotify fd. */ + r = bus_socket_inotify_setup(b); + if (r < 0) + return r; + + /* Let's now try to connect a second time, because in theory there's otherwise a race + * here: the socket might have been created in the time between our first connect() and + * the time we set up the inotify logic. But let's remember that we set up inotify now, + * so that we don't do the connect() more than twice. */ + inotify_done = true; + + } else + return -errno; + } else + break; } + /* Yay, established, we don't need no inotify anymore! */ + bus_close_inotify_fd(b); + return bus_socket_start_auth(b); } @@ -717,29 +948,24 @@ int bus_socket_exec(sd_bus *b) { if (r < 0) return -errno; - pid = fork(); - if (pid < 0) { + r = safe_fork_full("(sd-busexec)", s+1, 1, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS, &pid); + if (r < 0) { safe_close_pair(s); - return -errno; + return r; } - if (pid == 0) { + if (r == 0) { /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - - close_all_fds(s+1, 1); - assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO); assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO); if (!IN_SET(s[1], STDIN_FILENO, STDOUT_FILENO)) safe_close(s[1]); - fd_cloexec(STDIN_FILENO, false); - fd_cloexec(STDOUT_FILENO, false); - fd_nonblock(STDIN_FILENO, false); - fd_nonblock(STDOUT_FILENO, false); + (void) fd_cloexec(STDIN_FILENO, false); + (void) fd_cloexec(STDOUT_FILENO, false); + (void) fd_nonblock(STDIN_FILENO, false); + (void) fd_nonblock(STDOUT_FILENO, false); if (b->exec_argv) execvp(b->exec_path, b->exec_argv); @@ -1063,3 +1289,34 @@ int bus_socket_process_authenticating(sd_bus *b) { return bus_socket_read_auth(b); } + +int bus_socket_process_watch_bind(sd_bus *b) { + int r, q; + + assert(b); + assert(b->state == BUS_WATCH_BIND); + assert(b->inotify_fd >= 0); + + r = flush_fd(b->inotify_fd); + if (r <= 0) + return r; + + log_debug("Got inotify event on bus %s.", strna(b->description)); + + /* We flushed events out of the inotify fd. In that case, maybe the socket is valid now? Let's try to connect + * to it again */ + + r = bus_socket_connect(b); + if (r < 0) + return r; + + q = bus_attach_io_events(b); + if (q < 0) + return q; + + q = bus_attach_inotify_event(b); + if (q < 0) + return q; + + return r; +} diff --git a/src/libsystemd/sd-bus/bus-socket.h b/src/libsystemd/sd-bus/bus-socket.h index 915a283f5a..c180562f98 100644 --- a/src/libsystemd/sd-bus/bus-socket.h +++ b/src/libsystemd/sd-bus/bus-socket.h @@ -34,5 +34,6 @@ int bus_socket_read_message(sd_bus *bus); int bus_socket_process_opening(sd_bus *b); int bus_socket_process_authenticating(sd_bus *b); +int bus_socket_process_watch_bind(sd_bus *b); bool bus_socket_auth_needs_write(sd_bus *b); diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c index ab22d6e4de..5482d39a01 100644 --- a/src/libsystemd/sd-bus/bus-track.c +++ b/src/libsystemd/sd-bus/bus-track.c @@ -48,25 +48,13 @@ struct sd_bus_track { LIST_FIELDS(sd_bus_track, tracks); }; -#define MATCH_PREFIX \ - "type='signal'," \ - "sender='org.freedesktop.DBus'," \ - "path='/org/freedesktop/DBus'," \ - "interface='org.freedesktop.DBus'," \ - "member='NameOwnerChanged'," \ - "arg0='" - -#define MATCH_SUFFIX \ - "'" - -#define MATCH_FOR_NAME(name) \ - ({ \ - char *_x; \ - size_t _l = strlen(name); \ - _x = alloca(STRLEN(MATCH_PREFIX)+_l+STRLEN(MATCH_SUFFIX)+1); \ - strcpy(stpcpy(stpcpy(_x, MATCH_PREFIX), name), MATCH_SUFFIX); \ - _x; \ - }) +#define MATCH_FOR_NAME(name) \ + strjoina("type='signal'," \ + "sender='org.freedesktop.DBus'," \ + "path='/org/freedesktop/DBus'," \ + "interface='org.freedesktop.DBus'," \ + "member='NameOwnerChanged'," \ + "arg0='", name, "'") static struct track_item* track_item_free(struct track_item *i) { @@ -148,6 +136,7 @@ _public_ int sd_bus_track_new( sd_bus_track *t; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(track, -EINVAL); if (!bus->bus_client) @@ -259,9 +248,7 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { bus_track_remove_from_queue(track); /* don't dispatch this while we work in it */ - track->n_adding++; /* make sure we aren't dispatched while we synchronously add this match */ - r = sd_bus_add_match(track->bus, &n->slot, match, on_name_owner_changed, track); - track->n_adding--; + r = sd_bus_add_match_async(track->bus, &n->slot, match, on_name_owner_changed, NULL, track); if (r < 0) { bus_track_add_to_queue(track); return r; diff --git a/src/libsystemd/sd-bus/bus-type.c b/src/libsystemd/sd-bus/bus-type.c index fe486f441d..980b35d8ea 100644 --- a/src/libsystemd/sd-bus/bus-type.c +++ b/src/libsystemd/sd-bus/bus-type.c @@ -18,6 +18,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> + +#include "sd-bus.h" + #include "bus-type.h" bool bus_type_is_valid(char c) { diff --git a/src/libsystemd/sd-bus/bus-type.h b/src/libsystemd/sd-bus/bus-type.h index ae272b1e6a..834f09777a 100644 --- a/src/libsystemd/sd-bus/bus-type.h +++ b/src/libsystemd/sd-bus/bus-type.h @@ -22,8 +22,6 @@ #include <stdbool.h> -#include "sd-bus.h" - #include "macro.h" bool bus_type_is_valid(char c) _const_; diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 5fb15a7aaf..7e7ebb27a7 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -50,6 +50,7 @@ #include "macro.h" #include "missing.h" #include "parse-util.h" +#include "process-util.h" #include "string-util.h" #include "strv.h" #include "util.h" @@ -57,7 +58,7 @@ #define log_debug_bus_message(m) \ do { \ sd_bus_message *_mm = (m); \ - log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error-name=%s error-message=%s", \ + log_debug("Got message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s", \ bus_message_type_to_string(_mm->header->type), \ strna(sd_bus_message_get_sender(_mm)), \ strna(sd_bus_message_get_destination(_mm)), \ @@ -66,28 +67,97 @@ strna(sd_bus_message_get_member(_mm)), \ BUS_MESSAGE_COOKIE(_mm), \ _mm->reply_cookie, \ + strna(_mm->root_container.signature), \ strna(_mm->error.name), \ strna(_mm->error.message)); \ } while (false) static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec); -static int attach_io_events(sd_bus *b); -static void detach_io_events(sd_bus *b); +static void bus_detach_io_events(sd_bus *b); +static void bus_detach_inotify_event(sd_bus *b); static thread_local sd_bus *default_system_bus = NULL; static thread_local sd_bus *default_user_bus = NULL; static thread_local sd_bus *default_starter_bus = NULL; -static void bus_close_fds(sd_bus *b) { +static sd_bus **bus_choose_default(int (**bus_open)(sd_bus **)) { + const char *e; + + /* Let's try our best to reuse another cached connection. If + * the starter bus type is set, connect via our normal + * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that + * we can share the connection with the user/system default + * bus. */ + + e = secure_getenv("DBUS_STARTER_BUS_TYPE"); + if (e) { + if (streq(e, "system")) { + if (bus_open) + *bus_open = sd_bus_open_system; + return &default_system_bus; + } else if (STR_IN_SET(e, "user", "session")) { + if (bus_open) + *bus_open = sd_bus_open_user; + return &default_user_bus; + } + } + + /* No type is specified, so we have not other option than to + * use the starter address if it is set. */ + e = secure_getenv("DBUS_STARTER_ADDRESS"); + if (e) { + if (bus_open) + *bus_open = sd_bus_open; + return &default_starter_bus; + } + + /* Finally, if nothing is set use the cached connection for + * the right scope */ + + if (cg_pid_get_owner_uid(0, NULL) >= 0) { + if (bus_open) + *bus_open = sd_bus_open_user; + return &default_user_bus; + } else { + if (bus_open) + *bus_open = sd_bus_open_system; + return &default_system_bus; + } +} + +sd_bus *bus_resolve(sd_bus *bus) { + switch ((uintptr_t) bus) { + case (uintptr_t) SD_BUS_DEFAULT: + return *(bus_choose_default(NULL)); + case (uintptr_t) SD_BUS_DEFAULT_USER: + return default_user_bus; + case (uintptr_t) SD_BUS_DEFAULT_SYSTEM: + return default_system_bus; + default: + return bus; + } +} + +void bus_close_io_fds(sd_bus *b) { assert(b); - detach_io_events(b); + bus_detach_io_events(b); if (b->input_fd != b->output_fd) safe_close(b->output_fd); b->output_fd = b->input_fd = safe_close(b->input_fd); } +void bus_close_inotify_fd(sd_bus *b) { + assert(b); + + bus_detach_inotify_event(b); + + b->inotify_fd = safe_close(b->inotify_fd); + b->inotify_watches = mfree(b->inotify_watches); + b->n_inotify_watches = 0; +} + static void bus_reset_queues(sd_bus *b) { assert(b); @@ -131,9 +201,11 @@ static void bus_free(sd_bus *b) { if (b->default_bus_ptr) *b->default_bus_ptr = NULL; - bus_close_fds(b); + bus_close_io_fds(b); + bus_close_inotify_fd(b); free(b->label); + free(b->groups); free(b->rbuffer); free(b->unique_name); free(b->auth_buffer); @@ -141,6 +213,7 @@ static void bus_free(sd_bus *b) { free(b->machine); free(b->cgroup_root); free(b->description); + free(b->patch_sender); free(b->exec_path); strv_free(b->exec_argv); @@ -180,11 +253,12 @@ _public_ int sd_bus_new(sd_bus **ret) { r->n_ref = REFCNT_INIT; r->input_fd = r->output_fd = -1; + r->inotify_fd = -1; r->message_version = 1; r->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME; - r->hello_flags |= KDBUS_HELLO_ACCEPT_FD; - r->attach_flags |= KDBUS_ATTACH_NAMES; + r->accept_fd = true; r->original_pid = getpid_cached(); + r->n_groups = (size_t) -1; assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0); @@ -203,6 +277,7 @@ _public_ int sd_bus_set_address(sd_bus *bus, const char *address) { char *a; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(address, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -219,6 +294,7 @@ _public_ int sd_bus_set_address(sd_bus *bus, const char *address) { _public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(input_fd >= 0, -EBADF); assert_return(output_fd >= 0, -EBADF); @@ -233,6 +309,7 @@ _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) char *p, **a; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(path, -EINVAL); assert_return(!strv_isempty(argv), -EINVAL); @@ -259,7 +336,9 @@ _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) _public_ int sd_bus_set_bus_client(sd_bus *bus, int b) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); + assert_return(!bus->patch_sender, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); bus->bus_client = !!b; @@ -268,43 +347,40 @@ _public_ int sd_bus_set_bus_client(sd_bus *bus, int b) { _public_ int sd_bus_set_monitor(sd_bus *bus, int b) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - SET_FLAG(bus->hello_flags, KDBUS_HELLO_MONITOR, b); + bus->is_monitor = b; return 0; } _public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b); + bus->accept_fd = b; return 0; } _public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) { - uint64_t new_flags; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - new_flags = bus->attach_flags; - SET_FLAG(new_flags, KDBUS_ATTACH_TIMESTAMP, b); - - if (bus->attach_flags == new_flags) - return 0; - - bus->attach_flags = new_flags; + /* This is not actually supported by any of our transports these days, but we do honour it for synthetic + * replies, and maybe one day classic D-Bus learns this too */ + bus->attach_timestamp = b; return 0; } _public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) { - uint64_t new_flags; - assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL); assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -314,18 +390,12 @@ _public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) { /* The well knowns we need unconditionally, so that matches can work */ bus->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME; - /* Make sure we don't lose the timestamp flag */ - new_flags = (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) | attach_flags_to_kdbus(bus->creds_mask); - if (bus->attach_flags == new_flags) - return 0; - - bus->attach_flags = new_flags; - return 0; } _public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -337,6 +407,7 @@ _public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) { _public_ int sd_bus_set_anonymous(sd_bus *bus, int b) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -346,6 +417,7 @@ _public_ int sd_bus_set_anonymous(sd_bus *bus, int b) { _public_ int sd_bus_set_trusted(sd_bus *bus, int b) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -355,6 +427,7 @@ _public_ int sd_bus_set_trusted(sd_bus *bus, int b) { _public_ int sd_bus_set_description(sd_bus *bus, const char *description) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -363,6 +436,7 @@ _public_ int sd_bus_set_description(sd_bus *bus, const char *description) { _public_ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); bus->allow_interactive_authorization = !!b; @@ -371,11 +445,115 @@ _public_ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b) { _public_ int sd_bus_get_allow_interactive_authorization(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); return bus->allow_interactive_authorization; } +_public_ int sd_bus_set_watch_bind(sd_bus *bus, int b) { + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(bus->state == BUS_UNSET, -EPERM); + assert_return(!bus_pid_changed(bus), -ECHILD); + + bus->watch_bind = b; + return 0; +} + +_public_ int sd_bus_get_watch_bind(sd_bus *bus) { + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(!bus_pid_changed(bus), -ECHILD); + + return bus->watch_bind; +} + +_public_ int sd_bus_set_connected_signal(sd_bus *bus, int b) { + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(bus->state == BUS_UNSET, -EPERM); + assert_return(!bus_pid_changed(bus), -ECHILD); + + bus->connected_signal = b; + return 0; +} + +_public_ int sd_bus_get_connected_signal(sd_bus *bus) { + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(!bus_pid_changed(bus), -ECHILD); + + return bus->connected_signal; +} + +static int synthesize_connected_signal(sd_bus *bus) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + int r; + + assert(bus); + + /* If enabled, synthesizes a local "Connected" signal mirroring the local "Disconnected" signal. This is called + * whenever we fully established a connection, i.e. after the authorization phase, and after receiving the + * Hello() reply. Or in other words, whenver we enter BUS_RUNNING state. + * + * This is useful so that clients can start doing stuff whenver the connection is fully established in a way + * that works independently from whether we connected to a full bus or just a direct connection. */ + + if (!bus->connected_signal) + return 0; + + r = sd_bus_message_new_signal( + bus, + &m, + "/org/freedesktop/DBus/Local", + "org.freedesktop.DBus.Local", + "Connected"); + if (r < 0) + return r; + + bus_message_set_sender_local(bus, m); + + r = bus_seal_synthetic_message(bus, m); + if (r < 0) + return r; + + r = bus_rqueue_make_room(bus); + if (r < 0) + return r; + + /* Insert at the very front */ + memmove(bus->rqueue + 1, bus->rqueue, sizeof(sd_bus_message*) * bus->rqueue_size); + bus->rqueue[0] = m; + m = NULL; + bus->rqueue_size++; + + return 0; +} + +void bus_set_state(sd_bus *bus, enum bus_state state) { + + static const char * const table[_BUS_STATE_MAX] = { + [BUS_UNSET] = "UNSET", + [BUS_WATCH_BIND] = "WATCH_BIND", + [BUS_OPENING] = "OPENING", + [BUS_AUTHENTICATING] = "AUTHENTICATING", + [BUS_HELLO] = "HELLO", + [BUS_RUNNING] = "RUNNING", + [BUS_CLOSING] = "CLOSING", + [BUS_CLOSED] = "CLOSED", + }; + + assert(bus); + assert(state < _BUS_STATE_MAX); + + if (state == bus->state) + return; + + log_debug("Bus %s: changing state %s → %s", strna(bus->description), table[bus->state], table[state]); + bus->state = state; +} + static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) { const char *s; sd_bus *bus; @@ -401,8 +579,13 @@ static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *e if (!bus->unique_name) return -ENOMEM; - if (bus->state == BUS_HELLO) - bus->state = BUS_RUNNING; + if (bus->state == BUS_HELLO) { + bus_set_state(bus, BUS_RUNNING); + + r = synthesize_connected_signal(bus); + if (r < 0) + return r; + } return 1; } @@ -430,14 +613,37 @@ static int bus_send_hello(sd_bus *bus) { } int bus_start_running(sd_bus *bus) { + struct reply_callback *c; + Iterator i; + usec_t n; + int r; + assert(bus); + assert(bus->state < BUS_HELLO); + + /* We start all method call timeouts when we enter BUS_HELLO or BUS_RUNNING mode. At this point let's convert + * all relative to absolute timestamps. Note that we do not reshuffle the reply callback priority queue since + * adding a fixed value to all entries should not alter the internal order. */ + + n = now(CLOCK_MONOTONIC); + ORDERED_HASHMAP_FOREACH(c, bus->reply_callbacks, i) { + if (c->timeout_usec == 0) + continue; + + c->timeout_usec = usec_add(n, c->timeout_usec); + } if (bus->bus_client) { - bus->state = BUS_HELLO; + bus_set_state(bus, BUS_HELLO); return 1; } - bus->state = BUS_RUNNING; + bus_set_state(bus, BUS_RUNNING); + + r = synthesize_connected_signal(bus); + if (r < 0) + return r; + return 1; } @@ -799,6 +1005,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) b->nspid = 0; b->sockaddr.un.sun_family = AF_UNIX; + /* Note that we use the old /var/run prefix here, to increase compatibility with really old containers */ strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path)); b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un); b->is_local = false; @@ -898,7 +1105,8 @@ static int bus_start_address(sd_bus *b) { assert(b); for (;;) { - bus_close_fds(b); + bus_close_io_fds(b); + bus_close_inotify_fd(b); /* If you provide multiple different bus-addresses, we * try all of them in order and use the first one that @@ -906,20 +1114,25 @@ static int bus_start_address(sd_bus *b) { if (b->exec_path) r = bus_socket_exec(b); - else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC) r = bus_container_connect_socket(b); - else if (b->sockaddr.sa.sa_family != AF_UNSPEC) r = bus_socket_connect(b); - else goto next; if (r >= 0) { - r = attach_io_events(b); - if (r >= 0) - return r; + int q; + + q = bus_attach_io_events(b); + if (q < 0) + return q; + + q = bus_attach_inotify_event(b); + if (q < 0) + return q; + + return r; } b->last_connect_error = -r; @@ -976,10 +1189,11 @@ _public_ int sd_bus_start(sd_bus *bus) { int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - bus->state = BUS_OPENING; + bus_set_state(bus, BUS_OPENING); if (bus->is_server && bus->bus_client) return -EINVAL; @@ -1040,7 +1254,6 @@ _public_ int sd_bus_open(sd_bus **ret) { * be safe, and authenticate everything */ b->trusted = false; b->is_local = false; - b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS; b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS; r = sd_bus_start(b); @@ -1086,7 +1299,6 @@ _public_ int sd_bus_open_system(sd_bus **ret) { /* Let's do per-method access control on the system bus. We * need the caller's UID and capability set for that. */ b->trusted = false; - b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS; b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS; b->is_local = true; @@ -1120,7 +1332,7 @@ int bus_set_address_user(sd_bus *b) { if (!ee) return -ENOMEM; - if (asprintf(&s, UNIX_USER_BUS_ADDRESS_FMT, ee) < 0) + if (asprintf(&s, DEFAULT_USER_BUS_ADDRESS_FMT, ee) < 0) return -ENOMEM; b->address = s; @@ -1294,7 +1506,7 @@ _public_ void sd_bus_close(sd_bus *bus) { if (bus_pid_changed(bus)) return; - bus->state = BUS_CLOSED; + bus_set_state(bus, BUS_CLOSED); sd_bus_detach_event(bus); @@ -1302,7 +1514,8 @@ _public_ void sd_bus_close(sd_bus *bus) { * the bus object and the bus may be freed */ bus_reset_queues(bus); - bus_close_fds(bus); + bus_close_io_fds(bus); + bus_close_inotify_fd(bus); } _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) { @@ -1316,13 +1529,13 @@ _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) { return sd_bus_unref(bus); } -static void bus_enter_closing(sd_bus *bus) { +void bus_enter_closing(sd_bus *bus) { assert(bus); - if (!IN_SET(bus->state, BUS_OPENING, BUS_AUTHENTICATING, BUS_HELLO, BUS_RUNNING)) + if (!IN_SET(bus->state, BUS_WATCH_BIND, BUS_OPENING, BUS_AUTHENTICATING, BUS_HELLO, BUS_RUNNING)) return; - bus->state = BUS_CLOSING; + bus_set_state(bus, BUS_CLOSING); } _public_ sd_bus *sd_bus_ref(sd_bus *bus) { @@ -1352,23 +1565,33 @@ _public_ sd_bus *sd_bus_unref(sd_bus *bus) { _public_ int sd_bus_is_open(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); return BUS_IS_OPEN(bus->state); } +_public_ int sd_bus_is_ready(sd_bus *bus) { + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(!bus_pid_changed(bus), -ECHILD); + + return bus->state == BUS_RUNNING; +} + _public_ int sd_bus_can_send(sd_bus *bus, char type) { int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->state != BUS_UNSET, -ENOTCONN); assert_return(!bus_pid_changed(bus), -ECHILD); - if (bus->hello_flags & KDBUS_HELLO_MONITOR) + if (bus->is_monitor) return 0; if (type == SD_BUS_TYPE_UNIX_FD) { - if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) + if (!bus->accept_fd) return 0; r = bus_ensure_running(bus); @@ -1385,6 +1608,7 @@ _public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) { int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(id, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -1397,6 +1621,8 @@ _public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) { } static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) { + int r; + assert(b); assert(m); @@ -1411,6 +1637,12 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) { if (timeout == 0) timeout = BUS_DEFAULT_TIMEOUT; + if (!m->sender && b->patch_sender) { + r = sd_bus_message_set_sender(m, b->patch_sender); + if (r < 0) + return r; + } + return sd_bus_message_seal(m, ++b->cookie, timeout); } @@ -1436,7 +1668,7 @@ int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) { /* Fake some timestamps, if they were requested, and not * already initialized */ - if (b->attach_flags & KDBUS_ATTACH_TIMESTAMP) { + if (b->attach_timestamp) { if (m->realtime <= 0) m->realtime = now(CLOCK_REALTIME); @@ -1454,7 +1686,7 @@ int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) { return sd_bus_message_seal(m, 0xFFFFFFFFULL, 0); } -static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call, size_t *idx) { +static int bus_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { int r; assert(bus); @@ -1465,7 +1697,7 @@ static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call return r; if (*idx >= BUS_MESSAGE_SIZE(m)) - log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error-name=%s error-message=%s", + log_debug("Sent message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s", bus_message_type_to_string(m->header->type), strna(sd_bus_message_get_sender(m)), strna(sd_bus_message_get_destination(m)), @@ -1474,6 +1706,7 @@ static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call strna(sd_bus_message_get_member(m)), BUS_MESSAGE_COOKIE(m), m->reply_cookie, + strna(m->root_container.signature), strna(m->error.name), strna(m->error.message)); @@ -1488,7 +1721,7 @@ static int dispatch_wqueue(sd_bus *bus) { while (bus->wqueue_size > 0) { - r = bus_write_message(bus, bus->wqueue[0], false, &bus->windex); + r = bus_write_message(bus, bus->wqueue[0], &bus->windex); if (r < 0) return r; else if (r == 0) @@ -1567,7 +1800,7 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd } } -static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie, bool hint_sync_call) { +_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m); int r; @@ -1612,7 +1845,7 @@ static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie, if (IN_SET(bus->state, BUS_RUNNING, BUS_HELLO) && bus->wqueue_size <= 0) { size_t idx = 0; - r = bus_write_message(bus, m, hint_sync_call, &idx); + r = bus_write_message(bus, m, &idx); if (r < 0) { if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) { bus_enter_closing(bus); @@ -1652,10 +1885,6 @@ finish: return 1; } -_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie) { - return bus_send_internal(bus, m, cookie, false); -} - _public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) { int r; @@ -1682,26 +1911,35 @@ _public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destinat return sd_bus_send(bus, m, cookie); } -static usec_t calc_elapse(uint64_t usec) { +static usec_t calc_elapse(sd_bus *bus, uint64_t usec) { + assert(bus); + if (usec == (uint64_t) -1) return 0; - return now(CLOCK_MONOTONIC) + usec; + /* We start all timeouts the instant we enter BUS_HELLO/BUS_RUNNING state, so that the don't run in parallel + * with any connection setup states. Hence, if a method callback is started earlier than that we just store the + * relative timestamp, and afterwards the absolute one. */ + + if (IN_SET(bus->state, BUS_WATCH_BIND, BUS_OPENING, BUS_AUTHENTICATING)) + return usec; + else + return now(CLOCK_MONOTONIC) + usec; } static int timeout_compare(const void *a, const void *b) { const struct reply_callback *x = a, *y = b; - if (x->timeout != 0 && y->timeout == 0) + if (x->timeout_usec != 0 && y->timeout_usec == 0) return -1; - if (x->timeout == 0 && y->timeout != 0) + if (x->timeout_usec == 0 && y->timeout_usec != 0) return 1; - if (x->timeout < y->timeout) + if (x->timeout_usec < y->timeout_usec) return -1; - if (x->timeout > y->timeout) + if (x->timeout_usec > y->timeout_usec) return 1; return 0; @@ -1721,8 +1959,7 @@ _public_ int sd_bus_call_async( assert_return(m, -EINVAL); assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL); - assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL); - assert_return(callback, -EINVAL); + assert_return(!m->sealed || (!!callback == !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)), -EINVAL); if (!bus) bus = m->bus; @@ -1732,6 +1969,10 @@ _public_ int sd_bus_call_async( if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; + /* If no callback is specified and there's no interest in a slot, then there's no reason to ask for a reply */ + if (!callback && !slot && !m->sealed) + m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED; + r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops); if (r < 0) return r; @@ -1748,29 +1989,31 @@ _public_ int sd_bus_call_async( if (r < 0) return r; - s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata); - if (!s) - return -ENOMEM; + if (slot || callback) { + s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata); + if (!s) + return -ENOMEM; - s->reply_callback.callback = callback; + s->reply_callback.callback = callback; - s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m); - r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback); - if (r < 0) { - s->reply_callback.cookie = 0; - return r; - } - - s->reply_callback.timeout = calc_elapse(m->timeout); - if (s->reply_callback.timeout != 0) { - r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx); + s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m); + r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback); if (r < 0) { - s->reply_callback.timeout = 0; + s->reply_callback.cookie = 0; return r; } + + s->reply_callback.timeout_usec = calc_elapse(bus, m->timeout); + if (s->reply_callback.timeout_usec != 0) { + r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx); + if (r < 0) { + s->reply_callback.timeout_usec = 0; + return r; + } + } } - r = sd_bus_send(bus, m, &s->reply_callback.cookie); + r = sd_bus_send(bus, m, s ? &s->reply_callback.cookie : NULL); if (r < 0) return r; @@ -1848,11 +2091,11 @@ _public_ int sd_bus_call( if (r < 0) goto fail; - r = bus_send_internal(bus, m, &cookie, true); + r = sd_bus_send(bus, m, &cookie); if (r < 0) goto fail; - timeout = calc_elapse(m->timeout); + timeout = calc_elapse(bus, m->timeout); for (;;) { usec_t left; @@ -1871,7 +2114,7 @@ _public_ int sd_bus_call( if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) { - if (incoming->n_fds <= 0 || (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) { + if (incoming->n_fds <= 0 || bus->accept_fd) { if (reply) *reply = incoming; else @@ -1966,35 +2209,63 @@ fail: _public_ int sd_bus_get_fd(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(bus->input_fd == bus->output_fd, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - return bus->input_fd; + if (bus->state == BUS_CLOSED) + return -ENOTCONN; + + if (bus->inotify_fd >= 0) + return bus->inotify_fd; + + if (bus->input_fd >= 0) + return bus->input_fd; + + return -ENOTCONN; } _public_ int sd_bus_get_events(sd_bus *bus) { int flags = 0; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); - if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING) + switch (bus->state) { + + case BUS_UNSET: + case BUS_CLOSED: return -ENOTCONN; - if (bus->state == BUS_OPENING) + case BUS_WATCH_BIND: + flags |= POLLIN; + break; + + case BUS_OPENING: flags |= POLLOUT; - else if (bus->state == BUS_AUTHENTICATING) { + break; + case BUS_AUTHENTICATING: if (bus_socket_auth_needs_write(bus)) flags |= POLLOUT; flags |= POLLIN; + break; - } else if (IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)) { + case BUS_RUNNING: + case BUS_HELLO: if (bus->rqueue_size <= 0) flags |= POLLIN; if (bus->wqueue_size > 0) flags |= POLLOUT; + break; + + case BUS_CLOSING: + break; + + default: + assert_not_reached("Unknown state"); } return flags; @@ -2004,6 +2275,7 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) { struct reply_callback *c; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(timeout_usec, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2015,39 +2287,45 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) { return 1; } - if (bus->state == BUS_CLOSING) { - *timeout_usec = 0; - return 1; - } + switch (bus->state) { - if (bus->state == BUS_AUTHENTICATING) { + case BUS_AUTHENTICATING: *timeout_usec = bus->auth_timeout; return 1; - } - if (!IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)) { - *timeout_usec = (uint64_t) -1; - return 0; - } + case BUS_RUNNING: + case BUS_HELLO: + if (bus->rqueue_size > 0) { + *timeout_usec = 0; + return 1; + } + + c = prioq_peek(bus->reply_callbacks_prioq); + if (!c) { + *timeout_usec = (uint64_t) -1; + return 0; + } + + if (c->timeout_usec == 0) { + *timeout_usec = (uint64_t) -1; + return 0; + } + + *timeout_usec = c->timeout_usec; + return 1; - if (bus->rqueue_size > 0) { + case BUS_CLOSING: *timeout_usec = 0; return 1; - } - c = prioq_peek(bus->reply_callbacks_prioq); - if (!c) { + case BUS_WATCH_BIND: + case BUS_OPENING: *timeout_usec = (uint64_t) -1; return 0; - } - if (c->timeout == 0) { - *timeout_usec = (uint64_t) -1; - return 0; + default: + assert_not_reached("Unknown or unexpected stat"); } - - *timeout_usec = c->timeout; - return 1; } static int process_timeout(sd_bus *bus) { @@ -2055,17 +2333,19 @@ static int process_timeout(sd_bus *bus) { _cleanup_(sd_bus_message_unrefp) sd_bus_message* m = NULL; struct reply_callback *c; sd_bus_slot *slot; + bool is_hello; usec_t n; int r; assert(bus); + assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)); c = prioq_peek(bus->reply_callbacks_prioq); if (!c) return 0; n = now(CLOCK_MONOTONIC); - if (c->timeout > n) + if (c->timeout_usec > n) return 0; r = bus_message_new_synthetic_error( @@ -2081,7 +2361,7 @@ static int process_timeout(sd_bus *bus) { return r; assert_se(prioq_pop(bus->reply_callbacks_prioq) == c); - c->timeout = 0; + c->timeout_usec = 0; ordered_hashmap_remove(bus->reply_callbacks, &c->cookie); c->cookie = 0; @@ -2090,6 +2370,8 @@ static int process_timeout(sd_bus *bus) { bus->iteration_counter++; + is_hello = bus->state == BUS_HELLO && c->callback == hello_callback; + bus->current_message = m; bus->current_slot = sd_bus_slot_ref(slot); bus->current_handler = c->callback; @@ -2107,6 +2389,11 @@ static int process_timeout(sd_bus *bus) { sd_bus_slot_unref(slot); + /* When this is the hello message and it timed out, then make sure to propagate the error up, don't just log + * and ignore the callback handler's return value. */ + if (is_hello) + return r; + return bus_maybe_reply_error(m, r, &error_buffer); } @@ -2136,6 +2423,7 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) { _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; struct reply_callback *c; sd_bus_slot *slot; + bool is_hello; int r; assert(bus); @@ -2155,7 +2443,7 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) { slot = container_of(c, sd_bus_slot, reply_callback); - if (m->n_fds > 0 && !(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) { + if (m->n_fds > 0 && !bus->accept_fd) { /* If the reply contained a file descriptor which we * didn't want we pass an error instead. */ @@ -2184,11 +2472,13 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) { return r; } - if (c->timeout != 0) { + if (c->timeout_usec != 0) { prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx); - c->timeout = 0; + c->timeout_usec = 0; } + is_hello = bus->state == BUS_HELLO && c->callback == hello_callback; + bus->current_slot = sd_bus_slot_ref(slot); bus->current_handler = c->callback; bus->current_userdata = slot->userdata; @@ -2204,6 +2494,11 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) { sd_bus_slot_unref(slot); + /* When this is the hello message and it failed, then make sure to propagate the error up, don't just log and + * ignore the callback handler's return value. */ + if (is_hello) + return r; + return bus_maybe_reply_error(m, r, &error_buffer); } @@ -2280,7 +2575,7 @@ static int process_builtin(sd_bus *bus, sd_bus_message *m) { assert(bus); assert(m); - if (bus->hello_flags & KDBUS_HELLO_MONITOR) + if (bus->is_monitor) return 0; if (bus->manual_peer_interface) @@ -2338,13 +2633,13 @@ static int process_fd_check(sd_bus *bus, sd_bus_message *m) { * delivered to us later even though we ourselves did not * negotiate it. */ - if (bus->hello_flags & KDBUS_HELLO_MONITOR) + if (bus->is_monitor) return 0; if (m->n_fds <= 0) return 0; - if (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD) + if (bus->accept_fd) return 0; if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL) @@ -2515,9 +2810,9 @@ static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) if (r < 0) return r; - if (c->timeout != 0) { + if (c->timeout_usec != 0) { prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx); - c->timeout = 0; + c->timeout_usec = 0; } ordered_hashmap_remove(bus->reply_callbacks, &c->cookie); @@ -2622,6 +2917,7 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit * means *ret is filled in with an unprocessed message. */ assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); /* We don't allow recursively invoking sd_bus_process(). */ @@ -2636,48 +2932,44 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit case BUS_CLOSED: return -ECONNRESET; + case BUS_WATCH_BIND: + r = bus_socket_process_watch_bind(bus); + break; + case BUS_OPENING: r = bus_socket_process_opening(bus); - if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) { - bus_enter_closing(bus); - r = 1; - } else if (r < 0) - return r; - if (ret) - *ret = NULL; - return r; + break; case BUS_AUTHENTICATING: r = bus_socket_process_authenticating(bus); - if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) { - bus_enter_closing(bus); - r = 1; - } else if (r < 0) - return r; - - if (ret) - *ret = NULL; - - return r; + break; case BUS_RUNNING: case BUS_HELLO: r = process_running(bus, hint_priority, priority, ret); - if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) { - bus_enter_closing(bus); - r = 1; - - if (ret) - *ret = NULL; - } + if (r >= 0) + return r; - return r; + /* This branch initializes *ret, hence we don't use the generic error checking below */ + break; case BUS_CLOSING: return process_closing(bus, ret); + + default: + assert_not_reached("Unknown state"); } - assert_not_reached("Unknown state"); + if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) { + bus_enter_closing(bus); + r = 1; + } else if (r < 0) + return r; + + if (ret) + *ret = NULL; + + return r; } _public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) { @@ -2690,7 +2982,7 @@ _public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_messa static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) { struct pollfd p[2] = {}; - int r, e, n; + int r, n; struct timespec ts; usec_t m = USEC_INFINITY; @@ -2702,45 +2994,52 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) { if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; - e = sd_bus_get_events(bus); - if (e < 0) - return e; - - if (need_more) - /* The caller really needs some more data, he doesn't - * care about what's already read, or any timeouts - * except its own. */ - e |= POLLIN; - else { - usec_t until; - /* The caller wants to process if there's something to - * process, but doesn't care otherwise */ - - r = sd_bus_get_timeout(bus, &until); - if (r < 0) - return r; - if (r > 0) { - usec_t nw; - nw = now(CLOCK_MONOTONIC); - m = until > nw ? until - nw : 0; - } - } + if (bus->state == BUS_WATCH_BIND) { + assert(bus->inotify_fd >= 0); - if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m)) - m = timeout_usec; - - p[0].fd = bus->input_fd; - if (bus->output_fd == bus->input_fd) { - p[0].events = e; + p[0].events = POLLIN; + p[0].fd = bus->inotify_fd; n = 1; } else { - p[0].events = e & POLLIN; - p[1].fd = bus->output_fd; - p[1].events = e & POLLOUT; - n = 2; + int e; + + e = sd_bus_get_events(bus); + if (e < 0) + return e; + + if (need_more) + /* The caller really needs some more data, he doesn't + * care about what's already read, or any timeouts + * except its own. */ + e |= POLLIN; + else { + usec_t until; + /* The caller wants to process if there's something to + * process, but doesn't care otherwise */ + + r = sd_bus_get_timeout(bus, &until); + if (r < 0) + return r; + if (r > 0) + m = usec_sub_unsigned(until, now(CLOCK_MONOTONIC)); + } + + p[0].fd = bus->input_fd; + if (bus->output_fd == bus->input_fd) { + p[0].events = e; + n = 1; + } else { + p[0].events = e & POLLIN; + p[1].fd = bus->output_fd; + p[1].events = e & POLLOUT; + n = 2; + } } - r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL); + if (timeout_usec != (uint64_t) -1 && (m == USEC_INFINITY || timeout_usec < m)) + m = timeout_usec; + + r = ppoll(p, n, m == USEC_INFINITY ? NULL : timespec_store(&ts, m), NULL); if (r < 0) return -errno; @@ -2750,6 +3049,7 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) { _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); if (bus->state == BUS_CLOSING) @@ -2768,6 +3068,7 @@ _public_ int sd_bus_flush(sd_bus *bus) { int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); if (bus->state == BUS_CLOSING) @@ -2776,6 +3077,10 @@ _public_ int sd_bus_flush(sd_bus *bus) { if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; + /* We never were connected? Don't hang in inotify for good, as there's no timeout set for it */ + if (bus->state == BUS_WATCH_BIND) + return -EUNATCH; + r = bus_ensure_running(bus); if (r < 0) return r; @@ -2812,6 +3117,7 @@ _public_ int sd_bus_add_filter( sd_bus_slot *s; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(callback, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2830,11 +3136,78 @@ _public_ int sd_bus_add_filter( return 0; } -_public_ int sd_bus_add_match( +static int add_match_callback( + sd_bus_message *m, + void *userdata, + sd_bus_error *ret_error) { + + sd_bus_slot *match_slot = userdata; + bool failed = false; + int r; + + assert(m); + assert(match_slot); + + sd_bus_slot_ref(match_slot); + + if (sd_bus_message_is_method_error(m, NULL)) { + log_debug_errno(sd_bus_message_get_errno(m), + "Unable to add match %s, failing connection: %s", + match_slot->match_callback.match_string, + sd_bus_message_get_error(m)->message); + + failed = true; + } else + log_debug("Match %s successfully installed.", match_slot->match_callback.match_string); + + if (match_slot->match_callback.install_callback) { + sd_bus *bus; + + bus = sd_bus_message_get_bus(m); + + /* This function has been called as slot handler, and we want to call another slot handler. Let's + * update the slot callback metadata temporarily with our own data, and then revert back to the old + * values. */ + + assert(bus->current_slot == match_slot->match_callback.install_slot); + assert(bus->current_handler == add_match_callback); + assert(bus->current_userdata == userdata); + + bus->current_slot = match_slot; + bus->current_handler = match_slot->match_callback.install_callback; + bus->current_userdata = match_slot->userdata; + + r = match_slot->match_callback.install_callback(m, match_slot->userdata, ret_error); + + bus->current_slot = match_slot->match_callback.install_slot; + bus->current_handler = add_match_callback; + bus->current_userdata = userdata; + + match_slot->match_callback.install_slot = sd_bus_slot_unref(match_slot->match_callback.install_slot); + } else { + if (failed) /* Generic failure handling: destroy the connection */ + bus_enter_closing(sd_bus_message_get_bus(m)); + + r = 1; + } + + if (failed && match_slot->floating) { + bus_slot_disconnect(match_slot); + sd_bus_slot_unref(match_slot); + } + + sd_bus_slot_unref(match_slot); + + return r; +} + +static int bus_add_match_full( sd_bus *bus, sd_bus_slot **slot, + bool asynchronous, const char *match, sd_bus_message_handler_t callback, + sd_bus_message_handler_t install_callback, void *userdata) { struct bus_match_component *components = NULL; @@ -2843,6 +3216,7 @@ _public_ int sd_bus_add_match( int r = 0; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(match, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -2857,18 +3231,17 @@ _public_ int sd_bus_add_match( } s->match_callback.callback = callback; + s->match_callback.install_callback = install_callback; if (bus->bus_client) { enum bus_match_scope scope; scope = bus_match_get_scope(components, n_components); - /* Do not install server-side matches for matches - * against the local service, interface or bus path. */ + /* Do not install server-side matches for matches against the local service, interface or bus path. */ if (scope != BUS_MATCH_LOCAL) { - /* We store the original match string, so that - * we can use it to remove the match again. */ + /* We store the original match string, so that we can use it to remove the match again. */ s->match_callback.match_string = strdup(match); if (!s->match_callback.match_string) { @@ -2876,7 +3249,14 @@ _public_ int sd_bus_add_match( goto finish; } - r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components); + if (asynchronous) + r = bus_add_match_internal_async(bus, + &s->match_callback.install_slot, + s->match_callback.match_string, + add_match_callback, + s); + else + r = bus_add_match_internal(bus, s->match_callback.match_string); if (r < 0) goto finish; @@ -2900,35 +3280,25 @@ finish: return r; } -int bus_remove_match_by_string( +_public_ int sd_bus_add_match( sd_bus *bus, + sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata) { - struct bus_match_component *components = NULL; - unsigned n_components = 0; - struct match_callback *c; - int r = 0; - - assert_return(bus, -EINVAL); - assert_return(match, -EINVAL); - assert_return(!bus_pid_changed(bus), -ECHILD); - - r = bus_match_parse(match, &components, &n_components); - if (r < 0) - goto finish; - - r = bus_match_find(&bus->match_callbacks, components, n_components, NULL, NULL, &c); - if (r <= 0) - goto finish; - - sd_bus_slot_unref(container_of(c, sd_bus_slot, match_callback)); + return bus_add_match_full(bus, slot, false, match, callback, NULL, userdata); +} -finish: - bus_match_parse_free(components, n_components); +_public_ int sd_bus_add_match_async( + sd_bus *bus, + sd_bus_slot **slot, + const char *match, + sd_bus_message_handler_t callback, + sd_bus_message_handler_t install_callback, + void *userdata) { - return r; + return bus_add_match_full(bus, slot, true, match, callback, install_callback, userdata); } bool bus_pid_changed(sd_bus *bus) { @@ -2946,9 +3316,13 @@ static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userd assert(bus); + /* Note that this is called both on input_fd, output_fd as well as inotify_fd events */ + r = sd_bus_process(bus, NULL); - if (r < 0) - return r; + if (r < 0) { + log_debug_errno(r, "Processing of bus failed, closing down: %m"); + bus_enter_closing(bus); + } return 1; } @@ -2960,8 +3334,10 @@ static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) { assert(bus); r = sd_bus_process(bus, NULL); - if (r < 0) - return r; + if (r < 0) { + log_debug_errno(r, "Processing of bus failed, closing down: %m"); + bus_enter_closing(bus); + } return 1; } @@ -2975,38 +3351,45 @@ static int prepare_callback(sd_event_source *s, void *userdata) { assert(bus); e = sd_bus_get_events(bus); - if (e < 0) - return e; + if (e < 0) { + r = e; + goto fail; + } if (bus->output_fd != bus->input_fd) { r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN); if (r < 0) - return r; + goto fail; r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT); - if (r < 0) - return r; - } else { + } else r = sd_event_source_set_io_events(bus->input_io_event_source, e); - if (r < 0) - return r; - } + if (r < 0) + goto fail; r = sd_bus_get_timeout(bus, &until); if (r < 0) - return r; + goto fail; if (r > 0) { int j; j = sd_event_source_set_time(bus->time_event_source, until); - if (j < 0) - return j; + if (j < 0) { + r = j; + goto fail; + } } r = sd_event_source_set_enabled(bus->time_event_source, r > 0); if (r < 0) - return r; + goto fail; + + return 1; + +fail: + log_debug_errno(r, "Preparing of bus events failed, closing down: %m"); + bus_enter_closing(bus); return 1; } @@ -3022,7 +3405,7 @@ static int quit_callback(sd_event_source *event, void *userdata) { return 1; } -static int attach_io_events(sd_bus *bus) { +int bus_attach_io_events(sd_bus *bus) { int r; assert(bus); @@ -3076,7 +3459,7 @@ static int attach_io_events(sd_bus *bus) { return 0; } -static void detach_io_events(sd_bus *bus) { +static void bus_detach_io_events(sd_bus *bus) { assert(bus); if (bus->input_io_event_source) { @@ -3090,10 +3473,49 @@ static void detach_io_events(sd_bus *bus) { } } +int bus_attach_inotify_event(sd_bus *bus) { + int r; + + assert(bus); + + if (bus->inotify_fd < 0) + return 0; + + if (!bus->event) + return 0; + + if (!bus->inotify_event_source) { + r = sd_event_add_io(bus->event, &bus->inotify_event_source, bus->inotify_fd, EPOLLIN, io_callback, bus); + if (r < 0) + return r; + + r = sd_event_source_set_priority(bus->inotify_event_source, bus->event_priority); + if (r < 0) + return r; + + r = sd_event_source_set_description(bus->inotify_event_source, "bus-inotify"); + } else + r = sd_event_source_set_io_fd(bus->inotify_event_source, bus->inotify_fd); + if (r < 0) + return r; + + return 0; +} + +static void bus_detach_inotify_event(sd_bus *bus) { + assert(bus); + + if (bus->inotify_event_source) { + sd_event_source_set_enabled(bus->inotify_event_source, SD_EVENT_OFF); + bus->inotify_event_source = sd_event_source_unref(bus->inotify_event_source); + } +} + _public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) { int r; assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus->event, -EBUSY); assert(!bus->input_io_event_source); @@ -3130,7 +3552,11 @@ _public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) { if (r < 0) goto fail; - r = attach_io_events(bus); + r = bus_attach_io_events(bus); + if (r < 0) + goto fail; + + r = bus_attach_inotify_event(bus); if (r < 0) goto fail; @@ -3143,11 +3569,13 @@ fail: _public_ int sd_bus_detach_event(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); if (!bus->event) return 0; - detach_io_events(bus); + bus_detach_io_events(bus); + bus_detach_inotify_event(bus); if (bus->time_event_source) { sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF); @@ -3230,39 +3658,11 @@ _public_ int sd_bus_default_user(sd_bus **ret) { } _public_ int sd_bus_default(sd_bus **ret) { + int (*bus_open)(sd_bus **) = NULL; + sd_bus **busp; - const char *e; - - /* Let's try our best to reuse another cached connection. If - * the starter bus type is set, connect via our normal - * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that - * we can share the connection with the user/system default - * bus. */ - - e = secure_getenv("DBUS_STARTER_BUS_TYPE"); - if (e) { - if (streq(e, "system")) - return sd_bus_default_system(ret); - else if (STR_IN_SET(e, "user", "session")) - return sd_bus_default_user(ret); - } - - /* No type is specified, so we have not other option than to - * use the starter address if it is set. */ - - e = secure_getenv("DBUS_STARTER_ADDRESS"); - if (e) { - - return bus_default(sd_bus_open, &default_starter_bus, ret); - } - - /* Finally, if nothing is set use the cached connection for - * the right scope */ - - if (cg_pid_get_owner_uid(0, NULL) >= 0) - return sd_bus_default_user(ret); - else - return sd_bus_default_system(ret); + busp = bus_choose_default(&bus_open); + return bus_default(bus_open, busp, ret); } _public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) { @@ -3483,13 +3883,13 @@ _public_ int sd_bus_path_decode_many(const char *path, const char *path_template } va_end(list); - free(labels); - labels = NULL; + labels = mfree(labels); return 1; } _public_ int sd_bus_try_close(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); return -EOPNOTSUPP; @@ -3497,6 +3897,7 @@ _public_ int sd_bus_try_close(sd_bus *bus) { _public_ int sd_bus_get_description(sd_bus *bus, const char **description) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(description, -EINVAL); assert_return(bus->description, -ENXIO); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -3525,6 +3926,7 @@ int bus_get_root_path(sd_bus *bus) { _public_ int sd_bus_get_scope(sd_bus *bus, const char **scope) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(scope, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -3544,6 +3946,7 @@ _public_ int sd_bus_get_scope(sd_bus *bus, const char **scope) { _public_ int sd_bus_get_address(sd_bus *bus, const char **address) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(address, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -3557,6 +3960,7 @@ _public_ int sd_bus_get_address(sd_bus *bus, const char **address) { _public_ int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *mask) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(mask, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -3566,6 +3970,7 @@ _public_ int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *mask) { _public_ int sd_bus_is_bus_client(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); return bus->bus_client; @@ -3573,6 +3978,7 @@ _public_ int sd_bus_is_bus_client(sd_bus *bus) { _public_ int sd_bus_is_server(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); return bus->is_server; @@ -3580,6 +3986,7 @@ _public_ int sd_bus_is_server(sd_bus *bus) { _public_ int sd_bus_is_anonymous(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); return bus->anonymous_auth; @@ -3587,6 +3994,7 @@ _public_ int sd_bus_is_anonymous(sd_bus *bus) { _public_ int sd_bus_is_trusted(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); return bus->trusted; @@ -3594,9 +4002,10 @@ _public_ int sd_bus_is_trusted(sd_bus *bus) { _public_ int sd_bus_is_monitor(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); - return !!(bus->hello_flags & KDBUS_HELLO_MONITOR); + return bus->is_monitor; } static void flush_close(sd_bus *bus) { @@ -3618,6 +4027,7 @@ _public_ void sd_bus_default_flush_close(void) { _public_ int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); /* Turns on exit-on-disconnect, and triggers it immediately if the bus connection was already * disconnected. Note that this is triggered exclusively on disconnections triggered by the server side, never @@ -3630,6 +4040,28 @@ _public_ int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b) { _public_ int sd_bus_get_exit_on_disconnect(sd_bus *bus) { assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); return bus->exit_on_disconnect; } + +_public_ int sd_bus_set_sender(sd_bus *bus, const char *sender) { + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(!bus->bus_client, -EPERM); + assert_return(!sender || service_name_is_valid(sender), -EINVAL); + + return free_and_strdup(&bus->patch_sender, sender); +} + +_public_ int sd_bus_get_sender(sd_bus *bus, const char **ret) { + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(ret, -EINVAL); + + if (!bus->patch_sender) + return -ENODATA; + + *ret = bus->patch_sender; + return 0; +} diff --git a/src/libsystemd/sd-bus/test-bus-benchmark.c b/src/libsystemd/sd-bus/test-bus-benchmark.c index a466cddd75..bfd0f39372 100644 --- a/src/libsystemd/sd-bus/test-bus-benchmark.c +++ b/src/libsystemd/sd-bus/test-bus-benchmark.c @@ -319,7 +319,7 @@ int main(int argc, char *argv[]) { break; } - _exit(0); + _exit(EXIT_SUCCESS); } CPU_ZERO(&cpuset); diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c index 1b2efb9bb4..bd6721946a 100644 --- a/src/libsystemd/sd-bus/test-bus-chat.c +++ b/src/libsystemd/sd-bus/test-bus-chat.c @@ -102,9 +102,9 @@ static int server_init(sd_bus **_bus) { goto fail; } - r = sd_bus_add_match(bus, NULL, "type='signal',interface='foo.bar',member='Notify'", match_callback, NULL); + r = sd_bus_match_signal(bus, NULL, NULL, NULL, "foo.bar", "Notify", match_callback, NULL); if (r < 0) { - log_error_errno(r, "Failed to add match: %m"); + log_error_errno(r, "Failed to request match: %m"); goto fail; } diff --git a/src/libsystemd/sd-bus/test-bus-track.c b/src/libsystemd/sd-bus/test-bus-track.c index 320e8347f4..94c9d09de3 100644 --- a/src/libsystemd/sd-bus/test-bus-track.c +++ b/src/libsystemd/sd-bus/test-bus-track.c @@ -18,6 +18,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> +#include <sys/socket.h> + #include "sd-bus.h" #include "macro.h" diff --git a/src/libsystemd/sd-bus/test-bus-watch-bind.c b/src/libsystemd/sd-bus/test-bus-watch-bind.c new file mode 100644 index 0000000000..aef5ba9486 --- /dev/null +++ b/src/libsystemd/sd-bus/test-bus-watch-bind.c @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + This file is part of systemd. + + Copyright 2017 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <pthread.h> + +#include "sd-bus.h" +#include "sd-event.h" +#include "sd-id128.h" + +#include "alloc-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "mkdir.h" +#include "path-util.h" +#include "random-util.h" +#include "rm-rf.h" +#include "socket-util.h" +#include "string-util.h" + +static int method_foobar(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { + log_info("Got Foobar() call."); + + assert_se(sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 0) >= 0); + return sd_bus_reply_method_return(m, NULL); +} + +static int method_exit(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { + log_info("Got Exit() call"); + assert_se(sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 1) >= 0); + return sd_bus_reply_method_return(m, NULL); +} + +static const sd_bus_vtable vtable[] = { + SD_BUS_VTABLE_START(0), + SD_BUS_METHOD("Foobar", NULL, NULL, method_foobar, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Exit", NULL, NULL, method_exit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_VTABLE_END, +}; + +static void* thread_server(void *p) { + _cleanup_free_ char *suffixed = NULL, *suffixed2 = NULL, *d = NULL; + _cleanup_close_ int fd = -1; + union sockaddr_union u = { + .un.sun_family = AF_UNIX, + }; + const char *path = p; + + log_debug("Initializing server"); + + /* Let's play some games, by slowly creating the socket directory, and renaming it in the middle */ + (void) usleep(100 * USEC_PER_MSEC); + + assert_se(mkdir_parents(path, 0755) >= 0); + (void) usleep(100 * USEC_PER_MSEC); + + d = dirname_malloc(path); + assert_se(d); + assert_se(asprintf(&suffixed, "%s.%" PRIx64, d, random_u64()) >= 0); + assert_se(rename(d, suffixed) >= 0); + (void) usleep(100 * USEC_PER_MSEC); + + assert_se(asprintf(&suffixed2, "%s.%" PRIx64, d, random_u64()) >= 0); + assert_se(symlink(suffixed2, d) >= 0); + (void) usleep(100 * USEC_PER_MSEC); + + assert_se(symlink(basename(suffixed), suffixed2) >= 0); + (void) usleep(100 * USEC_PER_MSEC); + + strncpy(u.un.sun_path, path, sizeof(u.un.sun_path)); + + fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); + assert_se(fd >= 0); + + assert_se(bind(fd, &u.sa, SOCKADDR_UN_LEN(u.un)) >= 0); + usleep(100 * USEC_PER_MSEC); + + assert_se(listen(fd, SOMAXCONN) >= 0); + usleep(100 * USEC_PER_MSEC); + + assert_se(touch(path) >= 0); + usleep(100 * USEC_PER_MSEC); + + log_debug("Initialized server"); + + for (;;) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + _cleanup_(sd_event_unrefp) sd_event *event = NULL; + sd_id128_t id; + int bus_fd, code; + + assert_se(sd_id128_randomize(&id) >= 0); + + assert_se(sd_event_new(&event) >= 0); + + bus_fd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); + assert_se(bus_fd >= 0); + + log_debug("Accepted server connection"); + + assert_se(sd_bus_new(&bus) >= 0); + assert_se(sd_bus_set_description(bus, "server") >= 0); + assert_se(sd_bus_set_fd(bus, bus_fd, bus_fd) >= 0); + assert_se(sd_bus_set_server(bus, true, id) >= 0); + /* assert_se(sd_bus_set_anonymous(bus, true) >= 0); */ + + assert_se(sd_bus_attach_event(bus, event, 0) >= 0); + + assert_se(sd_bus_add_object_vtable(bus, NULL, "/foo", "foo.TestInterface", vtable, NULL) >= 0); + + assert_se(sd_bus_start(bus) >= 0); + + assert_se(sd_event_loop(event) >= 0); + + assert_se(sd_event_get_exit_code(event, &code) >= 0); + + if (code > 0) + break; + } + + log_debug("Server done"); + + return NULL; +} + +static void* thread_client1(void *p) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + const char *path = p, *t; + int r; + + log_debug("Initializing client1"); + + assert_se(sd_bus_new(&bus) >= 0); + assert_se(sd_bus_set_description(bus, "client1") >= 0); + + t = strjoina("unix:path=", path); + assert_se(sd_bus_set_address(bus, t) >= 0); + assert_se(sd_bus_set_watch_bind(bus, true) >= 0); + assert_se(sd_bus_start(bus) >= 0); + + r = sd_bus_call_method(bus, "foo.bar", "/foo", "foo.TestInterface", "Foobar", &error, NULL, NULL); + assert_se(r >= 0); + + log_debug("Client1 done"); + + return NULL; +} + +static int client2_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { + assert_se(sd_bus_message_is_method_error(m, NULL) == 0); + assert_se(sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 0) >= 0); + return 0; +} + +static void* thread_client2(void *p) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + _cleanup_(sd_event_unrefp) sd_event *event = NULL; + const char *path = p, *t; + + log_debug("Initializing client2"); + + assert_se(sd_event_new(&event) >= 0); + assert_se(sd_bus_new(&bus) >= 0); + assert_se(sd_bus_set_description(bus, "client2") >= 0); + + t = strjoina("unix:path=", path); + assert_se(sd_bus_set_address(bus, t) >= 0); + assert_se(sd_bus_set_watch_bind(bus, true) >= 0); + assert_se(sd_bus_attach_event(bus, event, 0) >= 0); + assert_se(sd_bus_start(bus) >= 0); + + assert_se(sd_bus_call_method_async(bus, NULL, "foo.bar", "/foo", "foo.TestInterface", "Foobar", client2_callback, NULL, NULL) >= 0); + + assert_se(sd_event_loop(event) >= 0); + + log_debug("Client2 done"); + + return NULL; +} + +static void request_exit(const char *path) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + const char *t; + + assert_se(sd_bus_new(&bus) >= 0); + + t = strjoina("unix:path=", path); + assert_se(sd_bus_set_address(bus, t) >= 0); + assert_se(sd_bus_set_watch_bind(bus, true) >= 0); + assert_se(sd_bus_set_description(bus, "request-exit") >= 0); + assert_se(sd_bus_start(bus) >= 0); + + assert_se(sd_bus_call_method(bus, "foo.bar", "/foo", "foo.TestInterface", "Exit", NULL, NULL, NULL) >= 0); +} + +int main(int argc, char *argv[]) { + _cleanup_(rm_rf_physical_and_freep) char *d = NULL; + pthread_t server, client1, client2; + char *path; + + log_set_max_level(LOG_DEBUG); + + /* We use /dev/shm here rather than /tmp, since some weird distros might set up /tmp as some weird fs that + * doesn't support inotify properly. */ + assert_se(mkdtemp_malloc("/dev/shm/systemd-watch-bind-XXXXXX", &d) >= 0); + + path = strjoina(d, "/this/is/a/socket"); + + assert_se(pthread_create(&server, NULL, thread_server, path) == 0); + assert_se(pthread_create(&client1, NULL, thread_client1, path) == 0); + assert_se(pthread_create(&client2, NULL, thread_client2, path) == 0); + + assert_se(pthread_join(client1, NULL) == 0); + assert_se(pthread_join(client2, NULL) == 0); + + request_exit(path); + + assert_se(pthread_join(server, NULL) == 0); + + return 0; +} diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index 64a74929bf..1334498ca4 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -39,6 +39,7 @@ #include "fs-util.h" #include "parse-util.h" #include "path-util.h" +#include "process-util.h" #include "socket-util.h" #include "strv.h" #include "util.h" @@ -306,17 +307,13 @@ _public_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint return 0; if (port > 0) { - if (sockaddr.sa.sa_family == AF_INET) { - if (l < sizeof(struct sockaddr_in)) - return -EINVAL; + unsigned sa_port; - return htobe16(port) == sockaddr.in.sin_port; - } else { - if (l < sizeof(struct sockaddr_in6)) - return -EINVAL; + r = sockaddr_port(&sockaddr.sa, &sa_port); + if (r < 0) + return r; - return htobe16(port) == sockaddr.in6.sin6_port; - } + return port == sa_port; } return 1; @@ -459,7 +456,13 @@ _public_ int sd_is_mq(int fd, const char *path) { return 1; } -_public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char *state, const int *fds, unsigned n_fds) { +_public_ int sd_pid_notify_with_fds( + pid_t pid, + int unset_environment, + const char *state, + const int *fds, + unsigned n_fds) { + union sockaddr_union sockaddr = { .sa.sa_family = AF_UNIX, }; @@ -474,7 +477,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char _cleanup_close_ int fd = -1; struct cmsghdr *cmsg = NULL; const char *e; - bool have_pid; + bool send_ucred; int r; if (!state) { @@ -508,7 +511,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char goto finish; } - fd_inc_sndbuf(fd, SNDBUF_SIZE); + (void) fd_inc_sndbuf(fd, SNDBUF_SIZE); iovec.iov_len = strlen(state); @@ -518,13 +521,16 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char msghdr.msg_namelen = SOCKADDR_UN_LEN(sockaddr.un); - have_pid = pid != 0 && pid != getpid_cached(); + send_ucred = + (pid != 0 && pid != getpid_cached()) || + getuid() != geteuid() || + getgid() != getegid(); - if (n_fds > 0 || have_pid) { + if (n_fds > 0 || send_ucred) { /* CMSG_SPACE(0) may return value different than zero, which results in miscalculated controllen. */ msghdr.msg_controllen = (n_fds > 0 ? CMSG_SPACE(sizeof(int) * n_fds) : 0) + - (have_pid ? CMSG_SPACE(sizeof(struct ucred)) : 0); + (send_ucred ? CMSG_SPACE(sizeof(struct ucred)) : 0); msghdr.msg_control = alloca0(msghdr.msg_controllen); @@ -536,11 +542,11 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * n_fds); - if (have_pid) + if (send_ucred) assert_se(cmsg = CMSG_NXTHDR(&msghdr, cmsg)); } - if (have_pid) { + if (send_ucred) { struct ucred *ucred; cmsg->cmsg_level = SOL_SOCKET; @@ -548,7 +554,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); ucred = (struct ucred*) CMSG_DATA(cmsg); - ucred->pid = pid; + ucred->pid = pid != 0 ? pid : getpid_cached(); ucred->uid = getuid(); ucred->gid = getgid(); } @@ -561,7 +567,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char } /* If that failed, try with our own ucred instead */ - if (have_pid) { + if (send_ucred) { msghdr.msg_controllen -= CMSG_SPACE(sizeof(struct ucred)); if (msghdr.msg_controllen == 0) msghdr.msg_control = NULL; diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index a96d7445ce..1297dfa911 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -166,25 +166,38 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { } if (verify) { - r = readlink_and_canonicalize(_syspath, NULL, &syspath); + r = chase_symlinks(_syspath, NULL, 0, &syspath); if (r == -ENOENT) /* the device does not exist (any more?) */ return -ENODEV; - else if (r == -EINVAL) { - /* not a symlink */ - syspath = canonicalize_file_name(_syspath); - if (!syspath) { - if (errno == ENOENT) - /* the device does not exist (any more?) */ - return -ENODEV; - - return log_debug_errno(errno, "sd-device: could not canonicalize '%s': %m", _syspath); - } - } else if (r < 0) { + else if (r < 0) { log_debug_errno(r, "sd-device: could not get target of '%s': %m", _syspath); return r; } + if (!path_startswith(syspath, "/sys")) { + _cleanup_free_ char *real_sys = NULL, *new_syspath = NULL; + char *p; + + /* /sys is a symlink to somewhere sysfs is mounted on? In that case, we convert the path to real sysfs to "/sys". */ + r = chase_symlinks("/sys", NULL, 0, &real_sys); + if (r < 0) + return log_debug_errno(r, "sd-device: could not chase symlink /sys: %m"); + + p = path_startswith(syspath, real_sys); + if (!p) { + log_debug("sd-device: canonicalized path '%s' does not starts with sysfs mount point '%s'", syspath, real_sys); + return -ENODEV; + } + + new_syspath = strjoin("/sys/", p); + if (!new_syspath) + return log_oom(); + + free_and_replace(syspath, new_syspath); + path_kill_slashes(syspath); + } + if (path_startswith(syspath, "/sys/devices/")) { char *path; diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index a5f3e854b1..cb9b3a4545 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -122,6 +122,7 @@ struct sd_event_source { uint32_t events; uint32_t revents; bool registered:1; + bool owned:1; } io; struct { sd_event_time_handler_t callback; @@ -240,8 +241,14 @@ struct sd_event { unsigned delays[sizeof(usec_t) * 8]; }; +static thread_local sd_event *default_event = NULL; + static void source_disconnect(sd_event_source *s); +static sd_event *event_resolve(sd_event *e) { + return e == SD_EVENT_DEFAULT ? default_event : e; +} + static int pending_prioq_compare(const void *a, const void *b) { const sd_event_source *x = a, *y = b; @@ -883,6 +890,10 @@ static void source_free(sd_event_source *s) { assert(s); source_disconnect(s); + + if (s->type == SOURCE_IO && s->io.owned) + safe_close(s->io.fd); + free(s->description); free(s); } @@ -967,6 +978,7 @@ _public_ int sd_event_add_io( int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(fd >= 0, -EBADF); assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL); assert_return(callback, -EINVAL); @@ -1067,6 +1079,7 @@ _public_ int sd_event_add_time( int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(accuracy != (uint64_t) -1, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); @@ -1148,6 +1161,7 @@ _public_ int sd_event_add_signal( int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(SIGNAL_VALID(sig), -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); @@ -1207,6 +1221,7 @@ _public_ int sd_event_add_child( int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(pid > 1, -EINVAL); assert_return(!(options & ~(WEXITED|WSTOPPED|WCONTINUED)), -EINVAL); assert_return(options != 0, -EINVAL); @@ -1264,6 +1279,7 @@ _public_ int sd_event_add_defer( int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(callback, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); @@ -1298,6 +1314,7 @@ _public_ int sd_event_add_post( int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(callback, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); @@ -1336,6 +1353,7 @@ _public_ int sd_event_add_exit( int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(callback, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); @@ -1481,6 +1499,21 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { return 0; } +_public_ int sd_event_source_get_io_fd_own(sd_event_source *s) { + assert_return(s, -EINVAL); + assert_return(s->type == SOURCE_IO, -EDOM); + + return s->io.owned; +} + +_public_ int sd_event_source_set_io_fd_own(sd_event_source *s, int own) { + assert_return(s, -EINVAL); + assert_return(s->type == SOURCE_IO, -EDOM); + + s->io.owned = own; + return 0; +} + _public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) { assert_return(s, -EINVAL); assert_return(events, -EINVAL); @@ -2449,6 +2482,7 @@ _public_ int sd_event_prepare(sd_event *e) { int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); @@ -2506,6 +2540,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { int r, m, i; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(e->state == SD_EVENT_ARMED, -EBUSY); @@ -2612,6 +2647,7 @@ _public_ int sd_event_dispatch(sd_event *e) { int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(e->state == SD_EVENT_PENDING, -EBUSY); @@ -2653,6 +2689,7 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); @@ -2697,6 +2734,7 @@ _public_ int sd_event_loop(sd_event *e) { int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); @@ -2718,6 +2756,7 @@ finish: _public_ int sd_event_get_fd(sd_event *e) { assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); return e->epoll_fd; @@ -2725,6 +2764,7 @@ _public_ int sd_event_get_fd(sd_event *e) { _public_ int sd_event_get_state(sd_event *e) { assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); return e->state; @@ -2732,6 +2772,7 @@ _public_ int sd_event_get_state(sd_event *e) { _public_ int sd_event_get_exit_code(sd_event *e, int *code) { assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(code, -EINVAL); assert_return(!event_pid_changed(e), -ECHILD); @@ -2744,6 +2785,7 @@ _public_ int sd_event_get_exit_code(sd_event *e, int *code) { _public_ int sd_event_exit(sd_event *e, int code) { assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); @@ -2755,6 +2797,7 @@ _public_ int sd_event_exit(sd_event *e, int code) { _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) { assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(usec, -EINVAL); assert_return(!event_pid_changed(e), -ECHILD); @@ -2779,8 +2822,6 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) { } _public_ int sd_event_default(sd_event **ret) { - - static thread_local sd_event *default_event = NULL; sd_event *e = NULL; int r; @@ -2806,6 +2847,7 @@ _public_ int sd_event_default(sd_event **ret) { _public_ int sd_event_get_tid(sd_event *e, pid_t *tid) { assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(tid, -EINVAL); assert_return(!event_pid_changed(e), -ECHILD); @@ -2821,6 +2863,7 @@ _public_ int sd_event_set_watchdog(sd_event *e, int b) { int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); if (e->watchdog == !!b) @@ -2871,6 +2914,7 @@ fail: _public_ int sd_event_get_watchdog(sd_event *e) { assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); return e->watchdog; @@ -2878,6 +2922,7 @@ _public_ int sd_event_get_watchdog(sd_event *e) { _public_ int sd_event_get_iteration(sd_event *e, uint64_t *ret) { assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_pid_changed(e), -ECHILD); *ret = e->iteration; diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c index 7f32838c6f..9873ae4a58 100644 --- a/src/libsystemd/sd-event/test-event.c +++ b/src/libsystemd/sd-event/test-event.c @@ -27,6 +27,7 @@ #include "macro.h" #include "signal-util.h" #include "util.h" +#include "process-util.h" static int prepare_handler(sd_event_source *s, void *userdata) { log_info("preparing %c", PTR_TO_INT(userdata)); @@ -97,7 +98,7 @@ static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, assert_se(pid >= 0); if (pid == 0) - _exit(0); + _exit(EXIT_SUCCESS); assert_se(sd_event_add_child(sd_event_source_get_event(s), &p, pid, WEXITED, child_handler, INT_TO_PTR('f')) >= 0); assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0); diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c index 5541e8d47e..a6e38578b1 100644 --- a/src/libsystemd/sd-id128/id128-util.c +++ b/src/libsystemd/sd-id128/id128-util.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <fcntl.h> #include <unistd.h> diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index e8adaa6823..69572d1a51 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -1061,10 +1061,15 @@ _public_ sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m) { } _public_ int sd_login_monitor_flush(sd_login_monitor *m) { + int r; assert_return(m, -EINVAL); - return flush_fd(MONITOR_TO_FD(m)); + r = flush_fd(MONITOR_TO_FD(m)); + if (r < 0) + return r; + + return 0; } _public_ int sd_login_monitor_get_fd(sd_login_monitor *m) { diff --git a/src/libsystemd/sd-netlink/generic-netlink.c b/src/libsystemd/sd-netlink/generic-netlink.c new file mode 100644 index 0000000000..771658d9ae --- /dev/null +++ b/src/libsystemd/sd-netlink/generic-netlink.c @@ -0,0 +1,97 @@ +#include <linux/genetlink.h> + +#include "sd-netlink.h" +#include "netlink-internal.h" +#include "alloc-util.h" + +typedef struct { + const char* name; + uint8_t version; +} genl_family; + +static const genl_family genl_families[] = { + [SD_GENL_ID_CTRL] = { .name = "", .version = 1 }, + [SD_GENL_WIREGUARD] = { .name = "wireguard", .version = 1 }, +}; + +int sd_genl_socket_open(sd_netlink **ret) { + return netlink_open_family(ret, NETLINK_GENERIC); +} +static int lookup_id(sd_netlink *nl, sd_genl_family family, uint16_t *id); + +static int genl_message_new(sd_netlink *nl, sd_genl_family family, uint16_t nlmsg_type, uint8_t cmd, sd_netlink_message **ret) { + int r; + struct genlmsghdr *genl; + const NLType *genl_cmd_type, *nl_type; + const NLTypeSystem *type_system; + size_t size; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + + assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL); + + r = type_system_get_type(&genl_family_type_system_root, &genl_cmd_type, family); + if (r < 0) + return r; + + r = message_new_empty(nl, &m); + if (r < 0) + return r; + + size = NLMSG_SPACE(sizeof(struct genlmsghdr)); + m->hdr = malloc0(size); + if (!m->hdr) + return -ENOMEM; + + m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + + type_get_type_system(genl_cmd_type, &type_system); + + r = type_system_get_type(type_system, &nl_type, cmd); + if (r < 0) + return r; + + m->hdr->nlmsg_len = size; + m->hdr->nlmsg_type = nlmsg_type; + + type_get_type_system(nl_type, &m->containers[0].type_system); + genl = NLMSG_DATA(m->hdr); + genl->cmd = cmd; + genl->version = genl_families[family].version; + + *ret = m; + m = NULL; + + return 0; +} + +int sd_genl_message_new(sd_netlink *nl, sd_genl_family family, uint8_t cmd, sd_netlink_message **ret) { + int r; + uint16_t id = GENL_ID_CTRL; + + if (family != SD_GENL_ID_CTRL) { + r = lookup_id(nl, family, &id); + if (r < 0) + return r; + } + + return genl_message_new(nl, family, id, cmd, ret); +} + +static int lookup_id(sd_netlink *nl, sd_genl_family family, uint16_t *id) { + int r; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; + + r = sd_genl_message_new(nl, SD_GENL_ID_CTRL, CTRL_CMD_GETFAMILY, &req); + if (r < 0) + return r; + + r = sd_netlink_message_append_string(req, CTRL_ATTR_FAMILY_NAME, genl_families[family].name); + if (r < 0) + return r; + + r = sd_netlink_call(nl, req, 0, &reply); + if (r < 0) + return r; + + return sd_netlink_message_read_u16(reply, CTRL_ATTR_FAMILY_ID, id); +} diff --git a/src/libsystemd/sd-netlink/local-addresses.c b/src/libsystemd/sd-netlink/local-addresses.c index 23acec4061..81e55b6d9f 100644 --- a/src/libsystemd/sd-netlink/local-addresses.c +++ b/src/libsystemd/sd-netlink/local-addresses.c @@ -225,6 +225,8 @@ int local_gateways(sd_netlink *context, int ifindex, int af, struct local_addres continue; r = sd_netlink_message_read_u32(m, RTA_OIF, &ifi); + if (r == -ENODATA) /* Not all routes have an RTA_OIF attribute (for example nexthop ones) */ + continue; if (r < 0) return r; if (ifindex > 0 && (int) ifi != ifindex) diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index f045ff67ca..dc553d708c 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -62,6 +62,8 @@ struct sd_netlink { struct sockaddr_nl nl; } sockaddr; + int protocol; + Hashmap *broadcast_group_refs; bool broadcast_group_dont_leave:1; /* until we can rely on 4.2 */ @@ -111,6 +113,8 @@ struct sd_netlink_message { sd_netlink *rtnl; + int protocol; + struct nlmsghdr *hdr; struct netlink_container containers[RTNL_CONTAINER_DEPTH]; unsigned n_containers; /* number of containers */ @@ -123,6 +127,8 @@ struct sd_netlink_message { int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type); int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret); +int netlink_open_family(sd_netlink **ret, int family); + int socket_open(int family); int socket_bind(sd_netlink *nl); int socket_broadcast_group_ref(sd_netlink *nl, unsigned group); diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index c88754540e..af3d13edcd 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -55,7 +55,7 @@ int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) { return -ENOMEM; m->n_ref = REFCNT_INIT; - + m->protocol = rtnl->protocol; m->sealed = false; *ret = m; @@ -66,10 +66,15 @@ int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) { int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; const NLType *nl_type; + const NLTypeSystem *type_system_root; size_t size; int r; - r = type_system_get_type(&type_system_root, &nl_type, type); + assert_return(rtnl, -EINVAL); + + type_system_root = type_system_get_root(rtnl->protocol); + + r = type_system_get_type(type_system_root, &nl_type, type); if (r < 0) return r; @@ -111,9 +116,10 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) { } sd_netlink_message *sd_netlink_message_ref(sd_netlink_message *m) { - if (m) - assert_se(REFCNT_INC(m->n_ref) >= 2); + if (!m) + return NULL; + assert_se(REFCNT_INC(m->n_ref) >= 2); return m; } @@ -186,6 +192,10 @@ static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *da /* get the new message size (with padding at the end) */ message_length = offset + RTA_ALIGN(rta_length); + /* buffer should be smaller than both one page or 8K to be accepted by the kernel */ + if (message_length > MIN(page_size(), 8192UL)) + return -ENOBUFS; + /* realloc to fit the new attribute */ new_hdr = realloc(m->hdr, message_length); if (!new_hdr) @@ -490,7 +500,7 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor if (r < 0) return r; - /* do we evere need non-null size */ + /* do we ever need non-null size */ r = add_rtattr(m, type | NLA_F_NESTED, NULL, 0); if (r < 0) return r; @@ -500,14 +510,53 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor return 0; } - int sd_netlink_message_close_container(sd_netlink_message *m) { assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); assert_return(m->n_containers > 0, -EINVAL); m->containers[m->n_containers].type_system = NULL; + m->containers[m->n_containers].offset = 0; + m->n_containers--; + + return 0; +} + +int sd_netlink_message_open_array(sd_netlink_message *m, uint16_t type) { + int r; + + assert_return(m, -EINVAL); + assert_return(!m->sealed, -EPERM); + assert_return(m->n_containers > 0, -EINVAL); + + r = add_rtattr(m, type | NLA_F_NESTED, NULL, 0); + if (r < 0) + return r; + + m->containers[m->n_containers].offset = r; + m->n_containers++; + m->containers[m->n_containers].type_system = m->containers[m->n_containers - 1].type_system; + + return 0; +} + +int sd_netlink_message_cancel_array(sd_netlink_message *m) { + unsigned i; + uint32_t rta_len; + + assert_return(m, -EINVAL); + assert_return(!m->sealed, -EPERM); + assert_return(m->n_containers > 1, -EINVAL); + + rta_len = GET_CONTAINER(m, (m->n_containers - 1))->rta_len; + + for (i = 0; i < m->n_containers; i++) + GET_CONTAINER(m, i)->rta_len -= rta_len; + + m->hdr->nlmsg_len -= rta_len; + m->n_containers--; + m->containers[m->n_containers].type_system = NULL; return 0; } @@ -519,13 +568,14 @@ static int netlink_message_read_internal(sd_netlink_message *m, unsigned short t assert_return(m, -EINVAL); assert_return(m->sealed, -EPERM); assert_return(data, -EINVAL); + assert(m->n_containers < RTNL_CONTAINER_DEPTH); assert(m->containers[m->n_containers].attributes); assert(type < m->containers[m->n_containers].n_attributes); attribute = &m->containers[m->n_containers].attributes[type]; - if (!attribute->offset) + if (attribute->offset == 0) return -ENODATA; rta = (struct rtattr*)((uint8_t *) m->hdr + attribute->offset); @@ -745,7 +795,7 @@ static int netlink_container_parse(sd_netlink_message *m, if (type >= count) continue; - if (attributes[type].offset) + if (attributes[type].offset != 0) log_debug("rtnl: message parse - overwriting repeated attribute"); attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr; @@ -899,6 +949,7 @@ int sd_netlink_message_get_errno(sd_netlink_message *m) { int sd_netlink_message_rewind(sd_netlink_message *m) { const NLType *nl_type; + const NLTypeSystem *type_system_root; uint16_t type; size_t size; unsigned i; @@ -910,6 +961,8 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { if (!m->sealed) rtnl_message_seal(m); + type_system_root = type_system_get_root(m->protocol); + for (i = 1; i <= m->n_containers; i++) m->containers[i].attributes = mfree(m->containers[i].attributes); @@ -921,7 +974,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { assert(m->hdr); - r = type_system_get_type(&type_system_root, &nl_type, m->hdr->nlmsg_type); + r = type_system_get_type(type_system_root, &nl_type, m->hdr->nlmsg_type); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index 22be94382a..e08248c9f6 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -269,13 +269,13 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool }; struct cmsghdr *cmsg; uint32_t group = 0; - int r; + ssize_t n; assert(fd >= 0); assert(iov); - r = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0)); - if (r < 0) { + n = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0)); + if (n < 0) { /* no data */ if (errno == ENOBUFS) log_debug("rtnl: kernel receive buffer overrun"); @@ -291,8 +291,8 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool if (peek) { /* drop the message */ - r = recvmsg(fd, &msg, 0); - if (r < 0) + n = recvmsg(fd, &msg, 0); + if (n < 0) return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno; } @@ -313,7 +313,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool if (_group) *_group = group; - return r; + return (int) n; } /* On success, the number of bytes received is returned and *ret points to the received message @@ -330,17 +330,20 @@ int socket_read_message(sd_netlink *rtnl) { size_t len; int r; unsigned i = 0; + const NLTypeSystem *type_system_root; assert(rtnl); assert(rtnl->rbuffer); assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr)); + type_system_root = type_system_get_root(rtnl->protocol); + /* read nothing, just get the pending message size */ r = socket_recv_message(rtnl->fd, &iov, NULL, true); if (r <= 0) return r; else - len = (size_t)r; + len = (size_t) r; /* make room for the pending message */ if (!greedy_realloc((void **)&rtnl->rbuffer, @@ -356,7 +359,7 @@ int socket_read_message(sd_netlink *rtnl) { if (r <= 0) return r; else - len = (size_t)r; + len = (size_t) r; if (len > rtnl->rbuffer_allocated) /* message did not fit in read buffer */ @@ -396,7 +399,7 @@ int socket_read_message(sd_netlink *rtnl) { } /* check that we support this message type */ - r = type_system_get_type(&type_system_root, &nl_type, new_msg->nlmsg_type); + r = type_system_get_type(type_system_root, &nl_type, new_msg->nlmsg_type); if (r < 0) { if (r == -EOPNOTSUPP) log_debug("sd-netlink: ignored message with unknown type: %i", @@ -433,7 +436,7 @@ int socket_read_message(sd_netlink *rtnl) { m = NULL; } - if (len) + if (len > 0) log_debug("sd-netlink: discarding %zu bytes of incoming message", len); if (!first) @@ -459,9 +462,9 @@ int socket_read_message(sd_netlink *rtnl) { } else { /* we only got a partial multi-part message, push it on the partial read queue */ - if (i < rtnl->rqueue_partial_size) { + if (i < rtnl->rqueue_partial_size) rtnl->rqueue_partial[i] = first; - } else { + else { r = rtnl_rqueue_partial_make_room(rtnl); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index f8be296d37..0ee7d6f0dc 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -18,25 +18,22 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <netinet/in.h> #include <stdint.h> #include <sys/socket.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> +#include <linux/genetlink.h> +#include <linux/ip.h> +#include <linux/if.h> #include <linux/can/netlink.h> #include <linux/fib_rules.h> -#include <linux/in6.h> -#include <linux/veth.h> -#include <linux/if_bridge.h> #include <linux/if_addr.h> #include <linux/if_addrlabel.h> -#include <linux/if.h> -#include <linux/ip.h> -#include <linux/if_addr.h> #include <linux/if_bridge.h> #include <linux/if_link.h> #include <linux/if_tunnel.h> -#include <linux/fib_rules.h> - +#include <linux/veth.h> #if HAVE_VXCAN_INFO_PEER #include <linux/can/vxcan.h> #endif @@ -44,8 +41,10 @@ #include "macro.h" #include "missing.h" #include "netlink-types.h" +#include "sd-netlink.h" #include "string-table.h" #include "util.h" +#include "wireguard-netlink.h" /* Maximum ARP IP target defined in kernel */ #define BOND_MAX_ARP_TARGETS 16 @@ -102,6 +101,7 @@ static const NLType rtnl_link_info_data_vxcan_types[] = { static const NLType rtnl_link_info_data_ipvlan_types[] = { [IFLA_IPVLAN_MODE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, }; static const NLType rtnl_link_info_data_macvlan_types[] = { @@ -337,7 +337,7 @@ static const char* const nl_union_link_info_data_table[] = { [NL_UNION_LINK_INFO_DATA_VCAN] = "vcan", [NL_UNION_LINK_INFO_DATA_GENEVE] = "geneve", [NL_UNION_LINK_INFO_DATA_VXCAN] = "vxcan", - + [NL_UNION_LINK_INFO_DATA_WIREGUARD] = "wireguard", }; DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); @@ -552,6 +552,8 @@ static const NLType rtnl_route_metrics_types[] = { [RTAX_INITCWND] = { .type = NETLINK_TYPE_U32 }, [RTAX_FEATURES] = { .type = NETLINK_TYPE_U32 }, [RTAX_RTO_MIN] = { .type = NETLINK_TYPE_U32 }, + [RTAX_INITRWND] = { .type = NETLINK_TYPE_U32 }, + [RTAX_QUICKACK] = { .type = NETLINK_TYPE_U32 }, }; static const NLTypeSystem rtnl_route_metrics_type_system = { @@ -663,11 +665,98 @@ static const NLType rtnl_types[] = { [RTM_GETRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) }, }; -const NLTypeSystem type_system_root = { +const NLTypeSystem rtnl_type_system_root = { .count = ELEMENTSOF(rtnl_types), .types = rtnl_types, }; +static const NLType genl_wireguard_allowedip_types[] = { + [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 }, + [WGALLOWEDIP_A_IPADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [WGALLOWEDIP_A_CIDR_MASK] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLTypeSystem genl_wireguard_allowedip_type_system = { + .count = ELEMENTSOF(genl_wireguard_allowedip_types), + .types = genl_wireguard_allowedip_types, +}; + +static const NLType genl_wireguard_peer_types[] = { + [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [WGPEER_A_ENDPOINT] = { /* either size of sockaddr_in or sockaddr_in6 depending on address family */ }, + [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system }, +}; + +static const NLTypeSystem genl_wireguard_peer_type_system = { + .count = ELEMENTSOF(genl_wireguard_peer_types), + .types = genl_wireguard_peer_types, +}; + +static const NLType genl_wireguard_set_device_types[] = { + [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING }, + [WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_PRIVATE_KEY] = { .size = WG_KEY_LEN }, + [WGDEVICE_A_LISTEN_PORT] = { .type = NETLINK_TYPE_U16 }, + [WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, +}; + +static const NLTypeSystem genl_wireguard_set_device_type_system = { + .count = ELEMENTSOF(genl_wireguard_set_device_types), + .types = genl_wireguard_set_device_types, +}; + +static const NLType genl_wireguard_cmds[] = { + [WG_CMD_SET_DEVICE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_set_device_type_system }, +}; + +static const NLTypeSystem genl_wireguard_type_system = { + .count = ELEMENTSOF(genl_wireguard_cmds), + .types = genl_wireguard_cmds, +}; + +static const NLType genl_get_family_types[] = { + [CTRL_ATTR_FAMILY_NAME] = { .type = NETLINK_TYPE_STRING }, + [CTRL_ATTR_FAMILY_ID] = { .type = NETLINK_TYPE_U16 }, +}; + +static const NLTypeSystem genl_get_family_type_system = { + .count = ELEMENTSOF(genl_get_family_types), + .types = genl_get_family_types, +}; + +static const NLType genl_ctrl_id_ctrl_cmds[] = { + [CTRL_CMD_GETFAMILY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system }, +}; + +static const NLTypeSystem genl_ctrl_id_ctrl_type_system = { + .count = ELEMENTSOF(genl_ctrl_id_ctrl_cmds), + .types = genl_ctrl_id_ctrl_cmds, +}; + +static const NLType genl_families[] = { + [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system }, + [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, +}; + +const NLTypeSystem genl_family_type_system_root = { + .count = ELEMENTSOF(genl_families), + .types = genl_families, +}; + +static const NLType genl_types[] = { + [GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system, .size = sizeof(struct genlmsghdr) }, +}; + +const NLTypeSystem genl_type_system_root = { + .count = ELEMENTSOF(genl_types), + .types = genl_types, +}; + uint16_t type_get_type(const NLType *type) { assert(type); return type->type; @@ -701,6 +790,15 @@ uint16_t type_system_get_count(const NLTypeSystem *type_system) { return type_system->count; } +const NLTypeSystem *type_system_get_root(int protocol) { + switch (protocol) { + case NETLINK_GENERIC: + return &genl_type_system_root; + default: /* NETLINK_ROUTE: */ + return &rtnl_type_system_root; + } +} + int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) { const NLType *nl_type; diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 57b46339f9..ea7f8d5e6c 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -54,13 +54,16 @@ struct NLTypeSystemUnion { const NLTypeSystem *type_systems; }; -extern const NLTypeSystem type_system_root; +extern const NLTypeSystem rtnl_type_system_root; +extern const NLTypeSystem genl_type_system_root; +extern const NLTypeSystem genl_family_type_system_root; uint16_t type_get_type(const NLType *type); size_t type_get_size(const NLType *type); void type_get_type_system(const NLType *type, const NLTypeSystem **ret); void type_get_type_system_union(const NLType *type, const NLTypeSystemUnion **ret); +const NLTypeSystem* type_system_get_root(int protocol); uint16_t type_system_get_count(const NLTypeSystem *type_system); int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type); @@ -91,6 +94,7 @@ typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_VCAN, NL_UNION_LINK_INFO_DATA_GENEVE, NL_UNION_LINK_INFO_DATA_VXCAN, + NL_UNION_LINK_INFO_DATA_WIREGUARD, _NL_UNION_LINK_INFO_DATA_MAX, _NL_UNION_LINK_INFO_DATA_INVALID = -1 } NLUnionLinkInfoData; diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c index b32fad271a..7680b30e70 100644 --- a/src/libsystemd/sd-netlink/netlink-util.c +++ b/src/libsystemd/sd-netlink/netlink-util.c @@ -98,13 +98,13 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, return 0; } -int rtnl_message_new_synthetic_error(int error, uint32_t serial, sd_netlink_message **ret) { +int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) { struct nlmsgerr *err; int r; assert(error <= 0); - r = message_new(NULL, ret, NLMSG_ERROR); + r = message_new(rtnl, ret, NLMSG_ERROR); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h index c804f5514c..795e4dc15c 100644 --- a/src/libsystemd/sd-netlink/netlink-util.h +++ b/src/libsystemd/sd-netlink/netlink-util.h @@ -24,7 +24,7 @@ #include "util.h" -int rtnl_message_new_synthetic_error(int error, uint32_t serial, sd_netlink_message **ret); +int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret); uint32_t rtnl_message_get_serial(sd_netlink_message *m); void rtnl_message_seal(sd_netlink_message *m); diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index 924b0c954f..116e287bb6 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -30,6 +30,7 @@ #include "missing.h" #include "netlink-internal.h" #include "netlink-util.h" +#include "process-util.h" #include "socket-util.h" #include "util.h" @@ -46,6 +47,7 @@ static int sd_netlink_new(sd_netlink **ret) { rtnl->fd = -1; rtnl->sockaddr.nl.nl_family = AF_NETLINK; rtnl->original_pid = getpid_cached(); + rtnl->protocol = -1; LIST_HEAD_INIT(rtnl->match_callbacks); @@ -106,6 +108,8 @@ static bool rtnl_pid_changed(sd_netlink *rtnl) { int sd_netlink_open_fd(sd_netlink **ret, int fd) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; int r; + int protocol; + socklen_t l; assert_return(ret, -EINVAL); assert_return(fd >= 0, -EBADF); @@ -114,11 +118,18 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) { if (r < 0) return r; + l = sizeof(protocol); + r = getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &l); + if (r < 0) + return r; + rtnl->fd = fd; + rtnl->protocol = protocol; r = socket_bind(rtnl); if (r < 0) { rtnl->fd = -1; /* on failure, the caller remains owner of the fd, hence don't close it here */ + rtnl->protocol = -1; return r; } @@ -128,11 +139,11 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) { return 0; } -int sd_netlink_open(sd_netlink **ret) { +int netlink_open_family(sd_netlink **ret, int family) { _cleanup_close_ int fd = -1; int r; - fd = socket_open(NETLINK_ROUTE); + fd = socket_open(family); if (fd < 0) return fd; @@ -145,6 +156,10 @@ int sd_netlink_open(sd_netlink **ret) { return 0; } +int sd_netlink_open(sd_netlink **ret) { + return netlink_open_family(ret, NETLINK_ROUTE); +} + int sd_netlink_inc_rcvbuf(sd_netlink *rtnl, size_t size) { assert_return(rtnl, -EINVAL); assert_return(!rtnl_pid_changed(rtnl), -ECHILD); @@ -309,7 +324,7 @@ static int process_timeout(sd_netlink *rtnl) { if (c->timeout > n) return 0; - r = rtnl_message_new_synthetic_error(-ETIMEDOUT, c->serial, &m); + r = rtnl_message_new_synthetic_error(rtnl, -ETIMEDOUT, c->serial, &m); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/test-local-addresses.c b/src/libsystemd/sd-netlink/test-local-addresses.c index bb195b9de9..bf11042221 100644 --- a/src/libsystemd/sd-netlink/test-local-addresses.c +++ b/src/libsystemd/sd-netlink/test-local-addresses.c @@ -38,6 +38,10 @@ int main(int argc, char *argv[]) { struct local_address *a; int n; + log_set_max_level(LOG_DEBUG); + log_parse_environment(); + log_open(); + a = NULL; n = local_addresses(NULL, 0, AF_UNSPEC, &a); assert_se(n >= 0); diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 73e5af0060..9ccc8ea607 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -143,13 +143,13 @@ static void test_address_get(sd_netlink *rtnl, int ifindex) { } -static void test_route(void) { +static void test_route(sd_netlink *rtnl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req; struct in_addr addr, addr_data; uint32_t index = 2, u32_data; int r; - r = sd_rtnl_message_new_route(NULL, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC); + r = sd_rtnl_message_new_route(rtnl, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC); if (r < 0) { log_error_errno(r, "Could not create RTM_NEWROUTE message: %m"); return; @@ -291,13 +291,13 @@ static void test_pipe(int ifindex) { assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); } -static void test_container(void) { +static void test_container(sd_netlink *rtnl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; uint16_t u16_data; uint32_t u32_data; const char *string_data; - assert_se(sd_rtnl_message_new_link(NULL, &m, RTM_NEWLINK, 0) >= 0); + assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0); assert_se(sd_netlink_message_open_container(m, IFLA_LINKINFO) >= 0); assert_se(sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "vlan") >= 0); @@ -369,10 +369,10 @@ static void test_get_addresses(sd_netlink *rtnl) { } } -static void test_message(void) { +static void test_message(sd_netlink *rtnl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - assert_se(rtnl_message_new_synthetic_error(-ETIMEDOUT, 1, &m) >= 0); + assert_se(rtnl_message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m) >= 0); assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT); } @@ -384,19 +384,19 @@ int main(void) { int if_loopback; uint16_t type; - test_message(); - test_match(); test_multiple(); - test_route(); - - test_container(); - assert_se(sd_netlink_open(&rtnl) >= 0); assert_se(rtnl); + test_route(rtnl); + + test_message(rtnl); + + test_container(rtnl); + if_loopback = (int) if_nametoindex("lo"); assert_se(if_loopback > 0); diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c index be3748e3ce..787642a7fb 100644 --- a/src/libsystemd/sd-resolve/sd-resolve.c +++ b/src/libsystemd/sd-resolve/sd-resolve.c @@ -40,6 +40,7 @@ #include "missing.h" #include "socket-util.h" #include "util.h" +#include "process-util.h" #define WORKERS_MIN 1U #define WORKERS_MAX 16U @@ -398,14 +399,9 @@ static int handle_request(int out_fd, const Packet *packet, size_t length) { static void* thread_worker(void *p) { sd_resolve *resolve = p; - sigset_t fullset; - - /* No signals in this thread please */ - assert_se(sigfillset(&fullset) == 0); - assert_se(pthread_sigmask(SIG_BLOCK, &fullset, NULL) == 0); /* Assign a pretty name to this thread */ - (void) prctl(PR_SET_NAME, (unsigned long) "sd-resolve"); + (void) pthread_setname_np(pthread_self(), "sd-resolve"); while (!resolve->dead) { union { @@ -437,8 +433,18 @@ static void* thread_worker(void *p) { } static int start_threads(sd_resolve *resolve, unsigned extra) { + sigset_t ss, saved_ss; unsigned n; - int r; + int r, k; + + if (sigfillset(&ss) < 0) + return -errno; + + /* No signals in forked off threads please. We set the mask before forking, so that the threads never exist + * with a different mask than a fully blocked one */ + r = pthread_sigmask(SIG_BLOCK, &ss, &saved_ss); + if (r > 0) + return -r; n = resolve->n_outstanding + extra; n = CLAMP(n, WORKERS_MIN, WORKERS_MAX); @@ -446,13 +452,22 @@ static int start_threads(sd_resolve *resolve, unsigned extra) { while (resolve->n_valid_workers < n) { r = pthread_create(&resolve->workers[resolve->n_valid_workers], NULL, thread_worker, resolve); - if (r != 0) - return -r; + if (r > 0) { + r = -r; + goto finish; + } resolve->n_valid_workers++; } - return 0; + r = 0; + +finish: + k = pthread_sigmask(SIG_SETMASK, &saved_ss, NULL); + if (k > 0 && r >= 0) + r = -k; + + return r; } static bool resolve_pid_changed(sd_resolve *r) { diff --git a/src/libsystemd/sd-resolve/test-resolve.c b/src/libsystemd/sd-resolve/test-resolve.c index 752eb15228..b728dee9dd 100644 --- a/src/libsystemd/sd-resolve/test-resolve.c +++ b/src/libsystemd/sd-resolve/test-resolve.c @@ -89,7 +89,9 @@ int main(int argc, char *argv[]) { assert_se(sd_resolve_default(&resolve) >= 0); /* Test a floating resolver query */ - sd_resolve_getaddrinfo(resolve, NULL, "redhat.com", "http", NULL, getaddrinfo_handler, NULL); + r = sd_resolve_getaddrinfo(resolve, NULL, "redhat.com", "http", NULL, getaddrinfo_handler, NULL); + if (r < 0) + log_error_errno(r, "sd_resolve_getaddrinfo(): %m"); /* Make a name -> address query */ r = sd_resolve_getaddrinfo(resolve, &q1, argc >= 2 ? argv[1] : "www.heise.de", NULL, &hints, getaddrinfo_handler, NULL); diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c index b941afb773..85ceb263a3 100644 --- a/src/libudev/libudev-queue.c +++ b/src/libudev/libudev-queue.c @@ -268,8 +268,16 @@ _public_ int udev_queue_get_fd(struct udev_queue *udev_queue) { * Returns: the result of clearing the watch for queue changes. */ _public_ int udev_queue_flush(struct udev_queue *udev_queue) { + int r; + + assert(udev_queue); + if (udev_queue->fd < 0) return -EINVAL; - return flush_fd(udev_queue->fd); + r = flush_fd(udev_queue->fd); + if (r < 0) + return r; + + return 0; } diff --git a/src/libudev/meson.build b/src/libudev/meson.build index 30d6721b60..c381352ce8 100644 --- a/src/libudev/meson.build +++ b/src/libudev/meson.build @@ -31,21 +31,8 @@ libudev_sources = files(''' ############################################################ -libudev_sym = 'libudev.sym' -libudev_sym_path = '@0@/@1@'.format(meson.current_source_dir(), libudev_sym) -libudev = shared_library( - 'udev', - libudev_sources, - version : libudev_version, - include_directories : includes, - link_args : ['-shared', - '-Wl,--version-script=' + libudev_sym_path], - link_with : [libbasic, - libsystemd_internal], - dependencies : [threads], - link_depends : libudev_sym, - install : true, - install_dir : rootlibdir) +libudev_sym = files('libudev.sym') +libudev_sym_path = meson.current_source_dir() + '/libudev.sym' install_headers('libudev.h') libudev_h_path = '@0@/libudev.h'.format(meson.current_source_dir()) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index f09fe42626..af39e431f5 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -595,7 +595,7 @@ static int localectl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char*argv[]) { - _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -615,6 +615,9 @@ int main(int argc, char*argv[]) { r = localectl_main(bus, argc, argv); finish: + /* make sure we terminate the bus connection first, and then close the + * pager, see issue #3543 for the details. */ + sd_bus_flush_close_unref(bus); pager_close(); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/src/locale/localed.c b/src/locale/localed.c index 3e3f03e046..02f5e8c656 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -652,9 +652,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { if (r < 0) return log_error_errno(r, "Failed to register object: %m"); - r = sd_bus_request_name(bus, "org.freedesktop.locale1", 0); + r = sd_bus_request_name_async(bus, NULL, "org.freedesktop.locale1", 0, NULL, NULL); if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); + return log_error_errno(r, "Failed to request name: %m"); r = sd_bus_attach_event(bus, event, 0); if (r < 0) diff --git a/src/login/73-seat-late.rules.in b/src/login/73-seat-late.rules.m4 index d2546c8ee9..4db8d4dd4c 100644 --- a/src/login/73-seat-late.rules.in +++ b/src/login/73-seat-late.rules.m4 @@ -13,7 +13,8 @@ ENV{ID_SEAT}=="", ENV{ID_AUTOSEAT}=="1", ENV{ID_FOR_SEAT}!="", ENV{ID_SEAT}="sea ENV{ID_SEAT}=="", IMPORT{parent}="ID_SEAT" ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}" - -TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess" +m4_ifdef(`HAVE_ACL',`` +TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess"'' +)m4_dnl LABEL="seat_late_end" diff --git a/src/login/inhibit.c b/src/login/inhibit.c index 7b9e3f0f6e..22657f9eda 100644 --- a/src/login/inhibit.c +++ b/src/login/inhibit.c @@ -266,26 +266,17 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - pid = fork(); - if (pid < 0) { - log_error_errno(errno, "Failed to fork: %m"); + r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); + if (r < 0) return EXIT_FAILURE; - } - - if (pid == 0) { + if (r == 0) { /* Child */ - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - - close_all_fds(NULL, 0); - execvp(argv[optind], argv + optind); log_error_errno(errno, "Failed to execute %s: %m", argv[optind]); _exit(EXIT_FAILURE); } - r = wait_for_terminate_and_warn(argv[optind], pid, true); + r = wait_for_terminate_and_check(argv[optind], pid, WAIT_LOG); return r < 0 ? EXIT_FAILURE : r; } diff --git a/src/login/loginctl.c b/src/login/loginctl.c index dfcaff6195..c811ee6c5e 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -1584,7 +1584,7 @@ static int loginctl_main(int argc, char *argv[], sd_bus *bus) { } int main(int argc, char *argv[]) { - _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -1607,6 +1607,9 @@ int main(int argc, char *argv[]) { r = loginctl_main(argc, argv, bus); finish: + /* make sure we terminate the bus connection first, and then close the + * pager, see issue #3543 for the details. */ + sd_bus_flush_close_unref(bus); pager_close(); polkit_agent_close(); diff --git a/src/login/logind-core.c b/src/login/logind-core.c index adeba746f5..e338682f41 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -31,6 +31,7 @@ #include "fd-util.h" #include "logind.h" #include "parse-util.h" +#include "process-util.h" #include "strv.h" #include "terminal-util.h" #include "udev-util.h" diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c index 8a6487ea45..e14835292e 100644 --- a/src/login/logind-inhibit.c +++ b/src/login/logind-inhibit.c @@ -305,7 +305,7 @@ int inhibitor_create_fifo(Inhibitor *i) { /* Open reading side */ if (i->fifo_fd < 0) { - i->fifo_fd = open(i->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY); + i->fifo_fd = open(i->fifo_path, O_RDONLY|O_CLOEXEC|O_NONBLOCK); if (i->fifo_fd < 0) return -errno; } @@ -321,7 +321,7 @@ int inhibitor_create_fifo(Inhibitor *i) { } /* Open writing side */ - r = open(i->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY); + r = open(i->fifo_path, O_WRONLY|O_CLOEXEC|O_NONBLOCK); if (r < 0) return -errno; diff --git a/src/login/logind-session.c b/src/login/logind-session.c index c4bde80c0c..92eb2943fe 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -962,7 +962,7 @@ int session_create_fifo(Session *s) { /* Open reading side */ if (s->fifo_fd < 0) { - s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY); + s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NONBLOCK); if (s->fifo_fd < 0) return -errno; @@ -981,7 +981,7 @@ int session_create_fifo(Session *s) { } /* Open writing side */ - r = open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY); + r = open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NONBLOCK); if (r < 0) return -errno; diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c index 9fca5ce0cd..d5d086cfe0 100644 --- a/src/login/logind-user-dbus.c +++ b/src/login/logind-user-dbus.c @@ -288,13 +288,13 @@ int user_object_find(sd_bus *bus, const char *path, const char *interface, void return 0; r = parse_uid(p, &uid); - } - if (r < 0) - return 0; + if (r < 0) + return 0; - user = hashmap_get(m->users, UID_TO_PTR(uid)); - if (!user) - return 0; + user = hashmap_get(m->users, UID_TO_PTR(uid)); + if (!user) + return 0; + } *found = user; return 1; diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 94e250b94a..32b2045696 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -344,16 +344,13 @@ static int user_mkdir_runtime_path(User *u) { if (path_is_mount_point(u->runtime_path, NULL, 0) <= 0) { _cleanup_free_ char *t = NULL; - (void) mkdir_label(u->runtime_path, 0700); + r = asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu%s", + u->uid, u->gid, u->manager->runtime_dir_size, + mac_smack_use() ? ",smackfsroot=*" : ""); + if (r < 0) + return log_oom(); - if (mac_smack_use()) - r = asprintf(&t, "mode=0700,smackfsroot=*,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size); - else - r = asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size); - if (r < 0) { - r = log_oom(); - goto fail; - } + (void) mkdir_label(u->runtime_path, 0700); r = mount("tmpfs", u->runtime_path, "tmpfs", MS_NODEV|MS_NOSUID, t); if (r < 0) { @@ -461,7 +458,7 @@ int user_start(User *u) { u->stopping = false; if (!u->started) { - log_debug("New user %s logged in.", u->name); + log_debug("Starting services for new user %s.", u->name); /* Make XDG_RUNTIME_DIR */ r = user_mkdir_runtime_path(u); @@ -530,9 +527,7 @@ static int user_stop_service(User *u) { return r; } - free(u->service_job); - u->service_job = job; - + free_and_replace(u->service_job, job); return r; } diff --git a/src/login/logind.c b/src/login/logind.c index 49ca367e18..d15d4cec5b 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -29,17 +29,18 @@ #include "alloc-util.h" #include "bus-error.h" #include "bus-util.h" +#include "cgroup-util.h" #include "conf-parser.h" #include "def.h" #include "dirent-util.h" #include "fd-util.h" #include "format-util.h" #include "logind.h" +#include "process-util.h" #include "selinux-util.h" #include "signal-util.h" #include "strv.h" #include "udev-util.h" -#include "cgroup-util.h" static void manager_free(Manager *m); @@ -658,7 +659,6 @@ static int manager_reserve_vt(Manager *m) { } static int manager_connect_bus(Manager *m) { - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(m); @@ -696,65 +696,65 @@ static int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to add user enumerator: %m"); - r = sd_bus_add_match(m->bus, - NULL, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Manager'," - "member='JobRemoved'," - "path='/org/freedesktop/systemd1'", - match_job_removed, m); + r = sd_bus_match_signal_async( + m->bus, + NULL, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "JobRemoved", + match_job_removed, NULL, m); if (r < 0) - return log_error_errno(r, "Failed to add match for JobRemoved: %m"); - - r = sd_bus_add_match(m->bus, - NULL, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Manager'," - "member='UnitRemoved'," - "path='/org/freedesktop/systemd1'", - match_unit_removed, m); + return log_error_errno(r, "Failed to request match for JobRemoved: %m"); + + r = sd_bus_match_signal_async( + m->bus, + NULL, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "UnitRemoved", + match_unit_removed, NULL, m); if (r < 0) - return log_error_errno(r, "Failed to add match for UnitRemoved: %m"); - - r = sd_bus_add_match(m->bus, - NULL, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.DBus.Properties'," - "member='PropertiesChanged'", - match_properties_changed, m); + return log_error_errno(r, "Failed to request match for UnitRemoved: %m"); + + r = sd_bus_match_signal_async( + m->bus, + NULL, + "org.freedesktop.systemd1", + NULL, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + match_properties_changed, NULL, m); if (r < 0) - return log_error_errno(r, "Failed to add match for PropertiesChanged: %m"); - - r = sd_bus_add_match(m->bus, - NULL, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Manager'," - "member='Reloading'," - "path='/org/freedesktop/systemd1'", - match_reloading, m); + return log_error_errno(r, "Failed to request match for PropertiesChanged: %m"); + + r = sd_bus_match_signal_async( + m->bus, + NULL, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Reloading", + match_reloading, NULL, m); if (r < 0) - return log_error_errno(r, "Failed to add match for Reloading: %m"); + return log_error_errno(r, "Failed to request match for Reloading: %m"); - r = sd_bus_call_method( + r = sd_bus_call_method_async( m->bus, + NULL, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Subscribe", - &error, - NULL, NULL); - if (r < 0) { - log_error("Failed to enable subscription: %s", bus_error_message(&error, r)); - return r; - } + NULL, NULL, + NULL); + if (r < 0) + return log_error_errno(r, "Failed to enable subscription: %m"); - r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0); + r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.login1", 0, NULL, NULL); if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); + return log_error_errno(r, "Failed to request name: %m"); r = sd_bus_attach_event(m->bus, m->event, SD_EVENT_PRIORITY_NORMAL); if (r < 0) diff --git a/src/login/meson.build b/src/login/meson.build index 33f9ed48cc..e8e4f7bd7d 100644 --- a/src/login/meson.build +++ b/src/login/meson.build @@ -97,19 +97,27 @@ if conf.get('ENABLE_LOGIND') == 1 install : install_polkit, install_dir : polkitpolicydir) - install_data('70-power-switch.rules', - '70-uaccess.rules', + install_data('70-power-switch.rules', install_dir : udevrulesdir) + + if conf.get('HAVE_ACL') == 1 + install_data('70-uaccess.rules', install_dir : udevrulesdir) + endif + + seat_rules = configure_file( + input : '71-seat.rules.in', + output : '71-seat.rules', + configuration : substs) + install_data(seat_rules, install_dir : udevrulesdir) - foreach file : ['71-seat.rules', - '73-seat-late.rules'] - gen = configure_file( - input : file + '.in', - output : file, - configuration : substs) - install_data(gen, - install_dir : udevrulesdir) - endforeach + custom_target( + '73-seat-late.rules', + input : '73-seat-late.rules.m4', + output: '73-seat-late.rules', + command : [m4, '-P'] + m4_defines + ['@INPUT@'], + capture : true, + install : true, + install_dir : udevrulesdir) custom_target( 'systemd-user', diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index 246bbddeee..1c3ba33e23 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -197,7 +197,7 @@ static int export_legacy_dbus_address( return PAM_SUCCESS; s = mfree(s); - if (asprintf(&s, UNIX_USER_BUS_ADDRESS_FMT, runtime) < 0) + if (asprintf(&s, DEFAULT_USER_BUS_ADDRESS_FMT, runtime) < 0) goto error; r = pam_misc_setenv(handle, "DBUS_SESSION_BUS_ADDRESS", s, 0); diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index 10d1b06016..8ba1380c81 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -75,10 +75,10 @@ int bus_image_method_remove( if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m"); - child = fork(); - if (child < 0) - return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); - if (child == 0) { + r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); + if (r == 0) { errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); r = image_remove(image); @@ -187,10 +187,10 @@ int bus_image_method_clone( if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m"); - child = fork(); - if (child < 0) - return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); - if (child == 0) { + r = safe_fork("(imgclone)", FORK_RESET_SIGNALS, &child); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); + if (r == 0) { errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); r = image_clone(image, new_name, read_only); diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 3761267b57..2d7806491b 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -228,7 +228,6 @@ int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd _cleanup_free_ char *us = NULL, *them = NULL; _cleanup_close_ int netns_fd = -1; const char *p; - siginfo_t si; pid_t child; r = readlink_malloc("/proc/self/ns/net", &us); @@ -250,11 +249,10 @@ int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0) return -errno; - child = fork(); - if (child < 0) - return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); - - if (child == 0) { + r = safe_fork("(sd-addr)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); + if (r == 0) { _cleanup_free_ struct local_address *addresses = NULL; struct local_address *a; int i, n; @@ -338,10 +336,10 @@ int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd return r; } - r = wait_for_terminate(child, &si); + r = wait_for_terminate_and_check("(sd-addr)", child, 0); if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m"); - if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) + if (r != EXIT_SUCCESS) return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally."); break; } @@ -380,7 +378,6 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s _cleanup_close_ int mntns_fd = -1, root_fd = -1; _cleanup_close_pair_ int pair[2] = { -1, -1 }; _cleanup_fclose_ FILE *f = NULL; - siginfo_t si; pid_t child; r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd); @@ -390,11 +387,10 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0) return -errno; - child = fork(); - if (child < 0) - return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); - - if (child == 0) { + r = safe_fork("(sd-osrel)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); + if (r == 0) { int fd = -1; pair[0] = safe_close(pair[0]); @@ -431,12 +427,12 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s if (r < 0) return r; - r = wait_for_terminate(child, &si); + r = wait_for_terminate_and_check("(sd-osrel)", child, 0); if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m"); - if (si.si_code == CLD_EXITED && si.si_status == EXIT_NOT_FOUND) + if (r == EXIT_NOT_FOUND) return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Machine does not contain OS release information"); - if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) + if (r != EXIT_SUCCESS) return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally."); break; @@ -613,7 +609,7 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu _cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL; sd_bus *container_bus = NULL; _cleanup_close_ int master = -1, slave = -1; - _cleanup_strv_free_ char **env = NULL, **args = NULL; + _cleanup_strv_free_ char **env = NULL, **args_wire = NULL, **args = NULL; Machine *m = userdata; const char *p, *unit, *user, *path, *description, *utmp_id; int r; @@ -625,22 +621,41 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu if (r < 0) return r; user = empty_to_null(user); - if (isempty(path)) - path = "/bin/sh"; - if (!path_is_absolute(path)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified path '%s' is not absolute", path); - - r = sd_bus_message_read_strv(message, &args); + r = sd_bus_message_read_strv(message, &args_wire); if (r < 0) return r; - if (strv_isempty(args)) { - args = strv_free(args); + if (isempty(path)) { + path = "/bin/sh"; - args = strv_new(path, NULL); + args = new0(char*, 3 + 1); if (!args) return -ENOMEM; - - args[0][0] = '-'; /* Tell /bin/sh that this shall be a login shell */ + args[0] = strdup("sh"); + if (!args[0]) + return -ENOMEM; + args[1] = strdup("-c"); + if (!args[1]) + return -ENOMEM; + r = asprintf(&args[2], + "shell=$(getent passwd %s 2>/dev/null | { IFS=: read _ _ _ _ _ _ x; echo \"$x\"; })\n"\ + "exec \"${shell:-/bin/sh}\" -l", /* -l is means --login */ + isempty(user) ? "root" : user); + if (r < 0) { + args[2] = NULL; + return -ENOMEM; + } + } else { + if (!path_is_absolute(path)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified path '%s' is not absolute", path); + args = args_wire; + args_wire = NULL; + if (strv_isempty(args)) { + args = strv_free(args); + + args = strv_new(path, NULL); + if (!args) + return -ENOMEM; + } } r = sd_bus_message_read_strv(message, &env); @@ -842,7 +857,6 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu const char *dest, *src; Machine *m = userdata; struct stat st; - siginfo_t si; pid_t child; uid_t uid; int r; @@ -931,7 +945,7 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu /* Second, we mount the source file or directory to a directory inside of our MS_SLAVE playground. */ mount_tmp = strjoina(mount_slave, "/mount"); if (S_ISDIR(st.st_mode)) - r = mkdir(mount_tmp, 0700) < 0 ? -errno : 0; + r = mkdir_errno_wrapper(mount_tmp, 0700); else r = touch(mount_tmp); if (r < 0) { @@ -997,13 +1011,12 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu goto finish; } - child = fork(); - if (child < 0) { - r = sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); + r = safe_fork("(sd-bindmnt)", FORK_RESET_SIGNALS, &child); + if (r < 0) { + sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); goto finish; } - - if (child == 0) { + if (r == 0) { const char *mount_inside; int mntfd; const char *q; @@ -1049,17 +1062,12 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]); - r = wait_for_terminate(child, &si); + r = wait_for_terminate_and_check("(sd-bindmnt)", child, 0); if (r < 0) { r = sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m"); goto finish; } - if (si.si_code != CLD_EXITED) { - r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally."); - goto finish; - } - if (si.si_status != EXIT_SUCCESS) { - + if (r != EXIT_SUCCESS) { if (read(errno_pipe_fd[0], &r, sizeof(r)) == sizeof(r)) r = sd_bus_error_set_errnof(error, r, "Failed to mount: %m"); else @@ -1172,11 +1180,10 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m"); - child = fork(); - if (child < 0) - return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); - - if (child == 0) { + r = safe_fork("(sd-copy)", FORK_RESET_SIGNALS, &child); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); + if (r == 0) { int containerfd; const char *q; int mntfd; @@ -1272,7 +1279,6 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda case MACHINE_CONTAINER: { _cleanup_close_ int mntns_fd = -1, root_fd = -1; _cleanup_close_pair_ int pair[2] = { -1, -1 }; - siginfo_t si; pid_t child; r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd); @@ -1282,11 +1288,10 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0) return -errno; - child = fork(); - if (child < 0) - return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); - - if (child == 0) { + r = safe_fork("(sd-openroot)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); + if (r == 0) { _cleanup_close_ int dfd = -1; pair[0] = safe_close(pair[0]); @@ -1309,10 +1314,10 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda pair[1] = safe_close(pair[1]); - r = wait_for_terminate(child, &si); + r = wait_for_terminate_and_check("(sd-openroot)", child, 0); if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m"); - if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) + if (r != EXIT_SUCCESS) return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally."); fd = receive_one_fd(pair[0], MSG_DONTWAIT); diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index c435bb9b5a..75743ce6a6 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -1568,9 +1568,9 @@ static int login_machine(int argc, char *argv[], void *userdata) { "member='MachineRemoved'," "arg0='", machine, "'"); - r = sd_bus_add_match(bus, &slot, match, on_machine_removed, &forward); + r = sd_bus_add_match_async(bus, &slot, match, on_machine_removed, NULL, &forward); if (r < 0) - return log_error_errno(r, "Failed to add machine removal match: %m"); + return log_error_errno(r, "Failed to request machine removal match: %m"); r = sd_bus_call_method( bus, @@ -1643,9 +1643,9 @@ static int shell_machine(int argc, char *argv[], void *userdata) { "member='MachineRemoved'," "arg0='", machine, "'"); - r = sd_bus_add_match(bus, &slot, match, on_machine_removed, &forward); + r = sd_bus_add_match_async(bus, &slot, match, on_machine_removed, NULL, &forward); if (r < 0) - return log_error_errno(r, "Failed to add machine removal match: %m"); + return log_error_errno(r, "Failed to request machine removal match: %m"); r = sd_bus_message_new_method_call( bus, @@ -2087,28 +2087,27 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) { if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); - r = sd_bus_add_match( + r = sd_bus_match_signal_async( bus, &slot_job_removed, - "type='signal'," - "sender='org.freedesktop.import1'," - "interface='org.freedesktop.import1.Manager'," - "member='TransferRemoved'," - "path='/org/freedesktop/import1'", - match_transfer_removed, &path); + "org.freedesktop.import1", + "/org/freedesktop/import1", + "org.freedesktop.import1.Manager", + "TransferRemoved", + match_transfer_removed, NULL, &path); if (r < 0) - return log_error_errno(r, "Failed to install match: %m"); + return log_error_errno(r, "Failed to request match: %m"); - r = sd_bus_add_match( + r = sd_bus_match_signal_async( bus, &slot_log_message, - "type='signal'," - "sender='org.freedesktop.import1'," - "interface='org.freedesktop.import1.Transfer'," - "member='LogMessage'", - match_log_message, &path); + "org.freedesktop.import1", + NULL, + "org.freedesktop.import1.Transfer", + "LogMessage", + match_log_message, NULL, &path); if (r < 0) - return log_error_errno(r, "Failed to install match: %m"); + return log_error_errno(r, "Failed to request match: %m"); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { @@ -3144,7 +3143,7 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) { } int main(int argc, char*argv[]) { - _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -3167,6 +3166,9 @@ int main(int argc, char*argv[]) { r = machinectl_main(argc, argv, bus); finish: + /* make sure we terminate the bus connection first, and then close the + * pager, see issue #3543 for the details. */ + sd_bus_flush_close_unref(bus); pager_close(); polkit_agent_close(); diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 330d6b3d6e..c5e59c4716 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -1078,11 +1078,10 @@ static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_err return -errno; /* This might be a slow operation, run it asynchronously in a background process */ - child = fork(); - if (child < 0) - return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); - - if (child == 0) { + r = safe_fork("(sd-clean)", FORK_RESET_SIGNALS, &child); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); + if (r == 0) { _cleanup_(image_hashmap_freep) Hashmap *images = NULL; bool success = true; Image *image; diff --git a/src/machine/machined.c b/src/machine/machined.c index d481020893..34b2024043 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -37,6 +37,7 @@ #include "machined.h" #include "process-util.h" #include "signal-util.h" +#include "special.h" Manager *manager_new(void) { Manager *m; @@ -112,7 +113,7 @@ static int manager_add_host_machine(Manager *m) { if (!rd) return log_oom(); - unit = strdup("-.slice"); + unit = strdup(SPECIAL_ROOT_SLICE); if (!unit) return log_oom(); @@ -185,7 +186,6 @@ int manager_enumerate_machines(Manager *m) { } static int manager_connect_bus(Manager *m) { - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(m); @@ -215,70 +215,65 @@ static int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to add image enumerator: %m"); - r = sd_bus_add_match(m->bus, - NULL, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Manager'," - "member='JobRemoved'," - "path='/org/freedesktop/systemd1'", - match_job_removed, - m); + r = sd_bus_match_signal_async( + m->bus, + NULL, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "JobRemoved", + match_job_removed, NULL, m); if (r < 0) return log_error_errno(r, "Failed to add match for JobRemoved: %m"); - r = sd_bus_add_match(m->bus, - NULL, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Manager'," - "member='UnitRemoved'," - "path='/org/freedesktop/systemd1'", - match_unit_removed, - m); + r = sd_bus_match_signal_async( + m->bus, + NULL, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "UnitRemoved", + match_unit_removed, NULL, m); if (r < 0) - return log_error_errno(r, "Failed to add match for UnitRemoved: %m"); - - r = sd_bus_add_match(m->bus, - NULL, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.DBus.Properties'," - "member='PropertiesChanged'," - "arg0='org.freedesktop.systemd1.Unit'", - match_properties_changed, - m); + return log_error_errno(r, "Failed to request match for UnitRemoved: %m"); + + r = sd_bus_match_signal_async( + m->bus, + NULL, + "org.freedesktop.systemd1", + NULL, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + match_properties_changed, NULL, m); if (r < 0) - return log_error_errno(r, "Failed to add match for PropertiesChanged: %m"); - - r = sd_bus_add_match(m->bus, - NULL, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Manager'," - "member='Reloading'," - "path='/org/freedesktop/systemd1'", - match_reloading, - m); + return log_error_errno(r, "Failed to request match for PropertiesChanged: %m"); + + r = sd_bus_match_signal_async( + m->bus, + NULL, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Reloading", + match_reloading, NULL, m); if (r < 0) - return log_error_errno(r, "Failed to add match for Reloading: %m"); + return log_error_errno(r, "Failed to request match for Reloading: %m"); - r = sd_bus_call_method( + r = sd_bus_call_method_async( m->bus, + NULL, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Subscribe", - &error, - NULL, NULL); - if (r < 0) { - log_error("Failed to enable subscription: %s", bus_error_message(&error, r)); - return r; - } + NULL, NULL, + NULL); + if (r < 0) + return log_error_errno(r, "Failed to enable subscription: %m"); - r = sd_bus_request_name(m->bus, "org.freedesktop.machine1", 0); + r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.machine1", 0, NULL, NULL); if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); + return log_error_errno(r, "Failed to request name: %m"); r = sd_bus_attach_event(m->bus, m->event, 0); if (r < 0) diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index da3647e7e2..0cd9f07094 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -40,7 +40,9 @@ #include "stat-util.h" #include "strv.h" #include "udev-util.h" +#include "unit-def.h" #include "unit-name.h" +#include "user-util.h" #include "terminal-util.h" enum { @@ -69,6 +71,8 @@ static usec_t arg_timeout_idle = USEC_INFINITY; static bool arg_timeout_idle_set = false; static char **arg_automount_property = NULL; static int arg_bind_device = -1; +static uid_t arg_uid = UID_INVALID; +static gid_t arg_gid = GID_INVALID; static bool arg_fsck = true; static bool arg_aggressive_gc = false; @@ -89,6 +93,7 @@ static void help(void) { " --discover Discover mount device metadata\n" " -t --type=TYPE File system type\n" " -o --options=OPTIONS Mount options\n" + " --owner=USER Add uid= and gid= options for USER\n" " --fsck=no Don't run file system check before mount\n" " --description=TEXT Description for unit\n" " -p --property=NAME=VALUE Set mount unit property\n" @@ -116,6 +121,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_DISCOVER, ARG_MOUNT_TYPE, ARG_MOUNT_OPTIONS, + ARG_OWNER, ARG_FSCK, ARG_DESCRIPTION, ARG_TIMEOUT_IDLE, @@ -139,6 +145,7 @@ static int parse_argv(int argc, char *argv[]) { { "discover", no_argument, NULL, ARG_DISCOVER }, { "type", required_argument, NULL, 't' }, { "options", required_argument, NULL, 'o' }, + { "owner", required_argument, NULL, ARG_OWNER }, { "fsck", required_argument, NULL, ARG_FSCK }, { "description", required_argument, NULL, ARG_DESCRIPTION }, { "property", required_argument, NULL, 'p' }, @@ -220,6 +227,18 @@ static int parse_argv(int argc, char *argv[]) { return log_oom(); break; + case ARG_OWNER: { + const char *user = optarg; + + r = get_user_creds(&user, &arg_uid, &arg_gid, NULL, NULL); + if (r < 0) + return log_error_errno(r, + r == -EBADMSG ? "UID or GID of user %s are invalid." + : "Cannot use \"%s\" as owner: %m", + optarg); + break; + } + case ARG_FSCK: r = parse_boolean(optarg); if (r < 0) @@ -385,7 +404,7 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -static int transient_unit_set_properties(sd_bus_message *m, char **properties) { +static int transient_unit_set_properties(sd_bus_message *m, UnitType t, char **properties) { int r; if (!isempty(arg_description)) { @@ -414,7 +433,7 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) { return r; } - r = bus_append_unit_property_assignment_many(m, properties); + r = bus_append_unit_property_assignment_many(m, t, properties); if (r < 0) return r; @@ -422,11 +441,12 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) { } static int transient_mount_set_properties(sd_bus_message *m) { + _cleanup_free_ char *options = NULL; int r; assert(m); - r = transient_unit_set_properties(m, arg_property); + r = transient_unit_set_properties(m, UNIT_MOUNT, arg_property); if (r < 0) return r; @@ -442,12 +462,25 @@ static int transient_mount_set_properties(sd_bus_message *m) { return r; } - if (arg_mount_options) { - r = sd_bus_message_append(m, "(sv)", "Options", "s", arg_mount_options); + /* Prepend uid=…,gid=… if arg_uid is set */ + if (arg_uid != UID_INVALID) { + r = asprintf(&options, + "uid=" UID_FMT ",gid=" GID_FMT "%s%s", + arg_uid, arg_gid, + arg_mount_options ? "," : "", arg_mount_options); if (r < 0) - return r; + return -ENOMEM; } + if (options || arg_mount_options) { + log_debug("Using mount options: %s", options ?: arg_mount_options); + + r = sd_bus_message_append(m, "(sv)", "Options", "s", options ?: arg_mount_options); + if (r < 0) + return r; + } else + log_debug("Not using any mount options"); + if (arg_fsck) { _cleanup_free_ char *fsck = NULL; @@ -471,7 +504,7 @@ static int transient_automount_set_properties(sd_bus_message *m) { assert(m); - r = transient_unit_set_properties(m, arg_automount_property); + r = transient_unit_set_properties(m, UNIT_AUTOMOUNT, arg_automount_property); if (r < 0) return r; @@ -1530,7 +1563,7 @@ finish: } int main(int argc, char* argv[]) { - _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + sd_bus *bus = NULL; int r; log_parse_environment(); @@ -1604,6 +1637,23 @@ int main(int argc, char* argv[]) { } } + /* The kernel (properly) refuses mounting file systems with unknown uid=,gid= options, + * but not for all filesystem types. Let's try to catch the cases where the option + * would be used if the file system does not support it. It is also possible to + * autodetect the file system, but that's only possible with disk-based file systems + * which incidentally seem to be implemented more carefully and reject unknown options, + * so it's probably OK that we do the check only when the type is specified. + */ + if (arg_mount_type && + !streq(arg_mount_type, "auto") && + arg_uid != UID_INVALID && + !fstype_can_uid_gid(arg_mount_type)) { + log_error("File system type %s is not known to support uid=/gid=, refusing.", + arg_mount_type); + r = -EOPNOTSUPP; + goto finish; + } + switch (arg_action) { case ACTION_MOUNT: @@ -1620,6 +1670,9 @@ int main(int argc, char* argv[]) { } finish: + /* make sure we terminate the bus connection first, and then close the + * pager, see issue #3543 for the details. */ + bus = sd_bus_flush_close_unref(bus); pager_close(); free(arg_mount_what); diff --git a/src/network/meson.build b/src/network/meson.build index f97484eb26..e1ac0f13dc 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -46,6 +46,8 @@ sources = files(''' netdev/geneve.h netdev/vxcan.c netdev/vxcan.h + netdev/wireguard.c + netdev/wireguard.h networkd-address-label.c networkd-address-label.h networkd-address-pool.c @@ -151,7 +153,7 @@ if conf.get('ENABLE_NETWORKD') == 1 [['src/network/test-network.c'], [libnetworkd_core, - libudev_internal, + libudev_static, libsystemd_network, libshared], [threads]], @@ -166,7 +168,7 @@ if conf.get('ENABLE_NETWORKD') == 1 'src/network/test-network-tables.c', test_tables_h], [libnetworkd_core, - libudev_internal, + libudev_static, libudev_core, libsystemd_network, libshared], diff --git a/src/network/netdev/ipvlan.c b/src/network/netdev/ipvlan.c index df9487418b..856f5bd805 100644 --- a/src/network/netdev/ipvlan.c +++ b/src/network/netdev/ipvlan.c @@ -27,11 +27,21 @@ static const char* const ipvlan_mode_table[_NETDEV_IPVLAN_MODE_MAX] = { [NETDEV_IPVLAN_MODE_L2] = "L2", [NETDEV_IPVLAN_MODE_L3] = "L3", + [NETDEV_IPVLAN_MODE_L3S] = "L3S", }; DEFINE_STRING_TABLE_LOOKUP(ipvlan_mode, IPVlanMode); DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_mode, ipvlan_mode, IPVlanMode, "Failed to parse ipvlan mode"); +static const char* const ipvlan_flags_table[_NETDEV_IPVLAN_FLAGS_MAX] = { + [NETDEV_IPVLAN_FLAGS_BRIGDE] = "bridge", + [NETDEV_IPVLAN_FLAGS_PRIVATE] = "private", + [NETDEV_IPVLAN_FLAGS_VEPA] = "vepa", +}; + +DEFINE_STRING_TABLE_LOOKUP(ipvlan_flags, IPVlanFlags); +DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_flags, ipvlan_flags, IPVlanFlags, "Failed to parse ipvlan flags"); + static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) { IPVlan *m; int r; @@ -50,6 +60,12 @@ static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netl return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPVLAN_MODE attribute: %m"); } + if (m->flags != _NETDEV_IPVLAN_FLAGS_INVALID) { + r = sd_netlink_message_append_u16(req, IFLA_IPVLAN_FLAGS, m->flags); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPVLAN_FLAGS attribute: %m"); + } + return 0; } @@ -63,6 +79,7 @@ static void ipvlan_init(NetDev *n) { assert(m); m->mode = _NETDEV_IPVLAN_MODE_INVALID; + m->flags = _NETDEV_IPVLAN_FLAGS_INVALID; } const NetDevVTable ipvlan_vtable = { diff --git a/src/network/netdev/ipvlan.h b/src/network/netdev/ipvlan.h index cb43db4348..b6bc1ac739 100644 --- a/src/network/netdev/ipvlan.h +++ b/src/network/netdev/ipvlan.h @@ -20,20 +20,33 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <linux/if_link.h> + #include "missing.h" #include "netdev/netdev.h" + typedef enum IPVlanMode { NETDEV_IPVLAN_MODE_L2 = IPVLAN_MODE_L2, NETDEV_IPVLAN_MODE_L3 = IPVLAN_MODE_L3, + NETDEV_IPVLAN_MODE_L3S = IPVLAN_MODE_L3S, _NETDEV_IPVLAN_MODE_MAX, _NETDEV_IPVLAN_MODE_INVALID = -1 } IPVlanMode; +typedef enum IPVlanFlags { + NETDEV_IPVLAN_FLAGS_BRIGDE, + NETDEV_IPVLAN_FLAGS_PRIVATE = IPVLAN_F_PRIVATE, + NETDEV_IPVLAN_FLAGS_VEPA = IPVLAN_F_VEPA, + _NETDEV_IPVLAN_FLAGS_MAX, + _NETDEV_IPVLAN_FLAGS_INVALID = -1 +} IPVlanFlags; + typedef struct IPVlan { NetDev meta; IPVlanMode mode; + IPVlanFlags flags; } IPVlan; DEFINE_NETDEV_CAST(IPVLAN, IPVlan); @@ -42,4 +55,8 @@ extern const NetDevVTable ipvlan_vtable; const char *ipvlan_mode_to_string(IPVlanMode d) _const_; IPVlanMode ipvlan_mode_from_string(const char *d) _pure_; +const char *ipvlan_flags_to_string(IPVlanFlags d) _const_; +IPVlanFlags ipvlan_flags_from_string(const char *d) _pure_; + int config_parse_ipvlan_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_ipvlan_flags(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index 628e6648b7..ba6268fa66 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -18,6 +18,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") #include "netdev/vrf.h" #include "netdev/netdev.h" #include "netdev/vxcan.h" +#include "netdev/wireguard.h" #include "vlan-util.h" %} struct ConfigPerfItem; @@ -31,114 +32,125 @@ struct ConfigPerfItem; %struct-type %includes %% -Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host) -Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt) -Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel) -Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch) -NetDev.Description, config_parse_string, 0, offsetof(NetDev, description) -NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname) -NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind) -NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu) -NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac) -VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id) -VLAN.GVRP, config_parse_tristate, 0, offsetof(VLan, gvrp) -VLAN.MVRP, config_parse_tristate, 0, offsetof(VLan, mvrp) -VLAN.LooseBinding, config_parse_tristate, 0, offsetof(VLan, loose_binding) -VLAN.ReorderHeader, config_parse_tristate, 0, offsetof(VLan, reorder_hdr) -MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) -MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) -IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode) -Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local) -Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote) -Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos) -Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl) -Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key) -Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey) -Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey) -Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc) -Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode) -Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, offsetof(Tunnel, ipv6_flowlabel) -Tunnel.CopyDSCP, config_parse_bool, 0, offsetof(Tunnel, copy_dscp) -Tunnel.EncapsulationLimit, config_parse_encap_limit, 0, offsetof(Tunnel, encap_limit) -Tunnel.Independent, config_parse_bool, 0, offsetof(Tunnel, independent) -Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer) -Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer) -VXCAN.Peer, config_parse_ifname, 0, offsetof(VxCan, ifname_peer) -VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id) -VXLAN.Group, config_parse_vxlan_address, 0, offsetof(VxLan, remote) -VXLAN.Local, config_parse_vxlan_address, 0, offsetof(VxLan, local) -VXLAN.Remote, config_parse_vxlan_address, 0, offsetof(VxLan, remote) -VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos) -VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl) -VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning) -VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy) -VXLAN.ReduceARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy) -VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss) -VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss) -VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit) -VXLAN.UDPCheckSum, config_parse_bool, 0, offsetof(VxLan, udpcsum) -VXLAN.UDPChecksum, config_parse_bool, 0, offsetof(VxLan, udpcsum) -VXLAN.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx) -VXLAN.UDP6ZeroChecksumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx) -VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx) -VXLAN.UDP6ZeroChecksumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx) -VXLAN.RemoteChecksumTx, config_parse_bool, 0, offsetof(VxLan, remote_csum_tx) -VXLAN.RemoteChecksumRx, config_parse_bool, 0, offsetof(VxLan, remote_csum_rx) -VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing) -VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy) -VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb) -VXLAN.PortRange, config_parse_port_range, 0, 0 -VXLAN.DestinationPort, config_parse_ip_port, 0, offsetof(VxLan, dest_port) -VXLAN.FlowLabel, config_parse_flow_label, 0, 0 -GENEVE.Id, config_parse_geneve_vni, 0, offsetof(Geneve, id) -GENEVE.Remote, config_parse_geneve_address, 0, offsetof(Geneve, remote) -GENEVE.TOS, config_parse_uint8, 0, offsetof(Geneve, tos) -GENEVE.TTL, config_parse_uint8, 0, offsetof(Geneve, ttl) -GENEVE.UDPChecksum, config_parse_bool, 0, offsetof(Geneve, udpcsum) -GENEVE.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumrx) -GENEVE.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumtx) -GENEVE.DestinationPort, config_parse_ip_port, 0, offsetof(Geneve, dest_port) -GENEVE.FlowLabel, config_parse_geneve_flow_label, 0, 0 -Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue) -Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue) -Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info) -Tun.User, config_parse_string, 0, offsetof(TunTap, user_name) -Tun.Group, config_parse_string, 0, offsetof(TunTap, group_name) -Tap.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue) -Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue) -Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info) -Tap.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr) -Tap.User, config_parse_string, 0, offsetof(TunTap, user_name) -Tap.Group, config_parse_string, 0, offsetof(TunTap, group_name) -Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode) -Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy) -Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate) -Bond.AdSelect, config_parse_bond_ad_select, 0, offsetof(Bond, ad_select) -Bond.FailOverMACPolicy, config_parse_bond_fail_over_mac, 0, offsetof(Bond, fail_over_mac) -Bond.ARPIPTargets, config_parse_arp_ip_target_address, 0, 0 -Bond.ARPValidate, config_parse_bond_arp_validate, 0, offsetof(Bond, arp_validate) -Bond.ARPAllTargets, config_parse_bond_arp_all_targets, 0, offsetof(Bond, arp_all_targets) -Bond.PrimaryReselectPolicy, config_parse_bond_primary_reselect, 0, offsetof(Bond, primary_reselect) -Bond.ResendIGMP, config_parse_unsigned, 0, offsetof(Bond, resend_igmp) -Bond.PacketsPerSlave, config_parse_unsigned, 0, offsetof(Bond, packets_per_slave) -Bond.GratuitousARP, config_parse_unsigned, 0, offsetof(Bond, num_grat_arp) -Bond.AllSlavesActive, config_parse_unsigned, 0, offsetof(Bond, all_slaves_active) -Bond.MinLinks, config_parse_unsigned, 0, offsetof(Bond, min_links) -Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon) -Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay) -Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay) -Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval) -Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval) -Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time) -Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age) -Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time) -Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay) -Bridge.Priority, config_parse_uint16, 0, offsetof(Bridge, priority) -Bridge.GroupForwardMask, config_parse_uint16, 0, offsetof(Bridge, group_fwd_mask) -Bridge.DefaultPVID, config_parse_default_port_vlanid, 0, offsetof(Bridge, default_pvid) -Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier) -Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping) -Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering) -Bridge.STP, config_parse_tristate, 0, offsetof(Bridge, stp) -VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table) /* deprecated */ -VRF.Table, config_parse_route_table, 0, offsetof(Vrf, table) +Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host) +Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt) +Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel_cmdline) +Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(NetDev, match_kernel_version) +Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch) +NetDev.Description, config_parse_string, 0, offsetof(NetDev, description) +NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname) +NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind) +NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu) +NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac) +VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id) +VLAN.GVRP, config_parse_tristate, 0, offsetof(VLan, gvrp) +VLAN.MVRP, config_parse_tristate, 0, offsetof(VLan, mvrp) +VLAN.LooseBinding, config_parse_tristate, 0, offsetof(VLan, loose_binding) +VLAN.ReorderHeader, config_parse_tristate, 0, offsetof(VLan, reorder_hdr) +MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) +MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) +IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode) +IPVLAN.Flags, config_parse_ipvlan_flags, 0, offsetof(IPVlan, flags) +Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local) +Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote) +Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos) +Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl) +Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key) +Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey) +Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey) +Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc) +Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode) +Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, offsetof(Tunnel, ipv6_flowlabel) +Tunnel.CopyDSCP, config_parse_bool, 0, offsetof(Tunnel, copy_dscp) +Tunnel.EncapsulationLimit, config_parse_encap_limit, 0, offsetof(Tunnel, encap_limit) +Tunnel.Independent, config_parse_bool, 0, offsetof(Tunnel, independent) +Tunnel.AllowLocalRemote, config_parse_tristate, 0, offsetof(Tunnel, allow_localremote) +Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer) +Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer) +VXCAN.Peer, config_parse_ifname, 0, offsetof(VxCan, ifname_peer) +VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id) +VXLAN.Group, config_parse_vxlan_address, 0, offsetof(VxLan, remote) +VXLAN.Local, config_parse_vxlan_address, 0, offsetof(VxLan, local) +VXLAN.Remote, config_parse_vxlan_address, 0, offsetof(VxLan, remote) +VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos) +VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl) +VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning) +VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy) +VXLAN.ReduceARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy) +VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss) +VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss) +VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit) +VXLAN.UDPCheckSum, config_parse_bool, 0, offsetof(VxLan, udpcsum) +VXLAN.UDPChecksum, config_parse_bool, 0, offsetof(VxLan, udpcsum) +VXLAN.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx) +VXLAN.UDP6ZeroChecksumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx) +VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx) +VXLAN.UDP6ZeroChecksumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx) +VXLAN.RemoteChecksumTx, config_parse_bool, 0, offsetof(VxLan, remote_csum_tx) +VXLAN.RemoteChecksumRx, config_parse_bool, 0, offsetof(VxLan, remote_csum_rx) +VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing) +VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy) +VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb) +VXLAN.PortRange, config_parse_port_range, 0, 0 +VXLAN.DestinationPort, config_parse_ip_port, 0, offsetof(VxLan, dest_port) +VXLAN.FlowLabel, config_parse_flow_label, 0, 0 +GENEVE.Id, config_parse_geneve_vni, 0, offsetof(Geneve, id) +GENEVE.Remote, config_parse_geneve_address, 0, offsetof(Geneve, remote) +GENEVE.TOS, config_parse_uint8, 0, offsetof(Geneve, tos) +GENEVE.TTL, config_parse_uint8, 0, offsetof(Geneve, ttl) +GENEVE.UDPChecksum, config_parse_bool, 0, offsetof(Geneve, udpcsum) +GENEVE.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumrx) +GENEVE.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumtx) +GENEVE.DestinationPort, config_parse_ip_port, 0, offsetof(Geneve, dest_port) +GENEVE.FlowLabel, config_parse_geneve_flow_label, 0, 0 +Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue) +Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue) +Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info) +Tun.User, config_parse_string, 0, offsetof(TunTap, user_name) +Tun.Group, config_parse_string, 0, offsetof(TunTap, group_name) +Tap.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue) +Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue) +Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info) +Tap.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr) +Tap.User, config_parse_string, 0, offsetof(TunTap, user_name) +Tap.Group, config_parse_string, 0, offsetof(TunTap, group_name) +Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode) +Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy) +Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate) +Bond.AdSelect, config_parse_bond_ad_select, 0, offsetof(Bond, ad_select) +Bond.FailOverMACPolicy, config_parse_bond_fail_over_mac, 0, offsetof(Bond, fail_over_mac) +Bond.ARPIPTargets, config_parse_arp_ip_target_address, 0, 0 +Bond.ARPValidate, config_parse_bond_arp_validate, 0, offsetof(Bond, arp_validate) +Bond.ARPAllTargets, config_parse_bond_arp_all_targets, 0, offsetof(Bond, arp_all_targets) +Bond.PrimaryReselectPolicy, config_parse_bond_primary_reselect, 0, offsetof(Bond, primary_reselect) +Bond.ResendIGMP, config_parse_unsigned, 0, offsetof(Bond, resend_igmp) +Bond.PacketsPerSlave, config_parse_unsigned, 0, offsetof(Bond, packets_per_slave) +Bond.GratuitousARP, config_parse_unsigned, 0, offsetof(Bond, num_grat_arp) +Bond.AllSlavesActive, config_parse_unsigned, 0, offsetof(Bond, all_slaves_active) +Bond.MinLinks, config_parse_unsigned, 0, offsetof(Bond, min_links) +Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon) +Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay) +Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay) +Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval) +Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval) +Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time) +Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age) +Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time) +Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay) +Bridge.Priority, config_parse_uint16, 0, offsetof(Bridge, priority) +Bridge.GroupForwardMask, config_parse_uint16, 0, offsetof(Bridge, group_fwd_mask) +Bridge.DefaultPVID, config_parse_default_port_vlanid, 0, offsetof(Bridge, default_pvid) +Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier) +Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping) +Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering) +Bridge.STP, config_parse_tristate, 0, offsetof(Bridge, stp) +VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table) /* deprecated */ +VRF.Table, config_parse_route_table, 0, offsetof(Vrf, table) +WireGuard.FwMark, config_parse_unsigned, 0, offsetof(Wireguard, fwmark) +WireGuard.ListenPort, config_parse_wireguard_listen_port, 0, offsetof(Wireguard, port) +WireGuard.PrivateKey, config_parse_wireguard_private_key, 0, 0 +WireGuardPeer.AllowedIPs, config_parse_wireguard_allowed_ips, 0, 0 +WireGuardPeer.Endpoint, config_parse_wireguard_endpoint, 0, 0 +WireGuardPeer.PublicKey, config_parse_wireguard_public_key, 0, 0 +WireGuardPeer.PresharedKey, config_parse_wireguard_preshared_key, 0, 0 +WireGuardPeer.PersistentKeepalive, config_parse_wireguard_keepalive, 0, 0 diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 5530760e19..93648e1be0 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -49,6 +49,7 @@ #include "netdev/vrf.h" #include "netdev/vcan.h" #include "netdev/vxcan.h" +#include "netdev/wireguard.h" const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { [NETDEV_KIND_BRIDGE] = &bridge_vtable, @@ -75,6 +76,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { [NETDEV_KIND_VCAN] = &vcan_vtable, [NETDEV_KIND_GENEVE] = &geneve_vtable, [NETDEV_KIND_VXCAN] = &vxcan_vtable, + [NETDEV_KIND_WIREGUARD] = &wireguard_vtable, }; static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { @@ -102,6 +104,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_VCAN] = "vcan", [NETDEV_KIND_GENEVE] = "geneve", [NETDEV_KIND_VXCAN] = "vxcan", + [NETDEV_KIND_WIREGUARD] = "wireguard", }; DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); @@ -111,10 +114,10 @@ static void netdev_cancel_callbacks(NetDev *netdev) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; netdev_join_callback *callback; - if (!netdev) + if (!netdev || !netdev->manager) return; - rtnl_message_new_synthetic_error(-ENODEV, 0, &m); + rtnl_message_new_synthetic_error(netdev->manager->rtnl, -ENODEV, 0, &m); while ((callback = netdev->callbacks)) { if (m) { @@ -138,7 +141,7 @@ static void netdev_free(NetDev *netdev) { netdev_cancel_callbacks(netdev); - if (netdev->ifname) + if (netdev->ifname && netdev->manager) hashmap_remove(netdev->manager->netdevs, netdev->ifname); free(netdev->filename); @@ -149,10 +152,19 @@ static void netdev_free(NetDev *netdev) { condition_free_list(netdev->match_host); condition_free_list(netdev->match_virt); - condition_free_list(netdev->match_kernel); + condition_free_list(netdev->match_kernel_cmdline); + condition_free_list(netdev->match_kernel_version); condition_free_list(netdev->match_arch); - if (NETDEV_VTABLE(netdev) && + /* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that + * because we parse .netdev files twice: once to determine the kind (with a short, minimal NetDev structure + * allocation, with no room for per-kind fields), and once to read the kind's properties (with a full, + * comprehensive NetDev structure allocation with enough space for whatever the specific kind needs). Now, in + * the first case we shouldn't try to destruct the per-kind NetDev fields on destruction, in the second case we + * should. We use the state field to discern the two cases: it's _NETDEV_STATE_INVALID on the first "raw" + * call. */ + if (netdev->state != _NETDEV_STATE_INVALID && + NETDEV_VTABLE(netdev) && NETDEV_VTABLE(netdev)->done) NETDEV_VTABLE(netdev)->done(netdev); @@ -321,7 +333,7 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t call } else if (IN_SET(netdev->state, NETDEV_STATE_LINGER, NETDEV_STATE_FAILED)) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - r = rtnl_message_new_synthetic_error(-ENODEV, 0, &m); + r = rtnl_message_new_synthetic_error(netdev->manager->rtnl, -ENODEV, 0, &m); if (r >= 0) callback(netdev->manager->rtnl, m, link); } else { @@ -601,8 +613,7 @@ int netdev_join(NetDev *netdev, Link *link, sd_netlink_message_handler_t callbac } static int netdev_load_one(Manager *manager, const char *filename) { - _cleanup_netdev_unref_ NetDev *netdev = NULL; - _cleanup_free_ NetDev *netdev_raw = NULL; + _cleanup_netdev_unref_ NetDev *netdev_raw = NULL, *netdev = NULL; _cleanup_fclose_ FILE *file = NULL; const char *dropin_dirname; bool independent = false; @@ -615,8 +626,8 @@ static int netdev_load_one(Manager *manager, const char *filename) { if (!file) { if (errno == ENOENT) return 0; - else - return -errno; + + return -errno; } if (null_or_empty_fd(fileno(file))) { @@ -628,24 +639,23 @@ static int netdev_load_one(Manager *manager, const char *filename) { if (!netdev_raw) return log_oom(); + netdev_raw->n_ref = 1; netdev_raw->kind = _NETDEV_KIND_INVALID; - dropin_dirname = strjoina(basename(filename), ".d"); + netdev_raw->state = _NETDEV_STATE_INVALID; /* an invalid state means done() of the implementation won't be called on destruction */ + dropin_dirname = strjoina(basename(filename), ".d"); r = config_parse_many(filename, network_dirs, dropin_dirname, "Match\0NetDev\0", config_item_perf_lookup, network_netdev_gperf_lookup, - CONFIG_PARSE_WARN, netdev_raw); + CONFIG_PARSE_WARN|CONFIG_PARSE_RELAXED, netdev_raw); if (r < 0) return r; - r = fseek(file, 0, SEEK_SET); - if (r < 0) - return -errno; - /* skip out early if configuration does not match the environment */ if (net_match_config(NULL, NULL, NULL, NULL, NULL, netdev_raw->match_host, netdev_raw->match_virt, - netdev_raw->match_kernel, netdev_raw->match_arch, + netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version, + netdev_raw->match_arch, NULL, NULL, NULL, NULL, NULL, NULL) <= 0) return 0; @@ -659,15 +669,18 @@ static int netdev_load_one(Manager *manager, const char *filename) { return 0; } + r = fseek(file, 0, SEEK_SET); + if (r < 0) + return -errno; + netdev = malloc0(NETDEV_VTABLE(netdev_raw)->object_size); if (!netdev) return log_oom(); netdev->n_ref = 1; netdev->manager = manager; - netdev->state = _NETDEV_STATE_INVALID; netdev->kind = netdev_raw->kind; - netdev->ifname = netdev_raw->ifname; + netdev->state = NETDEV_STATE_LOADING; /* we initialize the state here for the first time, so that done() will be called on destruction */ if (NETDEV_VTABLE(netdev)->init) NETDEV_VTABLE(netdev)->init(netdev); diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index ec65251464..51b3ea7a8f 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -60,11 +60,13 @@ typedef enum NetDevKind { NETDEV_KIND_VCAN, NETDEV_KIND_GENEVE, NETDEV_KIND_VXCAN, + NETDEV_KIND_WIREGUARD, _NETDEV_KIND_MAX, _NETDEV_KIND_INVALID = -1 } NetDevKind; typedef enum NetDevState { + NETDEV_STATE_LOADING, NETDEV_STATE_FAILED, NETDEV_STATE_CREATING, NETDEV_STATE_READY, @@ -93,7 +95,8 @@ typedef struct NetDev { Condition *match_host; Condition *match_virt; - Condition *match_kernel; + Condition *match_kernel_cmdline; + Condition *match_kernel_version; Condition *match_arch; NetDevState state; @@ -143,12 +146,14 @@ typedef struct NetDevVTable { extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX]; -#define NETDEV_VTABLE(n) netdev_vtable[(n)->kind] +#define NETDEV_VTABLE(n) ((n)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(n)->kind] : NULL) /* For casting a netdev into the various netdev kinds */ #define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase) \ static inline MixedCase* UPPERCASE(NetDev *n) { \ - if (_unlikely_(!n || n->kind != NETDEV_KIND_##UPPERCASE)) \ + if (_unlikely_(!n || \ + n->kind != NETDEV_KIND_##UPPERCASE) || \ + n->state == _NETDEV_STATE_INVALID) \ return NULL; \ \ return (MixedCase*) n; \ diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c index 8d6d54d567..a6a3c701f9 100644 --- a/src/network/netdev/tunnel.c +++ b/src/network/netdev/tunnel.c @@ -37,6 +37,7 @@ #define DEFAULT_TNL_HOP_LIMIT 64 #define IP6_FLOWINFO_FLOWLABEL htobe32(0x000FFFFF) +#define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0x40 static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = { [NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6", @@ -60,7 +61,6 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_netlin r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m"); - } r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in); @@ -95,7 +95,6 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m"); - } r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in); @@ -336,6 +335,9 @@ static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netl if (t->copy_dscp) t->flags |= IP6_TNL_F_RCV_DSCP_COPY; + if (t->allow_localremote != -1) + SET_FLAG(t->flags, IP6_TNL_F_ALLOW_LOCAL_REMOTE, t->allow_localremote); + if (t->encap_limit != IPV6_DEFAULT_TNL_ENCAP_LIMIT) { r = sd_netlink_message_append_u8(m, IFLA_IPTUN_ENCAP_LIMIT, t->encap_limit); if (r < 0) @@ -682,6 +684,7 @@ static void ip6tnl_init(NetDev *n) { t->encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT; t->ip6tnl_mode = _NETDEV_IP6_TNL_MODE_INVALID; t->ipv6_flowlabel = _NETDEV_IPV6_FLOWLABEL_INVALID; + t->allow_localremote = -1; } const NetDevVTable ipip_vtable = { diff --git a/src/network/netdev/tunnel.h b/src/network/netdev/tunnel.h index 67f8fe35c7..7ffafe9e98 100644 --- a/src/network/netdev/tunnel.h +++ b/src/network/netdev/tunnel.h @@ -45,6 +45,7 @@ typedef struct Tunnel { int family; int ipv6_flowlabel; + int allow_localremote; unsigned ttl; unsigned tos; diff --git a/src/network/netdev/tuntap.c b/src/network/netdev/tuntap.c index 4597a7feeb..4fc9b610af 100644 --- a/src/network/netdev/tuntap.c +++ b/src/network/netdev/tuntap.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <fcntl.h> #include <linux/if_tun.h> #include <net/if.h> diff --git a/src/network/netdev/veth.c b/src/network/netdev/veth.c index 9220b3200f..2a2f50e345 100644 --- a/src/network/netdev/veth.c +++ b/src/network/netdev/veth.c @@ -18,8 +18,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <net/if.h> +#include <errno.h> #include <linux/veth.h> +#include <net/if.h> #include "sd-netlink.h" diff --git a/src/network/netdev/vlan.c b/src/network/netdev/vlan.c index 3a0100d7e6..e7c0e7602a 100644 --- a/src/network/netdev/vlan.c +++ b/src/network/netdev/vlan.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <linux/if_vlan.h> #include <net/if.h> diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c new file mode 100644 index 0000000000..f1f4bab475 --- /dev/null +++ b/src/network/netdev/wireguard.c @@ -0,0 +1,721 @@ +/*** + This file is part of systemd. + + Copyright 2016-2017 Jörg Thalheim <joerg@thalheim.io> + Copyright 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/ioctl.h> +#include <net/if.h> + +#include "alloc-util.h" +#include "parse-util.h" +#include "fd-util.h" +#include "strv.h" +#include "hexdecoct.h" +#include "string-util.h" +#include "wireguard.h" +#include "networkd-link.h" +#include "networkd-util.h" +#include "networkd-manager.h" +#include "wireguard-netlink.h" + +static void resolve_endpoints(NetDev *netdev); + +static WireguardPeer *wireguard_peer_new(Wireguard *w, unsigned section) { + WireguardPeer *peer; + + assert(w); + + if (w->last_peer_section == section && w->peers) + return w->peers; + + peer = new0(WireguardPeer, 1); + if (!peer) + return NULL; + peer->flags = WGPEER_F_REPLACE_ALLOWEDIPS; + + LIST_PREPEND(peers, w->peers, peer); + w->last_peer_section = section; + + return peer; +} + +static int set_wireguard_interface(NetDev *netdev) { + int r; + unsigned int i, j; + WireguardPeer *peer, *peer_start; + WireguardIPmask *mask, *mask_start = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; + Wireguard *w; + uint32_t serial; + + assert(netdev); + w = WIREGUARD(netdev); + assert(w); + + peer_start = w->peers; + + do { + message = sd_netlink_message_unref(message); + + r = sd_genl_message_new(netdev->manager->genl, SD_GENL_WIREGUARD, WG_CMD_SET_DEVICE, &message); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Failed to allocate generic netlink message: %m"); + + r = sd_netlink_message_append_string(message, WGDEVICE_A_IFNAME, netdev->ifname); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append wireguard interface name: %m"); + + if (peer_start == w->peers) { + r = sd_netlink_message_append_data(message, WGDEVICE_A_PRIVATE_KEY, &w->private_key, WG_KEY_LEN); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append wireguard private key: %m"); + + r = sd_netlink_message_append_u16(message, WGDEVICE_A_LISTEN_PORT, w->port); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append wireguard port: %m"); + + r = sd_netlink_message_append_u32(message, WGDEVICE_A_FWMARK, w->fwmark); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append wireguard fwmark: %m"); + + r = sd_netlink_message_append_u32(message, WGDEVICE_A_FLAGS, w->flags); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append wireguard flags: %m"); + } + + r = sd_netlink_message_open_container(message, WGDEVICE_A_PEERS); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append wireguard peer attributes: %m"); + + i = 0; + + LIST_FOREACH(peers, peer, peer_start) { + r = sd_netlink_message_open_array(message, ++i); + if (r < 0) + break; + + r = sd_netlink_message_append_data(message, WGPEER_A_PUBLIC_KEY, &peer->public_key, sizeof(peer->public_key)); + if (r < 0) + break; + + if (!mask_start) { + r = sd_netlink_message_append_data(message, WGPEER_A_PRESHARED_KEY, &peer->preshared_key, WG_KEY_LEN); + if (r < 0) + break; + + r = sd_netlink_message_append_u32(message, WGPEER_A_FLAGS, peer->flags); + if (r < 0) + break; + + r = sd_netlink_message_append_u32(message, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, peer->persistent_keepalive_interval); + if (r < 0) + break; + + if (peer->endpoint.sa.sa_family == AF_INET) { + r = sd_netlink_message_append_data(message, WGPEER_A_ENDPOINT, &peer->endpoint.in, sizeof(peer->endpoint.in)); + if (r < 0) + break; + } else if (peer->endpoint.sa.sa_family == AF_INET6) { + r = sd_netlink_message_append_data(message, WGPEER_A_ENDPOINT, &peer->endpoint.in6, sizeof(peer->endpoint.in6)); + if (r < 0) + break; + } + + mask_start = peer->ipmasks; + } + + r = sd_netlink_message_open_container(message, WGPEER_A_ALLOWEDIPS); + if (r < 0) { + mask_start = NULL; + break; + } + j = 0; + LIST_FOREACH(ipmasks, mask, mask_start) { + r = sd_netlink_message_open_array(message, ++j); + if (r < 0) + break; + + r = sd_netlink_message_append_u16(message, WGALLOWEDIP_A_FAMILY, mask->family); + if (r < 0) + break; + + if (mask->family == AF_INET) { + r = sd_netlink_message_append_in_addr(message, WGALLOWEDIP_A_IPADDR, &mask->ip.in); + if (r < 0) + break; + } else if (mask->family == AF_INET6) { + r = sd_netlink_message_append_in6_addr(message, WGALLOWEDIP_A_IPADDR, &mask->ip.in6); + if (r < 0) + break; + } + + r = sd_netlink_message_append_u8(message, WGALLOWEDIP_A_CIDR_MASK, mask->cidr); + if (r < 0) + break; + + r = sd_netlink_message_close_container(message); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not add wireguard allowed ip: %m"); + } + mask_start = mask; + if (mask_start) { + r = sd_netlink_message_cancel_array(message); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not cancel wireguard allowed ip message attribute: %m"); + } + r = sd_netlink_message_close_container(message); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not add wireguard allowed ip: %m"); + + r = sd_netlink_message_close_container(message); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not add wireguard peer: %m"); + } + + peer_start = peer; + if (peer_start && !mask_start) { + r = sd_netlink_message_cancel_array(message); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not cancel wireguard peers: %m"); + } + + r = sd_netlink_message_close_container(message); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not close wireguard container: %m"); + + r = sd_netlink_send(netdev->manager->genl, message, &serial); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not set wireguard device: %m"); + + } while (peer || mask_start); + + return 0; +} + +static WireguardEndpoint* wireguard_endpoint_free(WireguardEndpoint *e) { + if (!e) + return NULL; + netdev_unref(e->netdev); + e->host = mfree(e->host); + e->port = mfree(e->port); + return mfree(e); +} + +DEFINE_TRIVIAL_CLEANUP_FUNC(WireguardEndpoint*, wireguard_endpoint_free); + +static int on_resolve_retry(sd_event_source *s, usec_t usec, void *userdata) { + NetDev *netdev = userdata; + Wireguard *w; + + assert(netdev); + w = WIREGUARD(netdev); + assert(w); + + w->resolve_retry_event_source = sd_event_source_unref(w->resolve_retry_event_source); + + w->unresolved_endpoints = w->failed_endpoints; + w->failed_endpoints = NULL; + + resolve_endpoints(netdev); + + return 0; +} + +/* + * Given the number of retries this function will return will an exponential + * increasing time in milliseconds to wait starting at 200ms and capped at 25 seconds. + */ +static int exponential_backoff_milliseconds(unsigned n_retries) { + return (2 << MAX(n_retries, 7U)) * 100 * USEC_PER_MSEC; +} + +static int wireguard_resolve_handler(sd_resolve_query *q, + int ret, + const struct addrinfo *ai, + void *userdata) { + NetDev *netdev; + Wireguard *w; + _cleanup_(wireguard_endpoint_freep) WireguardEndpoint *e; + int r; + + assert(userdata); + e = userdata; + netdev = e->netdev; + + assert(netdev); + w = WIREGUARD(netdev); + assert(w); + + w->resolve_query = sd_resolve_query_unref(w->resolve_query); + + if (ret != 0) { + log_netdev_error(netdev, "Failed to resolve host '%s:%s': %s", e->host, e->port, gai_strerror(ret)); + LIST_PREPEND(endpoints, w->failed_endpoints, e); + e = NULL; + } else if ((ai->ai_family == AF_INET && ai->ai_addrlen == sizeof(struct sockaddr_in)) || + (ai->ai_family == AF_INET6 && ai->ai_addrlen == sizeof(struct sockaddr_in6))) + memcpy(&e->peer->endpoint, ai->ai_addr, ai->ai_addrlen); + else + log_netdev_error(netdev, "Neither IPv4 nor IPv6 address found for peer endpoint: %s:%s", e->host, e->port); + + if (w->unresolved_endpoints) { + resolve_endpoints(netdev); + return 0; + } + + set_wireguard_interface(netdev); + if (w->failed_endpoints) { + w->n_retries++; + r = sd_event_add_time(netdev->manager->event, + &w->resolve_retry_event_source, + CLOCK_MONOTONIC, + now(CLOCK_MONOTONIC) + exponential_backoff_milliseconds(w->n_retries), + 0, + on_resolve_retry, + netdev); + if (r < 0) + log_netdev_warning_errno(netdev, r, "Could not arm resolve retry handler: %m"); + } + + return 0; +} + +static void resolve_endpoints(NetDev *netdev) { + int r = 0; + Wireguard *w; + WireguardEndpoint *endpoint; + static const struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_DGRAM, + .ai_protocol = IPPROTO_UDP + }; + + assert(netdev); + w = WIREGUARD(netdev); + assert(w); + + LIST_FOREACH(endpoints, endpoint, w->unresolved_endpoints) { + r = sd_resolve_getaddrinfo(netdev->manager->resolve, + &w->resolve_query, + endpoint->host, + endpoint->port, + &hints, + wireguard_resolve_handler, + endpoint); + + if (r == -ENOBUFS) + break; + + LIST_REMOVE(endpoints, w->unresolved_endpoints, endpoint); + + if (r < 0) + log_netdev_error_errno(netdev, r, "Failed create resolver: %m"); + } +} + + +static int netdev_wireguard_post_create(NetDev *netdev, Link *link, sd_netlink_message *m) { + Wireguard *w; + + assert(netdev); + w = WIREGUARD(netdev); + assert(w); + + set_wireguard_interface(netdev); + resolve_endpoints(netdev); + return 0; +} + +int config_parse_wireguard_listen_port(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + uint16_t *s = data; + uint16_t port = 0; + int r; + + assert(rvalue); + assert(data); + + if (!streq(rvalue, "auto")) { + r = parse_ip_port(rvalue, &port); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, r, "Invalid port specification, ignoring assignment: %s", rvalue); + } + + *s = port; + + return 0; +} + +static int parse_wireguard_key(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + _cleanup_free_ void *key = NULL; + size_t len; + int r; + + assert(filename); + assert(rvalue); + assert(userdata); + + r = unbase64mem(rvalue, strlen(rvalue), &key, &len); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Could not parse wireguard key \"%s\", ignoring assignment: %m", rvalue); + return 0; + } + if (len != WG_KEY_LEN) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Wireguard key is too short, ignoring assignment: %s", rvalue); + return 0; + } + + memcpy(userdata, key, WG_KEY_LEN); + return true; +} + +int config_parse_wireguard_private_key(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + Wireguard *w; + + assert(data); + + w = WIREGUARD(data); + + assert(w); + + return parse_wireguard_key(unit, + filename, + line, + section, + section_line, + lvalue, + ltype, + rvalue, + data, + &w->private_key); + +} + +int config_parse_wireguard_preshared_key(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + Wireguard *w; + WireguardPeer *peer; + + assert(data); + + w = WIREGUARD(data); + + assert(w); + + peer = wireguard_peer_new(w, section_line); + if (!peer) + return log_oom(); + + return parse_wireguard_key(unit, + filename, + line, + section, + section_line, + lvalue, + ltype, + rvalue, + data, + peer->preshared_key); +} + + +int config_parse_wireguard_public_key(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + Wireguard *w; + WireguardPeer *peer; + + assert(data); + + w = WIREGUARD(data); + + assert(w); + + peer = wireguard_peer_new(w, section_line); + if (!peer) + return log_oom(); + + return parse_wireguard_key(unit, + filename, + line, + section, + section_line, + lvalue, + ltype, + rvalue, + data, + peer->public_key); +} + +int config_parse_wireguard_allowed_ips(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + union in_addr_union addr; + unsigned char prefixlen; + int r, family; + Wireguard *w; + WireguardPeer *peer; + WireguardIPmask *ipmask; + + assert(rvalue); + assert(data); + + w = WIREGUARD(data); + + peer = wireguard_peer_new(w, section_line); + if (!peer) + return log_oom(); + + for (;;) { + _cleanup_free_ char *word = NULL; + + r = extract_first_word(&rvalue, &word, "," WHITESPACE, 0); + if (r == 0) + break; + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to split allowed ips \"%s\" option: %m", rvalue); + break; + } + + r = in_addr_prefix_from_string_auto(word, &family, &addr, &prefixlen); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Network address is invalid, ignoring assignment: %s", word); + return 0; + } + + ipmask = new0(WireguardIPmask, 1); + if (!ipmask) + return log_oom(); + ipmask->family = family; + ipmask->ip.in6 = addr.in6; + ipmask->cidr = prefixlen; + + LIST_PREPEND(ipmasks, peer->ipmasks, ipmask); + } + + return 0; +} + +int config_parse_wireguard_endpoint(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + Wireguard *w; + WireguardPeer *peer; + size_t len; + const char *begin, *end = NULL; + _cleanup_free_ char *host = NULL, *port = NULL; + _cleanup_(wireguard_endpoint_freep) WireguardEndpoint *endpoint = NULL; + + assert(data); + assert(rvalue); + + w = WIREGUARD(data); + + assert(w); + + peer = wireguard_peer_new(w, section_line); + if (!peer) + return log_oom(); + + endpoint = new0(WireguardEndpoint, 1); + if (!endpoint) + return log_oom(); + + if (rvalue[0] == '[') { + begin = &rvalue[1]; + end = strchr(rvalue, ']'); + if (!end) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to find matching brace of endpoint, ignoring assignment: %s", rvalue); + return 0; + } + len = end - begin; + ++end; + if (*end != ':' || !*(end + 1)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to find port of endpoint: %s", rvalue); + return 0; + } + ++end; + } else { + begin = rvalue; + end = strrchr(rvalue, ':'); + if (!end || !*(end + 1)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to find port of endpoint: %s", rvalue); + return 0; + } + len = end - begin; + ++end; + } + + host = strndup(begin, len); + if (!host) + return log_oom(); + + port = strdup(end); + if (!port) + return log_oom(); + + endpoint->peer = peer; + endpoint->host = host; + endpoint->port = port; + endpoint->netdev = netdev_ref(data); + LIST_PREPEND(endpoints, w->unresolved_endpoints, endpoint); + + peer = NULL; + host = NULL; + port = NULL; + endpoint = NULL; + + return 0; +} + +int config_parse_wireguard_keepalive(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + int r; + uint16_t keepalive = 0; + Wireguard *w; + WireguardPeer *peer; + + assert(rvalue); + assert(data); + + w = WIREGUARD(data); + + assert(w); + + peer = wireguard_peer_new(w, section_line); + if (!peer) + return log_oom(); + + if (streq(rvalue, "off")) + keepalive = 0; + else { + r = safe_atou16(rvalue, &keepalive); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, r, "The persistent keepalive interval must be 0-65535. Ignore assignment: %s", rvalue); + } + + peer->persistent_keepalive_interval = keepalive; + return 0; +} + +static void wireguard_init(NetDev *netdev) { + Wireguard *w; + + assert(netdev); + + w = WIREGUARD(netdev); + + assert(w); + + w->flags = WGDEVICE_F_REPLACE_PEERS; +} + +static void wireguard_done(NetDev *netdev) { + Wireguard *w; + WireguardPeer *peer; + WireguardIPmask *mask; + + assert(netdev); + w = WIREGUARD(netdev); + assert(!w->unresolved_endpoints); + w->resolve_retry_event_source = sd_event_source_unref(w->resolve_retry_event_source); + + while ((peer = w->peers)) { + LIST_REMOVE(peers, w->peers, peer); + while ((mask = peer->ipmasks)) { + LIST_REMOVE(ipmasks, peer->ipmasks, mask); + free(mask); + } + free(peer); + } +} + +const NetDevVTable wireguard_vtable = { + .object_size = sizeof(Wireguard), + .sections = "Match\0NetDev\0WireGuard\0WireGuardPeer\0", + .post_create = netdev_wireguard_post_create, + .init = wireguard_init, + .done = wireguard_done, + .create_type = NETDEV_CREATE_INDEPENDENT, +}; diff --git a/src/network/netdev/wireguard.h b/src/network/netdev/wireguard.h new file mode 100644 index 0000000000..f788fa4221 --- /dev/null +++ b/src/network/netdev/wireguard.h @@ -0,0 +1,98 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2016 Jörg Thalheim <joerg@thalheim.io> + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +typedef struct Wireguard Wireguard; + +#include "netdev.h" +#include "sd-resolve.h" +#include "wireguard-netlink.h" +#include "socket-util.h" +#include "in-addr-util.h" + +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +typedef struct WireguardIPmask { + uint16_t family; + union in_addr_union ip; + uint8_t cidr; + + LIST_FIELDS(struct WireguardIPmask, ipmasks); +} WireguardIPmask; + +typedef struct WireguardPeer { + uint8_t public_key[WG_KEY_LEN]; + uint8_t preshared_key[WG_KEY_LEN]; + uint32_t flags; + + union sockaddr_union endpoint; + + uint16_t persistent_keepalive_interval; + + LIST_HEAD(WireguardIPmask, ipmasks); + LIST_FIELDS(struct WireguardPeer, peers); +} WireguardPeer; + +typedef struct WireguardEndpoint { + char *host; + char *port; + + NetDev *netdev; + WireguardPeer *peer; + + LIST_FIELDS(struct WireguardEndpoint, endpoints); +} WireguardEndpoint; + +struct Wireguard { + NetDev meta; + unsigned last_peer_section; + + char interface[IFNAMSIZ]; + uint32_t flags; + + uint8_t public_key[WG_KEY_LEN]; + uint8_t private_key[WG_KEY_LEN]; + uint32_t fwmark; + + uint16_t port; + + LIST_HEAD(WireguardPeer, peers); + size_t allocation_size; + sd_event_source *resolve_retry_event_source; + + LIST_HEAD(WireguardEndpoint, unresolved_endpoints); + LIST_HEAD(WireguardEndpoint, failed_endpoints); + unsigned n_retries; + sd_resolve_query *resolve_query; +}; + +DEFINE_NETDEV_CAST(WIREGUARD, Wireguard); +extern const NetDevVTable wireguard_vtable; + +int config_parse_wireguard_allowed_ips(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_wireguard_endpoint(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_wireguard_listen_port(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +int config_parse_wireguard_public_key(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_wireguard_private_key(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_wireguard_preshared_key(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_wireguard_keepalive(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index ff125e35de..ca5b54bdbf 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -984,251 +984,3 @@ bool address_is_ready(const Address *a) { else return !(a->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED)); } - -int config_parse_router_preference(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - if (streq(rvalue, "high")) - network->router_preference = SD_NDISC_PREFERENCE_HIGH; - else if (STR_IN_SET(rvalue, "medium", "normal", "default")) - network->router_preference = SD_NDISC_PREFERENCE_MEDIUM; - else if (streq(rvalue, "low")) - network->router_preference = SD_NDISC_PREFERENCE_LOW; - else - log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Router preference '%s' is invalid, ignoring assignment: %m", rvalue); - - return 0; -} - -void prefix_free(Prefix *prefix) { - if (!prefix) - return; - - if (prefix->network) { - LIST_REMOVE(prefixes, prefix->network->static_prefixes, prefix); - assert(prefix->network->n_static_prefixes > 0); - prefix->network->n_static_prefixes--; - - if (prefix->section) - hashmap_remove(prefix->network->prefixes_by_section, - prefix->section); - } - - prefix->radv_prefix = sd_radv_prefix_unref(prefix->radv_prefix); - - free(prefix); -} - -int prefix_new(Prefix **ret) { - _cleanup_prefix_free_ Prefix *prefix = NULL; - - prefix = new0(Prefix, 1); - if (!prefix) - return -ENOMEM; - - if (sd_radv_prefix_new(&prefix->radv_prefix) < 0) - return -ENOMEM; - - *ret = prefix; - prefix = NULL; - - return 0; -} - -int prefix_new_static(Network *network, const char *filename, - unsigned section_line, Prefix **ret) { - _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL; - _cleanup_prefix_free_ Prefix *prefix = NULL; - int r; - - assert(network); - assert(ret); - assert(!!filename == (section_line > 0)); - - if (filename) { - r = network_config_section_new(filename, section_line, &n); - if (r < 0) - return r; - - if (section_line) { - prefix = hashmap_get(network->prefixes_by_section, n); - if (prefix) { - *ret = prefix; - prefix = NULL; - - return 0; - } - } - } - - r = prefix_new(&prefix); - if (r < 0) - return r; - - if (filename) { - prefix->section = n; - n = NULL; - - r = hashmap_put(network->prefixes_by_section, prefix->section, - prefix); - if (r < 0) - return r; - } - - prefix->network = network; - LIST_APPEND(prefixes, network->static_prefixes, prefix); - network->n_static_prefixes++; - - *ret = prefix; - prefix = NULL; - - return 0; -} - -int config_parse_prefix(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - _cleanup_prefix_free_ Prefix *p = NULL; - uint8_t prefixlen = 64; - union in_addr_union in6addr; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = prefix_new_static(network, filename, section_line, &p); - if (r < 0) - return r; - - r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Prefix is invalid, ignoring assignment: %s", rvalue); - return 0; - } - - if (sd_radv_prefix_set_prefix(p->radv_prefix, &in6addr.in6, prefixlen) < 0) - return -EADDRNOTAVAIL; - - log_syntax(unit, LOG_INFO, filename, line, r, "Found prefix %s", rvalue); - - p = NULL; - - return 0; -} - -int config_parse_prefix_flags(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - _cleanup_prefix_free_ Prefix *p = NULL; - int r, val; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = prefix_new_static(network, filename, section_line, &p); - if (r < 0) - return r; - - r = parse_boolean(rvalue); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address flag, ignoring: %s", rvalue); - return 0; - } - - val = r; - - if (streq(lvalue, "OnLink")) - r = sd_radv_prefix_set_onlink(p->radv_prefix, val); - else if (streq(lvalue, "AddressAutoconfiguration")) - r = sd_radv_prefix_set_address_autoconfiguration(p->radv_prefix, val); - if (r < 0) - return r; - - p = NULL; - - return 0; -} - -int config_parse_prefix_lifetime(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - _cleanup_prefix_free_ Prefix *p = NULL; - usec_t usec; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = prefix_new_static(network, filename, section_line, &p); - if (r < 0) - return r; - - r = parse_sec(rvalue, &usec); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Lifetime is invalid, ignoring assignment: %s", rvalue); - return 0; - } - - /* a value of 0xffffffff represents infinity */ - if (streq(lvalue, "PreferredLifetimeSec")) - r = sd_radv_prefix_set_preferred_lifetime(p->radv_prefix, - DIV_ROUND_UP(usec, USEC_PER_SEC)); - else if (streq(lvalue, "ValidLifetimeSec")) - r = sd_radv_prefix_set_valid_lifetime(p->radv_prefix, - DIV_ROUND_UP(usec, USEC_PER_SEC)); - if (r < 0) - return r; - - p = NULL; - - return 0; -} diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index 3f5dffac4c..c2a241b571 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -26,7 +26,6 @@ #include "in-addr-util.h" typedef struct Address Address; -typedef struct Prefix Prefix; #include "networkd-link.h" #include "networkd-network.h" @@ -37,15 +36,6 @@ typedef struct Network Network; typedef struct Link Link; typedef struct NetworkConfigSection NetworkConfigSection; -struct Prefix { - Network *network; - NetworkConfigSection *section; - - sd_radv_prefix *radv_prefix; - - LIST_FIELDS(Prefix, prefixes); -}; - struct Address { Network *network; NetworkConfigSection *section; @@ -90,21 +80,9 @@ bool address_is_ready(const Address *a); DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free); #define _cleanup_address_free_ _cleanup_(address_freep) -int prefix_new(Prefix **ret); -void prefix_free(Prefix *prefix); -int prefix_new_static(Network *network, const char *filename, unsigned section, - Prefix **ret); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Prefix*, prefix_free); -#define _cleanup_prefix_free_ _cleanup_(prefix_freep) - int config_parse_address(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_broadcast(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_label(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_lifetime(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_address_flags(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_address_scope(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_router_preference(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_prefix(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_prefix_flags(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_prefix_lifetime(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 0b46deb009..ecb96cdb57 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -71,8 +71,9 @@ static int route_scope_from_address(const Route *route, const struct in_addr *se } static int link_set_dhcp_routes(Link *link) { - struct in_addr gateway, address; _cleanup_free_ sd_dhcp_route **static_routes = NULL; + bool classless_route = false, static_route = false; + struct in_addr gateway, address; int r, n, i; uint32_t table; @@ -102,8 +103,21 @@ static int link_set_dhcp_routes(Link *link) { log_link_debug_errno(link, n, "DHCP error: could not get routes: %m"); for (i = 0; i < n; i++) { + if (static_routes[i]->option == SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE) + classless_route = true; + + if (static_routes[i]->option == SD_DHCP_OPTION_STATIC_ROUTE) + static_route = true; + } + + for (i = 0; i < n; i++) { _cleanup_route_free_ Route *route = NULL; + /* if the DHCP server returns both a Classless Static Routes option and a Static Routes option, + the DHCP client MUST ignore the Static Routes option. */ + if (classless_route && static_routes[i]->option == SD_DHCP_OPTION_STATIC_ROUTE) + continue; + r = route_new(&route); if (r < 0) return log_link_error_errno(link, r, "Could not allocate route: %m"); @@ -132,7 +146,10 @@ static int link_set_dhcp_routes(Link *link) { /* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and a Router option, the DHCP client MUST ignore the Router option. */ - if (r >= 0 && link->dhcp4_messages <= 0) { + if (classless_route && static_route) + log_link_warning(link, "Classless static routes received from DHCP server: ignoring static-route option and router option"); + + if (r >= 0 && !classless_route) { _cleanup_route_free_ Route *route = NULL; _cleanup_route_free_ Route *route_gw = NULL; diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index a46a11bf16..234e0a4602 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -20,21 +20,249 @@ #include <netinet/ether.h> #include <linux/if.h> +#include "sd-radv.h" #include "sd-dhcp6-client.h" +#include "hashmap.h" #include "hostname-util.h" #include "network-internal.h" #include "networkd-link.h" #include "networkd-manager.h" +#include "siphash24.h" +#include "string-util.h" +#include "radv-internal.h" static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link); +static bool dhcp6_verify_link(Link *link) { + if (!link->network) { + log_link_info(link, "Link is not managed by us"); + return false; + } + + if (!IN_SET(link->network->router_prefix_delegation, + RADV_PREFIX_DELEGATION_DHCP6, + RADV_PREFIX_DELEGATION_BOTH)) { + log_link_debug(link, "Link does not request DHCPv6 prefix delegation"); + return false; + } + + return true; +} + +static bool dhcp6_enable_prefix_delegation(Link *dhcp6_link) { + Manager *manager; + Link *l; + Iterator i; + + assert(dhcp6_link); + + manager = dhcp6_link->manager; + assert(manager); + + HASHMAP_FOREACH(l, manager->links, i) { + if (l == dhcp6_link) + continue; + + if (!dhcp6_verify_link(l)) + continue; + + return true; + } + + return false; +} + static int dhcp6_lease_information_acquired(sd_dhcp6_client *client, Link *link) { return 0; } +static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix, + uint8_t prefix_len, + uint32_t lifetime_preferred, + uint32_t lifetime_valid) { + sd_radv *radv = link->radv; + int r; + _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL; + + r = sd_radv_prefix_new(&p); + if (r < 0) + return r; + + r = sd_radv_prefix_set_prefix(p, prefix, prefix_len); + if (r < 0) + return r; + + r = sd_radv_prefix_set_preferred_lifetime(p, lifetime_preferred); + if (r < 0) + return r; + + r = sd_radv_prefix_set_valid_lifetime(p, lifetime_valid); + if (r < 0) + return r; + + r = sd_radv_stop(radv); + if (r < 0) + return r; + + r = sd_radv_add_prefix(radv, p, true); + if (r < 0 && r != -EEXIST) + return r; + + r = manager_dhcp6_prefix_add(link->manager, &p->opt.in6_addr, link); + if (r < 0) + return r; + + return sd_radv_start(radv); +} + +static Network *dhcp6_reset_pd_prefix_network(Link *link) { + assert(link); + assert(link->manager); + assert(link->manager->networks); + + return link->manager->networks; +} + +static int dhcp6_pd_prefix_distribute(Link *dhcp6_link, Iterator *i, + struct in6_addr *pd_prefix, + uint8_t pd_prefix_len, + uint32_t lifetime_preferred, + uint32_t lifetime_valid) { + Link *link; + Manager *manager = dhcp6_link->manager; + union in_addr_union prefix; + uint8_t n_prefixes, n_used = 0; + _cleanup_free_ char *buf = NULL; + int r; + + assert(manager); + assert(pd_prefix_len <= 64); + + prefix.in6 = *pd_prefix; + + r = in_addr_mask(AF_INET6, &prefix, pd_prefix_len); + if (r < 0) + return r; + + n_prefixes = 1 << (64 - pd_prefix_len); + + (void) in_addr_to_string(AF_INET6, &prefix, &buf); + log_link_debug(dhcp6_link, "Assigning up to %u prefixes from %s/%u", + n_prefixes, strnull(buf), pd_prefix_len); + + while (hashmap_iterate(manager->links, i, (void **)&link, NULL)) { + Link *assigned_link; + + if (n_used == n_prefixes) { + log_link_debug(dhcp6_link, "Assigned %u/%u prefixes from %s/%u", + n_used, n_prefixes, strnull(buf), pd_prefix_len); + + return -EAGAIN; + } + + if (link == dhcp6_link) + continue; + + if (!dhcp6_verify_link(link)) + continue; + + assigned_link = manager_dhcp6_prefix_get(manager, &prefix.in6); + if (assigned_link != NULL && assigned_link != link) + continue; + + r = dhcp6_pd_prefix_assign(link, &prefix.in6, 64, + lifetime_preferred, lifetime_valid); + if (r < 0) { + log_link_error_errno(link, r, "Unable to %s prefix %s/%u for link: %m", + assigned_link ? "update": "assign", + strnull(buf), pd_prefix_len); + + if (assigned_link == NULL) + continue; + + } else + log_link_debug(link, "Assigned prefix %u/%u %s/64 to link", + n_used + 1, n_prefixes, strnull(buf)); + + n_used++; + + r = in_addr_prefix_next(AF_INET6, &prefix, pd_prefix_len); + if (r < 0 && n_used < n_prefixes) + return r; + } + + if (n_used < n_prefixes) { + Route *route; + int n = n_used; + + r = route_new(&route); + if (r < 0) + return r; + + while (n < n_prefixes) { + route_update(route, &prefix, pd_prefix_len, NULL, NULL, + 0, 0, RTN_UNREACHABLE); + + r = route_configure(route, link, NULL); + if (r < 0) { + route_free(route); + return r; + } + + r = in_addr_prefix_next(AF_INET6, &prefix, pd_prefix_len); + if (r < 0) + return r; + } + } + + return n_used; +} + +static int dhcp6_lease_pd_prefix_acquired(sd_dhcp6_client *client, Link *link) { + int r; + sd_dhcp6_lease *lease; + struct in6_addr pd_prefix; + uint8_t pd_prefix_len; + uint32_t lifetime_preferred, lifetime_valid; + _cleanup_free_ char *buf = NULL; + Iterator i = ITERATOR_FIRST; + + r = sd_dhcp6_client_get_lease(client, &lease); + if (r < 0) + return r; + + (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &pd_prefix, &buf); + + dhcp6_reset_pd_prefix_network(link); + sd_dhcp6_lease_reset_pd_prefix_iter(lease); + + while (sd_dhcp6_lease_get_pd(lease, &pd_prefix, &pd_prefix_len, + &lifetime_preferred, + &lifetime_valid) >= 0) { + + if (pd_prefix_len > 64) { + log_link_debug(link, "PD Prefix length > 64, ignoring prefix %s/%u", + strnull(buf), pd_prefix_len); + continue; + } + + r = dhcp6_pd_prefix_distribute(link, &i, &pd_prefix, + pd_prefix_len, + lifetime_preferred, + lifetime_valid); + if (r < 0 && r != -EAGAIN) + return r; + + if (r >= 0) + i = ITERATOR_FIRST; + } + + return 0; +} + static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { _cleanup_link_unref_ Link *link = userdata; @@ -139,6 +367,8 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) { if (sd_dhcp6_client_get_lease(client, NULL) >= 0) log_link_warning(link, "DHCPv6 lease lost"); + (void) manager_dhcp6_prefix_remove_all(link->manager, link); + link->dhcp6_configured = false; break; @@ -149,6 +379,10 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) { return; } + r = dhcp6_lease_pd_prefix_acquired(client, link); + if (r < 0) + log_link_debug(link, "DHCPv6 did not receive prefixes to delegate"); + _fallthrough_; case SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST: r = dhcp6_lease_information_acquired(client, link); @@ -237,10 +471,11 @@ static int dhcp6_set_hostname(sd_dhcp6_client *client, Link *link) { int dhcp6_configure(Link *link) { sd_dhcp6_client *client = NULL; - int r; const DUID *duid; + int r; assert(link); + assert(link->network); if (link->dhcp6_client) return 0; @@ -279,10 +514,22 @@ int dhcp6_configure(Link *link) { if (r < 0) goto error; + if (link->network->rapid_commit) { + r = sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_RAPID_COMMIT); + if (r < 0) + goto error; + } + r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link); if (r < 0) goto error; + if (dhcp6_enable_prefix_delegation(link)) { + r = sd_dhcp6_client_set_prefix_delegation(client, true); + if (r < 0) + goto error; + } + link->dhcp6_client = client; return 0; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 60ac980ad9..64c45080df 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -92,6 +92,9 @@ static bool link_ipv4ll_enabled(Link *link) { if (!link->network) return false; + if (streq_ptr(link->kind, "wireguard")) + return false; + return link->network->link_local & ADDRESS_FAMILY_IPV4; } @@ -107,6 +110,9 @@ static bool link_ipv6ll_enabled(Link *link) { if (!link->network) return false; + if (streq_ptr(link->kind, "wireguard")) + return false; + return link->network->link_local & ADDRESS_FAMILY_IPV6; } @@ -129,7 +135,7 @@ static bool link_radv_enabled(Link *link) { if (!link_ipv6ll_enabled(link)) return false; - return link->network->router_prefix_delegation; + return link->network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE; } static bool link_lldp_rx_enabled(Link *link) { @@ -849,6 +855,8 @@ static int link_enter_set_routes(Link *link) { assert(link->network); assert(link->state == LINK_STATE_SETTING_ADDRESSES); + (void) link_set_routing_policy_rule(link); + link_set_state(link, LINK_STATE_SETTING_ROUTES); LIST_FOREACH(routes, rt, link->network->static_routes) { @@ -862,8 +870,6 @@ static int link_enter_set_routes(Link *link) { link->route_messages++; } - (void) link_set_routing_policy_rule(link); - if (link->route_messages == 0) { link->static_routes_configured = true; link_check_ready(link); @@ -3317,6 +3323,12 @@ int link_update(Link *link, sd_netlink_message *m) { if (r < 0) return log_link_warning_errno(link, r, "Could not update MAC for Router Advertisement: %m"); } + + if (link->ndisc) { + r = sd_ndisc_set_mac(link->ndisc, &link->mac); + if (r < 0) + return log_link_warning_errno(link, r, "Could not update MAC for ndisc: %m"); + } } } diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index cc17af9391..749b87f336 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -82,19 +82,6 @@ static int setup_default_address_pool(Manager *m) { return 0; } -static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) { - Manager *m = userdata; - - assert(s); - assert(m); - - m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source); - - manager_connect_bus(m); - - return 0; -} - static int manager_reset_all(Manager *m) { Link *link; Iterator i; @@ -116,6 +103,7 @@ static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_b int b, r; assert(message); + assert(m); r = sd_bus_message_read(message, "b", &b); if (r < 0) { @@ -128,40 +116,37 @@ static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_b log_debug("Coming back from suspend, resetting all connections..."); - manager_reset_all(m); + (void) manager_reset_all(m); return 0; } -int manager_connect_bus(Manager *m) { - int r; +static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { + Manager *m = userdata; + assert(message); assert(m); - r = sd_bus_default_system(&m->bus); - if (r < 0) { - /* We failed to connect? Yuck, we must be in early - * boot. Let's try in 5s again. */ + /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */ + if (m->dynamic_hostname) + (void) manager_set_hostname(m, m->dynamic_hostname); + if (m->dynamic_timezone) + (void) manager_set_timezone(m, m->dynamic_timezone); + + return 0; +} - log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m"); +int manager_connect_bus(Manager *m) { + int r; - r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m); - if (r < 0) - return log_error_errno(r, "Failed to install bus reconnect time event: %m"); + assert(m); + if (m->bus) return 0; - } - r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot, - "type='signal'," - "sender='org.freedesktop.login1'," - "interface='org.freedesktop.login1.Manager'," - "member='PrepareForSleep'," - "path='/org/freedesktop/login1'", - match_prepare_for_sleep, - m); + r = bus_open_system_watch_bind(&m->bus); if (r < 0) - return log_error_errno(r, "Failed to add match for PrepareForSleep: %m"); + return log_error_errno(r, "Failed to connect to bus: %m"); r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m); if (r < 0) @@ -183,25 +168,35 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to add network enumerator: %m"); - r = sd_bus_request_name(m->bus, "org.freedesktop.network1", 0); + r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.network1", 0, NULL, NULL); if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); + return log_error_errno(r, "Failed to request name: %m"); r = sd_bus_attach_event(m->bus, m->event, 0); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); - /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */ - if (m->dynamic_hostname) { - r = manager_set_hostname(m, m->dynamic_hostname); - if (r < 0) - return r; - } - if (m->dynamic_timezone) { - r = manager_set_timezone(m, m->dynamic_timezone); - if (r < 0) - return r; - } + r = sd_bus_match_signal_async( + m->bus, + &m->connected_slot, + "org.freedesktop.DBus.Local", + NULL, + "org.freedesktop.DBus.Local", + "Connected", + on_connected, NULL, m); + if (r < 0) + return log_error_errno(r, "Failed to request match on Connected signal: %m"); + + r = sd_bus_match_signal_async( + m->bus, + &m->prepare_for_sleep_slot, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "PrepareForSleep", + match_prepare_for_sleep, NULL, m); + if (r < 0) + log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m"); return 0; } @@ -244,7 +239,8 @@ static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t if (!device) return -ENOMEM; - manager_udev_process_link(m, device); + (void) manager_udev_process_link(m, device); + return 0; } @@ -309,17 +305,17 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo if (sd_netlink_message_is_error(message)) { r = sd_netlink_message_get_errno(message); if (r < 0) - log_warning_errno(r, "rtnl: failed to receive route: %m"); + log_warning_errno(r, "rtnl: failed to receive route, ignoring: %m"); return 0; } r = sd_netlink_message_get_type(message, &type); if (r < 0) { - log_warning_errno(r, "rtnl: could not get message type: %m"); + log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); return 0; } else if (!IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE)) { - log_warning("rtnl: received unexpected message type when processing route"); + log_warning("rtnl: received unexpected message type when processing route, ignoring"); return 0; } @@ -346,7 +342,7 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo r = sd_rtnl_message_route_get_family(message, &family); if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) { - log_link_warning(link, "rtnl: received address with invalid family, ignoring."); + log_link_warning(link, "rtnl: received address with invalid family, ignoring"); return 0; } @@ -458,15 +454,17 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo return 0; } - route_get(link, family, &dst, dst_prefixlen, tos, priority, table, &route); + (void) route_get(link, family, &dst, dst_prefixlen, tos, priority, table, &route); switch (type) { case RTM_NEWROUTE: if (!route) { /* A route appeared that we did not request */ r = route_add_foreign(link, family, &dst, dst_prefixlen, tos, priority, table, &route); - if (r < 0) + if (r < 0) { + log_link_warning_errno(link, r, "Failed to add route, ignoring: %m"); return 0; + } } route_update(route, &src, src_prefixlen, &gw, &prefsrc, scope, protocol, rt_type); @@ -506,26 +504,26 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, if (sd_netlink_message_is_error(message)) { r = sd_netlink_message_get_errno(message); if (r < 0) - log_warning_errno(r, "rtnl: failed to receive address: %m"); + log_warning_errno(r, "rtnl: failed to receive address, ignoring: %m"); return 0; } r = sd_netlink_message_get_type(message, &type); if (r < 0) { - log_warning_errno(r, "rtnl: could not get message type: %m"); + log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); return 0; } else if (!IN_SET(type, RTM_NEWADDR, RTM_DELADDR)) { - log_warning("rtnl: received unexpected message type when processing address"); + log_warning("rtnl: received unexpected message type when processing address, ignoring"); return 0; } r = sd_rtnl_message_addr_get_ifindex(message, &ifindex); if (r < 0) { - log_warning_errno(r, "rtnl: could not get ifindex from address: %m"); + log_warning_errno(r, "rtnl: could not get ifindex from address, ignoring: %m"); return 0; } else if (ifindex <= 0) { - log_warning("rtnl: received address message with invalid ifindex: %d", ifindex); + log_warning("rtnl: received address message with invalid ifindex, ignoring: %d", ifindex); return 0; } else { r = link_get(m, ifindex, &link); @@ -540,7 +538,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, r = sd_rtnl_message_addr_get_family(message, &family); if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) { - log_link_warning(link, "rtnl: received address with invalid family, ignoring."); + log_link_warning(link, "rtnl: received address with invalid family, ignoring"); return 0; } @@ -582,23 +580,26 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, break; default: - log_link_debug(link, "rtnl: ignoring unsupported address family: %d", family); + assert_not_reached("Received unsupported address family"); } if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN)) { - log_link_warning(link, "Could not print address"); + log_link_warning(link, "Could not print address, ignoring"); return 0; } r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo); - if (r >= 0) { + if (r < 0 && r != -ENODATA) { + log_link_warning_errno(link, r, "rtnl: cannot get IFA_CACHEINFO attribute, ignoring: %m"); + return 0; + } else if (r >= 0) { if (cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME) valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX, cinfo.ifa_valid * USEC_PER_SEC, USEC_PER_SEC); } - address_get(link, family, &in_addr, prefixlen, &address); + (void) address_get(link, family, &in_addr, prefixlen, &address); switch (type) { case RTM_NEWADDR: @@ -609,14 +610,18 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, /* An address appeared that we did not request */ r = address_add_foreign(link, family, &in_addr, prefixlen, &address); if (r < 0) { - log_link_warning_errno(link, r, "Failed to add address %s/%u: %m", buf, prefixlen); + log_link_warning_errno(link, r, "Failed to add address %s/%u, ignoring: %m", buf, prefixlen); return 0; } else log_link_debug(link, "Adding address: %s/%u (valid %s%s)", buf, prefixlen, valid_str ? "for " : "forever", strempty(valid_str)); } - address_update(address, flags, scope, &cinfo); + r = address_update(address, flags, scope, &cinfo); + if (r < 0) { + log_link_warning_errno(link, r, "Failed to update address %s/%u, ignoring: %m", buf, prefixlen); + return 0; + } break; @@ -625,9 +630,9 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, if (address) { log_link_debug(link, "Removing address: %s/%u (valid %s%s)", buf, prefixlen, valid_str ? "for " : "forever", strempty(valid_str)); - address_drop(address); + (void) address_drop(address); } else - log_link_warning(link, "Removing non-existent address: %s/%u (valid %s%s)", buf, prefixlen, + log_link_warning(link, "Removing non-existent address: %s/%u (valid %s%s), ignoring", buf, prefixlen, valid_str ? "for " : "forever", strempty(valid_str)); break; @@ -653,32 +658,32 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa if (sd_netlink_message_is_error(message)) { r = sd_netlink_message_get_errno(message); if (r < 0) - log_warning_errno(r, "rtnl: Could not receive link: %m"); + log_warning_errno(r, "rtnl: Could not receive link, ignoring: %m"); return 0; } r = sd_netlink_message_get_type(message, &type); if (r < 0) { - log_warning_errno(r, "rtnl: Could not get message type: %m"); + log_warning_errno(r, "rtnl: Could not get message type, ignoring: %m"); return 0; } else if (!IN_SET(type, RTM_NEWLINK, RTM_DELLINK)) { - log_warning("rtnl: Received unexpected message type when processing link"); + log_warning("rtnl: Received unexpected message type when processing link, ignoring"); return 0; } r = sd_rtnl_message_link_get_ifindex(message, &ifindex); if (r < 0) { - log_warning_errno(r, "rtnl: Could not get ifindex from link: %m"); + log_warning_errno(r, "rtnl: Could not get ifindex from link, ignoring: %m"); return 0; } else if (ifindex <= 0) { - log_warning("rtnl: received link message with invalid ifindex: %d", ifindex); + log_warning("rtnl: received link message with invalid ifindex %d, ignoring", ifindex); return 0; } r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name); if (r < 0) { - log_warning_errno(r, "rtnl: Received link message without ifname: %m"); + log_warning_errno(r, "rtnl: Received link message without ifname, ignoring: %m"); return 0; } @@ -691,7 +696,7 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa /* link is new, so add it */ r = link_add(m, message, &link); if (r < 0) { - log_warning_errno(r, "Could not add new link: %m"); + log_warning_errno(r, "Could not add new link, ignoring: %m"); return 0; } } @@ -700,14 +705,16 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa /* netdev exists, so make sure the ifindex matches */ r = netdev_set_ifindex(netdev, message); if (r < 0) { - log_warning_errno(r, "Could not set ifindex on netdev: %m"); + log_warning_errno(r, "Could not set ifindex on netdev, ignoring: %m"); return 0; } } r = link_update(link, message); - if (r < 0) + if (r < 0) { + log_warning_errno(r, "Could not update link, ignoring: %m"); return 0; + } break; @@ -726,11 +733,11 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) { uint8_t tos = 0, to_prefixlen = 0, from_prefixlen = 0; + union in_addr_union to = {}, from = {}; RoutingPolicyRule *rule = NULL; - union in_addr_union to, from; uint32_t fwmark = 0, table = 0; + char *iif = NULL, *oif = NULL; Manager *m = userdata; - char *iif, *oif; uint16_t type; int family; int r; @@ -742,60 +749,80 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi if (sd_netlink_message_is_error(message)) { r = sd_netlink_message_get_errno(message); if (r < 0) - log_warning_errno(r, "rtnl: failed to receive rule: %m"); + log_warning_errno(r, "rtnl: failed to receive rule, ignoring: %m"); return 0; } r = sd_netlink_message_get_type(message, &type); if (r < 0) { - log_warning_errno(r, "rtnl: could not get message type: %m"); + log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); return 0; } else if (!IN_SET(type, RTM_NEWRULE, RTM_DELRULE)) { - log_warning("rtnl: received unexpected message type '%u' when processing rule.", type); + log_warning("rtnl: received unexpected message type '%u' when processing rule, ignoring", type); return 0; } r = sd_rtnl_message_get_family(message, &family); if (r < 0) { - log_warning_errno(r, "rtnl: could not get rule family: %m"); + log_warning_errno(r, "rtnl: could not get rule family, ignoring: %m"); return 0; } else if (!IN_SET(family, AF_INET, AF_INET6)) { - log_debug("rtnl: received address with invalid family %u, ignoring.", family); + log_debug("rtnl: received address with invalid family %u, ignoring", family); return 0; } switch (family) { case AF_INET: r = sd_netlink_message_read_in_addr(message, FRA_SRC, &from.in); - if (r >= 0) { + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m"); + return 0; + } else if (r >= 0) { r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen); - if (r < 0) - log_warning_errno(r, "rtnl: failed to retrive rule from prefix length: %m"); + if (r < 0) { + log_warning_errno(r, "rtnl: failed to retrive rule from prefix length, ignoring: %m"); + return 0; + } } r = sd_netlink_message_read_in_addr(message, FRA_DST, &to.in); - if (r >= 0) { + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m"); + return 0; + } else if (r >= 0) { r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen); - if (r < 0) - log_warning_errno(r, "rtnl: failed to retrive rule to prefix length: %m"); + if (r < 0) { + log_warning_errno(r, "rtnl: failed to retrive rule to prefix length, ignoring: %m"); + return 0; + } } break; case AF_INET6: r = sd_netlink_message_read_in6_addr(message, FRA_SRC, &from.in6); - if (r >= 0) { + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m"); + return 0; + } else if (r >= 0) { r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen); - if (r < 0) - log_warning_errno(r, "rtnl: failed to retrive rule from prefix length: %m"); + if (r < 0) { + log_warning_errno(r, "rtnl: failed to retrive rule from prefix length, ignoring: %m"); + return 0; + } } r = sd_netlink_message_read_in6_addr(message, FRA_DST, &to.in6); - if (r >= 0) { + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m"); + return 0; + } else if (r >= 0) { r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen); - if (r < 0) - log_warning_errno(r, "rtnl: failed to retrive rule to prefix length: %m"); + if (r < 0) { + log_warning_errno(r, "rtnl: failed to retrive rule to prefix length, ignoring: %m"); + return 0; + } } break; @@ -807,11 +834,35 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi if (from_prefixlen == 0 && to_prefixlen == 0) return 0; - (void) sd_netlink_message_read_u32(message, FRA_FWMARK, &fwmark); - (void) sd_netlink_message_read_u32(message, FRA_TABLE, &table); - (void) sd_rtnl_message_routing_policy_rule_get_tos(message, &tos); - (void) sd_netlink_message_read_string(message, FRA_IIFNAME, (const char **) &iif); - (void) sd_netlink_message_read_string(message, FRA_OIFNAME, (const char **) &oif); + r = sd_netlink_message_read_u32(message, FRA_FWMARK, &fwmark); + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_FWMARK attribute, ignoring: %m"); + return 0; + } + + r = sd_netlink_message_read_u32(message, FRA_TABLE, &table); + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_TABLE attribute, ignoring: %m"); + return 0; + } + + r = sd_rtnl_message_routing_policy_rule_get_tos(message, &tos); + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get ip rule TOS, ignoring: %m"); + return 0; + } + + r = sd_netlink_message_read_string(message, FRA_IIFNAME, (const char **) &iif); + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_IIFNAME attribute, ignoring: %m"); + return 0; + } + + r = sd_netlink_message_read_string(message, FRA_OIFNAME, (const char **) &oif); + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_OIFNAME attribute, ignoring: %m"); + return 0; + } (void) routing_policy_rule_get(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule); @@ -820,7 +871,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi if (!rule) { r = routing_policy_rule_add_foreign(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule); if (r < 0) { - log_warning_errno(r, "Could not add rule: %m"); + log_warning_errno(r, "Could not add rule, ignoring: %m"); return 0; } } @@ -856,6 +907,26 @@ static int systemd_netlink_fd(void) { return rtnl_fd; } +static int manager_connect_genl(Manager *m) { + int r; + + assert(m); + + r = sd_genl_socket_open(&m->genl); + if (r < 0) + return r; + + r = sd_netlink_inc_rcvbuf(m->genl, RCVBUF_SIZE); + if (r < 0) + return r; + + r = sd_netlink_attach_event(m->genl, m->event, 0); + if (r < 0) + return r; + + return 0; +} + static int manager_connect_rtnl(Manager *m) { int fd, r; @@ -1178,6 +1249,145 @@ static int manager_dirty_handler(sd_event_source *s, void *userdata) { return 1; } +Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr) { + assert_return(m, NULL); + assert_return(m->dhcp6_prefixes, NULL); + assert_return(addr, NULL); + + return hashmap_get(m->dhcp6_prefixes, addr); +} + +static int dhcp6_route_add_callback(sd_netlink *nl, sd_netlink_message *m, + void *userdata) { + Link *l = userdata; + int r; + union in_addr_union prefix; + _cleanup_free_ char *buf = NULL; + + r = sd_netlink_message_get_errno(m); + if (r != 0) { + log_link_debug_errno(l, r, "Received error adding DHCPv6 Prefix Delegation route: %m"); + return 0; + } + + r = sd_netlink_message_read_in6_addr(m, RTA_DST, &prefix.in6); + if (r < 0) { + log_link_debug_errno(l, r, "Could not read IPv6 address from DHCPv6 Prefix Delegation while adding route: %m"); + return 0; + } + + (void) in_addr_to_string(AF_INET6, &prefix, &buf); + log_link_debug(l, "Added DHCPv6 Prefix Deleagtion route %s/64", + strnull(buf)); + + return 0; +} + +int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) { + int r; + Route *route; + + assert_return(m, -EINVAL); + assert_return(m->dhcp6_prefixes, -ENODATA); + assert_return(addr, -EINVAL); + + r = route_add(link, AF_INET6, (union in_addr_union *) addr, 64, + 0, 0, 0, &route); + if (r < 0) + return r; + + r = route_configure(route, link, dhcp6_route_add_callback); + if (r < 0) + return r; + + return hashmap_put(m->dhcp6_prefixes, addr, link); +} + +static int dhcp6_route_remove_callback(sd_netlink *nl, sd_netlink_message *m, + void *userdata) { + Link *l = userdata; + int r; + union in_addr_union prefix; + _cleanup_free_ char *buf = NULL; + + r = sd_netlink_message_get_errno(m); + if (r != 0) { + log_link_debug_errno(l, r, "Received error on DHCPv6 Prefix Delegation route removal: %m"); + return 0; + } + + r = sd_netlink_message_read_in6_addr(m, RTA_DST, &prefix.in6); + if (r < 0) { + log_link_debug_errno(l, r, "Could not read IPv6 address from DHCPv6 Prefix Delegation while removing route: %m"); + return 0; + } + + (void) in_addr_to_string(AF_INET6, &prefix, &buf); + log_link_debug(l, "Removed DHCPv6 Prefix Delegation route %s/64", + strnull(buf)); + + return 0; +} + +int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) { + Link *l; + int r; + Route *route; + + assert_return(m, -EINVAL); + assert_return(m->dhcp6_prefixes, -ENODATA); + assert_return(addr, -EINVAL); + + l = hashmap_remove(m->dhcp6_prefixes, addr); + if (!l) + return -EINVAL; + + (void) sd_radv_remove_prefix(l->radv, addr, 64); + r = route_get(l, AF_INET6, (union in_addr_union *) addr, 64, + 0, 0, 0, &route); + if (r >= 0) + (void) route_remove(route, l, dhcp6_route_remove_callback); + + return 0; +} + +int manager_dhcp6_prefix_remove_all(Manager *m, Link *link) { + Iterator i; + Link *l; + struct in6_addr *addr; + + assert_return(m, -EINVAL); + assert_return(link, -EINVAL); + + HASHMAP_FOREACH_KEY(l, addr, m->dhcp6_prefixes, i) { + if (l != link) + continue; + + (void) manager_dhcp6_prefix_remove(m, addr); + } + + return 0; +} + +static void dhcp6_prefixes_hash_func(const void *p, struct siphash *state) { + const struct in6_addr *addr = p; + + assert(p); + + siphash24_compress(addr, sizeof(*addr), state); +} + +static int dhcp6_prefixes_compare_func(const void *_a, const void *_b) { + const struct in6_addr *a = _a, *b = _b; + + return memcmp(&a, &b, sizeof(*a)); +} + +static const struct hash_ops dhcp6_prefixes_hash_ops = { + .hash = dhcp6_prefixes_hash_func, + .compare = dhcp6_prefixes_compare_func, +}; + int manager_new(Manager **ret, sd_event *event) { _cleanup_manager_free_ Manager *m = NULL; int r; @@ -1200,6 +1410,10 @@ int manager_new(Manager **ret, sd_event *event) { if (r < 0) return r; + r = manager_connect_genl(m); + if (r < 0) + return r; + r = manager_connect_udev(m); if (r < 0) return r; @@ -1210,10 +1424,22 @@ int manager_new(Manager **ret, sd_event *event) { LIST_HEAD_INIT(m->networks); + r = sd_resolve_default(&m->resolve); + if (r < 0) + return r; + + r = sd_resolve_attach_event(m->resolve, m->event, 0); + if (r < 0) + return r; + r = setup_default_address_pool(m); if (r < 0) return r; + m->dhcp6_prefixes = hashmap_new(&dhcp6_prefixes_hash_ops); + if (!m->dhcp6_prefixes) + return -ENOMEM; + m->duid.type = DUID_TYPE_EN; (void) routing_policy_load_rules(m->state_file, &m->rules_saved); @@ -1238,6 +1464,10 @@ void manager_free(Manager *m) { while ((network = m->networks)) network_free(network); + while ((link = hashmap_first(m->dhcp6_prefixes))) + link_unref(link); + hashmap_free(m->dhcp6_prefixes); + while ((link = hashmap_first(m->links))) link_unref(link); hashmap_free(m->links); @@ -1259,12 +1489,15 @@ void manager_free(Manager *m) { sd_netlink_unref(m->rtnl); sd_event_unref(m->event); + sd_resolve_unref(m->resolve); + sd_event_source_unref(m->udev_event_source); udev_monitor_unref(m->udev_monitor); udev_unref(m->udev); sd_bus_unref(m->bus); sd_bus_slot_unref(m->prepare_for_sleep_slot); + sd_bus_slot_unref(m->connected_slot); sd_event_source_unref(m->bus_retry_event_source); free(m->dynamic_timezone); @@ -1539,12 +1772,12 @@ int manager_set_hostname(Manager *m, const char *hostname) { int r; log_debug("Setting transient hostname: '%s'", strna(hostname)); + if (free_and_strdup(&m->dynamic_hostname, hostname) < 0) return log_oom(); - if (!m->bus) { - /* TODO: replace by assert when we can rely on kdbus */ - log_info("Not connected to system bus, ignoring transient hostname."); + if (!m->bus || sd_bus_is_ready(m->bus) <= 0) { + log_info("Not connected to system bus, not setting hostname."); return 0; } @@ -1591,8 +1824,8 @@ int manager_set_timezone(Manager *m, const char *tz) { if (free_and_strdup(&m->dynamic_timezone, tz) < 0) return log_oom(); - if (!m->bus) { - log_info("Not connected to system bus, ignoring timezone."); + if (!m->bus || sd_bus_is_ready(m->bus) <= 0) { + log_info("Not connected to system bus, not setting hostname."); return 0; } diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index 186cb41891..229812ae0e 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -25,6 +25,7 @@ #include "sd-bus.h" #include "sd-event.h" #include "sd-netlink.h" +#include "sd-resolve.h" #include "udev.h" #include "dhcp-identifier.h" @@ -39,10 +40,14 @@ extern const char* const network_dirs[]; struct Manager { sd_netlink *rtnl; + /* lazy initialized */ + sd_netlink *genl; sd_event *event; + sd_resolve *resolve; sd_event_source *bus_retry_event_source; sd_bus *bus; sd_bus_slot *prepare_for_sleep_slot; + sd_bus_slot *connected_slot; struct udev *udev; struct udev_monitor *udev_monitor; sd_event_source *udev_event_source; @@ -58,6 +63,7 @@ struct Manager { Hashmap *links; Hashmap *netdevs; Hashmap *networks_by_name; + Hashmap *dhcp6_prefixes; LIST_HEAD(Network, networks); LIST_HEAD(AddressPool, address_pools); @@ -109,5 +115,10 @@ Link* manager_find_uplink(Manager *m, Link *exclude); int manager_set_hostname(Manager *m, const char *hostname); int manager_set_timezone(Manager *m, const char *timezone); +Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr); +int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link); +int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr); +int manager_dhcp6_prefix_remove_all(Manager *m, Link *link); + DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); #define _cleanup_manager_free_ _cleanup_(manager_freep) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 57a96aff94..281ba657b3 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -27,7 +27,8 @@ Match.Type, config_parse_strv, Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name) Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host) Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt) -Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel) +Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel_cmdline) +Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(Network, match_kernel_version) Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch) Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac) Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu) @@ -107,6 +108,9 @@ Route.GatewayOnlink, config_parse_gateway_onlink, Route.IPv6Preference, config_parse_ipv6_route_preference, 0, 0 Route.Protocol, config_parse_route_protocol, 0, 0 Route.Type, config_parse_route_type, 0, 0 +Route.InitialCongestionWindow, config_parse_tcp_window, 0, 0 +Route.InitialAdvertisedReceiveWindow, config_parse_tcp_window, 0, 0 +Route.QuickAck, config_parse_quickack, 0, 0 DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns) DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_use_ntp) @@ -127,6 +131,7 @@ DHCP.RouteTable, config_parse_dhcp_route_table, DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCP.IAID, config_parse_iaid, 0, offsetof(Network, iaid) DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) +DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit) IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns) IPv6AcceptRA.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains) IPv6AcceptRA.RouteTable, config_parse_uint32, 0, offsetof(Network, ipv6_accept_ra_route_table) @@ -153,7 +158,7 @@ BridgeFDB.VLANId, config_parse_fdb_vlan_id, BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0 BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0 BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0 -Network.IPv6PrefixDelegation, config_parse_bool, 0, offsetof(Network, router_prefix_delegation) +Network.IPv6PrefixDelegation, config_parse_router_prefix_delegation, 0, 0 IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec) IPv6PrefixDelegation.Managed, config_parse_bool, 0, offsetof(Network, router_managed) IPv6PrefixDelegation.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 8e37a0a229..2dc3de3f6a 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -228,6 +228,7 @@ static int network_load_one(Manager *manager, const char *filename) { network->dhcp_use_mtu = false; /* NOTE: from man: UseTimezone=... Defaults to "no".*/ network->dhcp_use_timezone = false; + network->rapid_commit = true; network->dhcp_server_emit_dns = true; network->dhcp_server_emit_ntp = true; @@ -431,7 +432,8 @@ void network_free(Network *network) { condition_free_list(network->match_host); condition_free_list(network->match_virt); - condition_free_list(network->match_kernel); + condition_free_list(network->match_kernel_cmdline); + condition_free_list(network->match_kernel_version); condition_free_list(network->match_arch); free(network->dhcp_server_timezone); @@ -485,8 +487,8 @@ int network_get(Manager *manager, struct udev_device *device, if (net_match_config(network->match_mac, network->match_path, network->match_driver, network->match_type, network->match_name, network->match_host, - network->match_virt, network->match_kernel, - network->match_arch, + network->match_virt, network->match_kernel_cmdline, + network->match_kernel_version, network->match_arch, address, path, parent_driver, driver, devtype, ifname)) { if (network->match_name && device) { diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 49c62654b6..7b40ba51e6 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -34,6 +34,7 @@ #include "networkd-fdb.h" #include "networkd-lldp-tx.h" #include "networkd-ipv6-proxy-ndp.h" +#include "networkd-radv.h" #include "networkd-route.h" #include "networkd-routing-policy-rule.h" #include "networkd-util.h" @@ -85,6 +86,13 @@ typedef struct DUID { uint8_t raw_data[MAX_DUID_LEN]; } DUID; +typedef enum RADVPrefixDelegation { + RADV_PREFIX_DELEGATION_NONE, + RADV_PREFIX_DELEGATION_STATIC, + RADV_PREFIX_DELEGATION_DHCP6, + RADV_PREFIX_DELEGATION_BOTH, +} RADVPrefixDelegation; + typedef struct NetworkConfigSection { unsigned line; char filename[]; @@ -112,7 +120,8 @@ struct Network { Condition *match_host; Condition *match_virt; - Condition *match_kernel; + Condition *match_kernel_cmdline; + Condition *match_kernel_version; Condition *match_arch; char *description; @@ -139,6 +148,7 @@ struct Network { bool dhcp_use_mtu; bool dhcp_use_routes; bool dhcp_use_timezone; + bool rapid_commit; bool dhcp_use_hostname; bool dhcp_route_table_set; DHCPUseDomains dhcp_use_domains; @@ -163,7 +173,7 @@ struct Network { bool ipv4ll_route; /* IPv6 prefix delegation support */ - bool router_prefix_delegation; + RADVPrefixDelegation router_prefix_delegation; usec_t router_lifetime_usec; uint8_t router_preference; bool router_managed; diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c index 535454c472..a921d120b3 100644 --- a/src/network/networkd-radv.c +++ b/src/network/networkd-radv.c @@ -24,7 +24,296 @@ #include "networkd-address.h" #include "networkd-manager.h" #include "networkd-radv.h" +#include "parse-util.h" #include "sd-radv.h" +#include "string-util.h" + +int config_parse_router_prefix_delegation( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + int d; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + if (streq(rvalue, "static")) + network->router_prefix_delegation = RADV_PREFIX_DELEGATION_STATIC; + else if (streq(rvalue, "dhcpv6")) + network->router_prefix_delegation = RADV_PREFIX_DELEGATION_DHCP6; + else { + d = parse_boolean(rvalue); + if (d > 0) + network->router_prefix_delegation = RADV_PREFIX_DELEGATION_BOTH; + else + network->router_prefix_delegation = RADV_PREFIX_DELEGATION_NONE; + + if (d < 0) + log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Router prefix delegation '%s' is invalid, ignoring assignment: %m", rvalue); + } + + return 0; +} + +int config_parse_router_preference(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + Network *network = userdata; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + if (streq(rvalue, "high")) + network->router_preference = SD_NDISC_PREFERENCE_HIGH; + else if (STR_IN_SET(rvalue, "medium", "normal", "default")) + network->router_preference = SD_NDISC_PREFERENCE_MEDIUM; + else if (streq(rvalue, "low")) + network->router_preference = SD_NDISC_PREFERENCE_LOW; + else + log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Router preference '%s' is invalid, ignoring assignment: %m", rvalue); + + return 0; +} + +void prefix_free(Prefix *prefix) { + if (!prefix) + return; + + if (prefix->network) { + LIST_REMOVE(prefixes, prefix->network->static_prefixes, prefix); + assert(prefix->network->n_static_prefixes > 0); + prefix->network->n_static_prefixes--; + + if (prefix->section) + hashmap_remove(prefix->network->prefixes_by_section, + prefix->section); + } + + prefix->radv_prefix = sd_radv_prefix_unref(prefix->radv_prefix); + + free(prefix); +} + +int prefix_new(Prefix **ret) { + Prefix *prefix = NULL; + + prefix = new0(Prefix, 1); + if (!prefix) + return -ENOMEM; + + if (sd_radv_prefix_new(&prefix->radv_prefix) < 0) + return -ENOMEM; + + *ret = prefix; + prefix = NULL; + + return 0; +} + +int prefix_new_static(Network *network, const char *filename, + unsigned section_line, Prefix **ret) { + _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL; + _cleanup_prefix_free_ Prefix *prefix = NULL; + int r; + + assert(network); + assert(ret); + assert(!!filename == (section_line > 0)); + + if (filename) { + r = network_config_section_new(filename, section_line, &n); + if (r < 0) + return r; + + if (section_line) { + prefix = hashmap_get(network->prefixes_by_section, n); + if (prefix) { + *ret = prefix; + prefix = NULL; + + return 0; + } + } + } + + r = prefix_new(&prefix); + if (r < 0) + return r; + + if (filename) { + prefix->section = n; + n = NULL; + + r = hashmap_put(network->prefixes_by_section, prefix->section, + prefix); + if (r < 0) + return r; + } + + prefix->network = network; + LIST_APPEND(prefixes, network->static_prefixes, prefix); + network->n_static_prefixes++; + + *ret = prefix; + prefix = NULL; + + return 0; +} + +int config_parse_prefix(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + _cleanup_prefix_free_ Prefix *p = NULL; + uint8_t prefixlen = 64; + union in_addr_union in6addr; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = prefix_new_static(network, filename, section_line, &p); + if (r < 0) + return r; + + r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Prefix is invalid, ignoring assignment: %s", rvalue); + return 0; + } + + if (sd_radv_prefix_set_prefix(p->radv_prefix, &in6addr.in6, prefixlen) < 0) + return -EADDRNOTAVAIL; + + log_syntax(unit, LOG_INFO, filename, line, r, "Found prefix %s", rvalue); + + p = NULL; + + return 0; +} + +int config_parse_prefix_flags(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + Network *network = userdata; + _cleanup_prefix_free_ Prefix *p = NULL; + int r, val; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = prefix_new_static(network, filename, section_line, &p); + if (r < 0) + return r; + + r = parse_boolean(rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address flag, ignoring: %s", rvalue); + return 0; + } + + val = r; + + if (streq(lvalue, "OnLink")) + r = sd_radv_prefix_set_onlink(p->radv_prefix, val); + else if (streq(lvalue, "AddressAutoconfiguration")) + r = sd_radv_prefix_set_address_autoconfiguration(p->radv_prefix, val); + if (r < 0) + return r; + + p = NULL; + + return 0; +} + +int config_parse_prefix_lifetime(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + Network *network = userdata; + _cleanup_prefix_free_ Prefix *p = NULL; + usec_t usec; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = prefix_new_static(network, filename, section_line, &p); + if (r < 0) + return r; + + r = parse_sec(rvalue, &usec); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Lifetime is invalid, ignoring assignment: %s", rvalue); + return 0; + } + + /* a value of 0xffffffff represents infinity */ + if (streq(lvalue, "PreferredLifetimeSec")) + r = sd_radv_prefix_set_preferred_lifetime(p->radv_prefix, + DIV_ROUND_UP(usec, USEC_PER_SEC)); + else if (streq(lvalue, "ValidLifetimeSec")) + r = sd_radv_prefix_set_valid_lifetime(p->radv_prefix, + DIV_ROUND_UP(usec, USEC_PER_SEC)); + if (r < 0) + return r; + + p = NULL; + + return 0; +} static int radv_get_ip6dns(Network *network, struct in6_addr **dns, size_t *n_dns) { @@ -211,10 +500,14 @@ int radv_configure(Link *link) { return r; } - LIST_FOREACH(prefixes, p, link->network->static_prefixes) { - r = sd_radv_add_prefix(link->radv, p->radv_prefix); - if (r != -EEXIST && r < 0) - return r; + if (IN_SET(link->network->router_prefix_delegation, + RADV_PREFIX_DELEGATION_STATIC, + RADV_PREFIX_DELEGATION_BOTH)) { + LIST_FOREACH(prefixes, p, link->network->static_prefixes) { + r = sd_radv_add_prefix(link->radv, p->radv_prefix, false); + if (r != -EEXIST && r < 0) + return r; + } } return radv_emit_dns(link); diff --git a/src/network/networkd-radv.h b/src/network/networkd-radv.h index f23029935a..22a169d263 100644 --- a/src/network/networkd-radv.h +++ b/src/network/networkd-radv.h @@ -20,7 +20,33 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "networkd-address.h" #include "networkd-link.h" +typedef struct Prefix Prefix; + +struct Prefix { + Network *network; + NetworkConfigSection *section; + + sd_radv_prefix *radv_prefix; + + LIST_FIELDS(Prefix, prefixes); +}; + +int prefix_new(Prefix **ret); +void prefix_free(Prefix *prefix); +int prefix_new_static(Network *network, const char *filename, unsigned section, + Prefix **ret); + +DEFINE_TRIVIAL_CLEANUP_FUNC(Prefix*, prefix_free); +#define _cleanup_prefix_free_ _cleanup_(prefix_freep) + +int config_parse_router_prefix_delegation(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_router_preference(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_prefix(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_prefix_flags(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_prefix_lifetime(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + int radv_emit_dns(Link *link); int radv_configure(Link *link); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index b0ad707811..70dca5219b 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -74,6 +74,7 @@ int route_new(Route **ret) { route->type = RTN_UNICAST; route->table = RT_TABLE_MAIN; route->lifetime = USEC_INFINITY; + route->quickack = -1; *ret = route; route = NULL; @@ -636,6 +637,24 @@ int route_configure( return log_error_errno(r, "Could not append RTAX_MTU attribute: %m"); } + if (route->initcwnd > 0) { + r = sd_netlink_message_append_u32(req, RTAX_INITCWND, route->initcwnd); + if (r < 0) + return log_error_errno(r, "Could not append RTAX_INITCWND attribute: %m"); + } + + if (route->initrwnd > 0) { + r = sd_netlink_message_append_u32(req, RTAX_INITRWND, route->initrwnd); + if (r < 0) + return log_error_errno(r, "Could not append RTAX_INITRWND attribute: %m"); + } + + if (route->quickack != -1) { + r = sd_netlink_message_append_u32(req, RTAX_QUICKACK, route->quickack); + if (r < 0) + return log_error_errno(r, "Could not append RTAX_QUICKACK attribute: %m"); + } + r = sd_netlink_message_close_container(req); if (r < 0) return log_error_errno(r, "Could not append RTA_METRICS attribute: %m"); @@ -1069,3 +1088,85 @@ int config_parse_route_type(const char *unit, return 0; } + +int config_parse_tcp_window(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + _cleanup_route_free_ Route *n = NULL; + Network *network = userdata; + uint64_t k; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &n); + if (r < 0) + return r; + + r = parse_size(rvalue, 1024, &k); + if (r < 0 || k > UINT32_MAX) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Could not parse TCP %s \"%s\" bytes, ignoring assignment: %m", rvalue, lvalue); + return 0; + } + + if (streq(lvalue, "InitialCongestionWindow")) + n->initcwnd = k; + else if (streq(lvalue, "InitialAdvertisedReceiveWindow")) + n->initrwnd = k; + else { + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse TCP %s: %s", lvalue, rvalue); + return 0; + } + + n = NULL; + + return 0; +} + +int config_parse_quickack(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + _cleanup_route_free_ Route *n = NULL; + Network *network = userdata; + int k, r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &n); + if (r < 0) + return r; + + k = parse_boolean(rvalue); + if (k < 0) { + log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse TCP quickack, ignoring: %s", rvalue); + return 0; + } + + n->quickack = !!k; + n = NULL; + + return 0; +} diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index cfb85cbd6d..6db9d592ea 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -32,6 +32,8 @@ struct Route { Link *link; int family; + int quickack; + unsigned char dst_prefixlen; unsigned char src_prefixlen; unsigned char scope; @@ -41,6 +43,8 @@ struct Route { uint32_t priority; /* note that ip(8) calls this 'metric' */ uint32_t table; uint32_t mtu; + uint32_t initcwnd; + uint32_t initrwnd; unsigned char pref; unsigned flags; @@ -81,3 +85,5 @@ int config_parse_gateway_onlink(const char *unit, const char *filename, unsigned int config_parse_ipv6_route_preference(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_route_protocol(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_route_type(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_tcp_window(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_quickack(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 1314564c11..fdbaec58eb 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -60,10 +60,11 @@ void routing_policy_rule_free(RoutingPolicyRule *rule) { network_config_section_free(rule->section); } - if (rule->network->manager) { - set_remove(rule->network->manager->rules, rule); - set_remove(rule->network->manager->rules_foreign, rule); - } + } + + if (rule->manager) { + set_remove(rule->manager->rules, rule); + set_remove(rule->manager->rules_foreign, rule); } free(rule->iif); @@ -236,7 +237,8 @@ int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule) { return -ENOENT; } -static int routing_policy_rule_add_internal(Set **rules, +static int routing_policy_rule_add_internal(Manager *m, + Set **rules, int family, const union in_addr_union *from, uint8_t from_prefixlen, @@ -258,6 +260,7 @@ static int routing_policy_rule_add_internal(Set **rules, if (r < 0) return r; + rule->manager = m; rule->family = family; rule->from = *from; rule->from_prefixlen = from_prefixlen; @@ -298,7 +301,7 @@ int routing_policy_rule_add(Manager *m, char *oif, RoutingPolicyRule **ret) { - return routing_policy_rule_add_internal(&m->rules, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret); + return routing_policy_rule_add_internal(m, &m->rules, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret); } int routing_policy_rule_add_foreign(Manager *m, @@ -313,7 +316,7 @@ int routing_policy_rule_add_foreign(Manager *m, char *iif, char *oif, RoutingPolicyRule **ret) { - return routing_policy_rule_add_internal(&m->rules_foreign, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret); + return routing_policy_rule_add_internal(m, &m->rules_foreign, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret); } static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h index 70a861723b..48353b9d10 100644 --- a/src/network/networkd-routing-policy-rule.h +++ b/src/network/networkd-routing-policy-rule.h @@ -33,8 +33,10 @@ typedef struct RoutingPolicyRule RoutingPolicyRule; typedef struct Network Network; typedef struct Link Link; typedef struct NetworkConfigSection NetworkConfigSection; +typedef struct Manager Manager; struct RoutingPolicyRule { + Manager *manager; Network *network; Link *link; NetworkConfigSection *section; diff --git a/src/network/networkd.c b/src/network/networkd.c index 9243384af8..79c15d4111 100644 --- a/src/network/networkd.c +++ b/src/network/networkd.c @@ -53,24 +53,13 @@ int main(int argc, char *argv[]) { goto out; } - /* Always create the directories people can create inotify - * watches in. */ + /* Create runtime directory. This is not necessary when networkd is + * started with "RuntimeDirectory=systemd/netif", or after + * systemd-tmpfiles-setup.service. */ r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid, false); if (r < 0) log_warning_errno(r, "Could not create runtime directory: %m"); - r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid, false); - if (r < 0) - log_warning_errno(r, "Could not create runtime directory 'links': %m"); - - r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid, false); - if (r < 0) - log_warning_errno(r, "Could not create runtime directory 'leases': %m"); - - r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid, false); - if (r < 0) - log_warning_errno(r, "Could not create runtime directory 'lldp': %m"); - /* Drop privileges, but only if we have been started as root. If we are not running as root we assume all * privileges are already dropped. */ if (geteuid() == 0) { @@ -83,6 +72,21 @@ int main(int argc, char *argv[]) { goto out; } + /* Always create the directories people can create inotify watches in. + * It is necessary to create the following subdirectories after drop_privileges() + * to support old kernels not supporting AmbientCapabilities=. */ + r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid, false); + if (r < 0) + log_warning_errno(r, "Could not create runtime directory 'links': %m"); + + r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid, false); + if (r < 0) + log_warning_errno(r, "Could not create runtime directory 'leases': %m"); + + r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid, false); + if (r < 0) + log_warning_errno(r, "Could not create runtime directory 'lldp': %m"); + assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0); r = sd_event_default(&event); diff --git a/src/network/test-routing-policy-rule.c b/src/network/test-routing-policy-rule.c index c29d134de2..3bbdd25b76 100644 --- a/src/network/test-routing-policy-rule.c +++ b/src/network/test-routing-policy-rule.c @@ -41,13 +41,15 @@ static void test_rule_serialization(const char *title, const char *ruleset, cons log_info("========== %s ==========", title); log_info("put:\n%s\n", ruleset); - assert_se((fd = mkostemp_safe(pattern)) >= 0); + fd = mkostemp_safe(pattern); + assert_se(fd >= 0); assert_se(f = fdopen(fd, "a+e")); assert_se(write_string_stream(f, ruleset, 0) == 0); assert_se(routing_policy_load_rules(pattern, &rules) == 0); - assert_se((fd2 = mkostemp_safe(pattern2)) >= 0); + fd2 = mkostemp_safe(pattern2); + assert_se(fd2 >= 0); assert_se(f2 = fdopen(fd2, "a+e")); assert_se(routing_policy_serialize_rules(rules, f2) == 0); @@ -57,7 +59,8 @@ static void test_rule_serialization(const char *title, const char *ruleset, cons log_info("got:\n%s", buf); - assert_se((fd3 = mkostemp_safe(pattern3)) >= 0); + fd3 = mkostemp_safe(pattern3); + assert_se(fd3 >= 0); assert_se(f3 = fdopen(fd3, "we")); assert_se(write_string_stream(f3, expected ?: ruleset, 0) == 0); diff --git a/src/notify/notify.c b/src/notify/notify.c index 3e511b7e47..d58a45cdd2 100644 --- a/src/notify/notify.c +++ b/src/notify/notify.c @@ -33,12 +33,15 @@ #include "parse-util.h" #include "string-util.h" #include "strv.h" +#include "user-util.h" #include "util.h" static bool arg_ready = false; static pid_t arg_pid = 0; static const char *arg_status = NULL; static bool arg_booted = false; +static uid_t arg_uid = UID_INVALID; +static gid_t arg_gid = GID_INVALID; static void help(void) { printf("%s [OPTIONS...] [VARIABLE=VALUE...]\n\n" @@ -46,7 +49,8 @@ static void help(void) { " -h --help Show this help\n" " --version Show package version\n" " --ready Inform the init system about service start-up completion\n" - " --pid[=PID] Set main pid of daemon\n" + " --pid[=PID] Set main PID of daemon\n" + " --uid=USER Set user to send from\n" " --status=TEXT Set status text\n" " --booted Check if the system was booted up with systemd\n", program_invocation_short_name); @@ -60,6 +64,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_PID, ARG_STATUS, ARG_BOOTED, + ARG_UID, }; static const struct option options[] = { @@ -69,10 +74,11 @@ static int parse_argv(int argc, char *argv[]) { { "pid", optional_argument, NULL, ARG_PID }, { "status", required_argument, NULL, ARG_STATUS }, { "booted", no_argument, NULL, ARG_BOOTED }, + { "uid", required_argument, NULL, ARG_UID }, {} }; - int c; + int c, r; assert(argc >= 0); assert(argv); @@ -112,6 +118,18 @@ static int parse_argv(int argc, char *argv[]) { arg_booted = true; break; + case ARG_UID: { + const char *u = optarg; + + r = get_user_creds(&u, &arg_uid, &arg_gid, NULL, NULL); + if (r == -ESRCH) /* If the user doesn't exist, then accept it anyway as numeric */ + r = parse_uid(u, &arg_uid); + if (r < 0) + return log_error_errno(r, "Can't resolve user %s: %m", optarg); + + break; + } + case '?': return -EINVAL; @@ -179,7 +197,7 @@ int main(int argc, char* argv[]) { goto finish; } - if (strv_length(final_env) <= 0) { + if (strv_isempty(final_env)) { r = 0; goto finish; } @@ -190,6 +208,22 @@ int main(int argc, char* argv[]) { goto finish; } + /* If this is requested change to the requested UID/GID. Note thta we only change the real UID here, and leave + the effective UID in effect (which is 0 for this to work). That's because we want the privileges to fake the + ucred data, and sd_pid_notify() uses the real UID for filling in ucred. */ + + if (arg_gid != GID_INVALID) + if (setregid(arg_gid, (gid_t) -1) < 0) { + r = log_error_errno(errno, "Failed to change GID: %m"); + goto finish; + } + + if (arg_uid != UID_INVALID) + if (setreuid(arg_uid, (uid_t) -1) < 0) { + r = log_error_errno(errno, "Failed to change UID: %m"); + goto finish; + } + r = sd_pid_notify(arg_pid ? arg_pid : getppid(), false, n); if (r < 0) { log_error_errno(r, "Failed to notify init system: %m"); diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index 920e114718..c9236ea3d1 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -474,9 +474,9 @@ static int mkdir_userns(const char *path, mode_t mode, MountSettingsMask mask, u assert(path); - r = mkdir(path, mode); - if (r < 0 && errno != EEXIST) - return -errno; + r = mkdir_errno_wrapper(path, mode); + if (r < 0 && r != -EEXIST) + return r; if ((mask & MOUNT_USE_USERNS) == 0) return 0; @@ -484,8 +484,7 @@ static int mkdir_userns(const char *path, mode_t mode, MountSettingsMask mask, u if (mask & MOUNT_IN_USERNS) return 0; - r = lchown(path, uid_shift, uid_shift); - if (r < 0) + if (lchown(path, uid_shift, uid_shift) < 0) return -errno; return 0; diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c index ef9db31df7..07d68242c6 100644 --- a/src/nspawn/nspawn-register.c +++ b/src/nspawn/nspawn-register.c @@ -203,7 +203,7 @@ int register_machine( if (r < 0) return r; - r = bus_append_unit_property_assignment_many(m, properties); + r = bus_append_unit_property_assignment_many(m, UNIT_SERVICE, properties); if (r < 0) return r; @@ -339,7 +339,7 @@ int allocate_scope( if (r < 0) return r; - r = bus_append_unit_property_assignment_many(m, properties); + r = bus_append_unit_property_assignment_many(m, UNIT_SCOPE, properties); if (r < 0) return r; diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h index c0c5a153b0..10b8a63052 100644 --- a/src/nspawn/nspawn-settings.h +++ b/src/nspawn/nspawn-settings.h @@ -22,6 +22,8 @@ #include <stdio.h> +#include "sd-id128.h" + #include "macro.h" #include "nspawn-expose-ports.h" #include "nspawn-mount.h" diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index 31f5dd3cdd..b08bcd988a 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -23,6 +23,7 @@ #include <unistd.h> #include "alloc-util.h" +#include "errno.h" #include "fd-util.h" #include "mkdir.h" #include "nspawn-setuid.h" @@ -33,7 +34,7 @@ #include "util.h" static int spawn_getent(const char *database, const char *key, pid_t *rpid) { - int pipe_fds[2]; + int pipe_fds[2], r; pid_t pid; assert(database); @@ -43,10 +44,10 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { if (pipe2(pipe_fds, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to allocate pipe: %m"); - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork getent child: %m"); - else if (pid == 0) { + r = safe_fork("(getent)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { int nullfd; char *empty_env = NULL; @@ -71,8 +72,6 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { if (nullfd > 2) safe_close(nullfd); - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); close_all_fds(NULL, 0); execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env); @@ -135,7 +134,7 @@ int change_uid_gid(const char *user, char **_home) { truncate_nl(line); - wait_for_terminate_and_warn("getent passwd", pid, true); + (void) wait_for_terminate_and_check("getent passwd", pid, WAIT_LOG); x = strchr(line, ':'); if (!x) { @@ -218,7 +217,7 @@ int change_uid_gid(const char *user, char **_home) { truncate_nl(line); - wait_for_terminate_and_warn("getent initgroups", pid, true); + (void) wait_for_terminate_and_check("getent initgroups", pid, WAIT_LOG); /* Skip over the username and subsequent separator whitespace */ x = line; diff --git a/src/nspawn/nspawn-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c index 7f2f8f1f13..58f4636866 100644 --- a/src/nspawn/nspawn-stub-pid1.c +++ b/src/nspawn/nspawn-stub-pid1.c @@ -25,6 +25,7 @@ #include "fd-util.h" #include "log.h" +#include "missing.h" #include "nspawn-stub-pid1.h" #include "process-util.h" #include "signal-util.h" @@ -92,7 +93,7 @@ int stub_pid1(sd_id128_t uuid) { sd_id128_to_string(uuid, new_environment + sizeof(new_environment) - SD_ID128_STRING_MAX); reset_environ(new_environment, sizeof(new_environment)); - rename_process("STUBINIT"); + (void) rename_process("(sd-stubinit)"); assert_se(sigemptyset(&waitmask) >= 0); assert_se(sigset_add_many(&waitmask, diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 71b14e2302..0f05ecff03 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1313,13 +1313,14 @@ static int userns_lchown(const char *p, uid_t uid, gid_t gid) { static int userns_mkdir(const char *root, const char *path, mode_t mode, uid_t uid, gid_t gid) { const char *q; + int r; q = prefix_roota(root, path); - if (mkdir(q, mode) < 0) { - if (errno == EEXIST) - return 0; - return -errno; - } + r = mkdir_errno_wrapper(q, mode); + if (r == -EEXIST) + return 0; + if (r < 0) + return r; return userns_lchown(q, uid, gid); } @@ -1599,8 +1600,10 @@ static int setup_pts(const char *dest) { /* Mount /dev/pts itself */ p = prefix_roota(dest, "/dev/pts"); - if (mkdir(p, 0755) < 0) - return log_error_errno(errno, "Failed to create /dev/pts: %m"); + r = mkdir_errno_wrapper(p, 0755); + if (r < 0) + return log_error_errno(r, "Failed to create /dev/pts: %m"); + r = mount_verbose(LOG_ERR, "devpts", p, "devpts", MS_NOSUID|MS_NOEXEC, options); if (r < 0) return r; @@ -1846,12 +1849,13 @@ static int setup_journal(const char *directory) { /* don't create parents here — if the host doesn't have * permanent journal set up, don't force it here */ - if (mkdir(p, 0755) < 0 && errno != EEXIST) { + r = mkdir_errno_wrapper(p, 0755); + if (r < 0 && r != -EEXIST) { if (try) { - log_debug_errno(errno, "Failed to create %s, skipping journal setup: %m", p); + log_debug_errno(r, "Failed to create %s, skipping journal setup: %m", p); return 0; } else - return log_error_errno(errno, "Failed to create %s: %m", p); + return log_error_errno(r, "Failed to create %s: %m", p); } } else if (access(p, F_OK) < 0) @@ -2159,8 +2163,11 @@ static int determine_names(void) { if (!arg_ephemeral) arg_read_only = arg_read_only || i->read_only; - } else - arg_directory = get_current_dir_name(); + } else { + r = safe_getcwd(&arg_directory); + if (r < 0) + return log_error_errno(r, "Failed to determine current directory: %m"); + } if (!arg_directory && !arg_image) { log_error("Failed to determine path, please use -D or -i."); @@ -3512,9 +3519,11 @@ static int run(int master, } /* Wait for the outer child. */ - r = wait_for_terminate_and_warn("namespace helper", *pid, NULL); - if (r != 0) - return r < 0 ? r : -EIO; + r = wait_for_terminate_and_check("(sd-namespace)", *pid, WAIT_LOG_ABNORMAL); + if (r < 0) + return r; + if (r != EXIT_SUCCESS) + return -EIO; /* And now retrieve the PID of the inner child. */ l = recv(pid_socket_pair[0], pid, sizeof *pid, 0); @@ -3616,14 +3625,16 @@ static int run(int master, * case PID 1 will send us a friendly RequestStop signal, when it is asked to terminate the * scope. Let's hook into that, and cleanly shut down the container, and print a friendly message. */ - r = sd_bus_add_match(bus, NULL, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Scope'," - "member='RequestStop'", - on_request_stop, PID_TO_PTR(*pid)); + r = sd_bus_match_signal_async( + bus, + NULL, + "org.freedesktop.systemd1", + NULL, + "org.freedesktop.systemd1.Scope", + "RequestStop", + on_request_stop, NULL, PID_TO_PTR(*pid)); if (r < 0) - return log_error_errno(r, "Failed to install request stop match: %m"); + return log_error_errno(r, "Failed to request RequestStop match: %m"); } if (arg_register) { diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c index cab3c22bb2..fe6ce4cbbf 100644 --- a/src/nss-resolve/nss-resolve.c +++ b/src/nss-resolve/nss-resolve.c @@ -30,6 +30,7 @@ #include "in-addr-util.h" #include "macro.h" #include "nss-util.h" +#include "resolved-def.h" #include "string-util.h" #include "util.h" #include "signal-util.h" @@ -37,8 +38,6 @@ NSS_GETHOSTBYNAME_PROTOTYPES(resolve); NSS_GETHOSTBYADDR_PROTOTYPES(resolve); -#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC) - static bool bus_error_shall_fallback(sd_bus_error *e) { return sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) || sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER) || @@ -157,7 +156,7 @@ enum nss_status _nss_resolve_gethostbyname4_r( if (r < 0) goto fail; - r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply); + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); if (r < 0) { if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) { *errnop = ESRCH; @@ -335,7 +334,7 @@ enum nss_status _nss_resolve_gethostbyname3_r( if (r < 0) goto fail; - r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply); + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); if (r < 0) { if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) { *errnop = ESRCH; @@ -533,7 +532,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( if (r < 0) goto fail; - r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply); + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); if (r < 0) { if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) { *errnop = ESRCH; diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c index cc641e1615..f75405d2e5 100644 --- a/src/nss-systemd/nss-systemd.c +++ b/src/nss-systemd/nss-systemd.c @@ -136,7 +136,8 @@ enum nss_status _nss_systemd_getpwnam_r( *errnop = 0; return NSS_STATUS_SUCCESS; } - if (streq(name, nobody_passwd.pw_name)) { + if (synthesize_nobody() && + streq(name, nobody_passwd.pw_name)) { *pwd = nobody_passwd; *errnop = 0; return NSS_STATUS_SUCCESS; @@ -244,7 +245,8 @@ enum nss_status _nss_systemd_getpwuid_r( *errnop = 0; return NSS_STATUS_SUCCESS; } - if (uid == nobody_passwd.pw_uid) { + if (synthesize_nobody() && + uid == nobody_passwd.pw_uid) { *pwd = nobody_passwd; *errnop = 0; return NSS_STATUS_SUCCESS; @@ -351,7 +353,8 @@ enum nss_status _nss_systemd_getgrnam_r( *errnop = 0; return NSS_STATUS_SUCCESS; } - if (streq(name, nobody_group.gr_name)) { + if (synthesize_nobody() && + streq(name, nobody_group.gr_name)) { *gr = nobody_group; *errnop = 0; return NSS_STATUS_SUCCESS; @@ -456,7 +459,8 @@ enum nss_status _nss_systemd_getgrgid_r( *errnop = 0; return NSS_STATUS_SUCCESS; } - if (gid == nobody_group.gr_gid) { + if (synthesize_nobody() && + gid == nobody_group.gr_gid) { *gr = nobody_group; *errnop = 0; return NSS_STATUS_SUCCESS; diff --git a/src/partition/growfs.c b/src/partition/growfs.c index 901b33e39e..41b4e872be 100644 --- a/src/partition/growfs.c +++ b/src/partition/growfs.c @@ -28,6 +28,7 @@ #include <sys/types.h> #include <sys/vfs.h> +#include "blockdev-util.h" #include "crypt-util.h" #include "device-nodes.h" #include "dissect-image.h" diff --git a/src/partition/makefs.c b/src/partition/makefs.c index e5e125255b..a957967dfe 100644 --- a/src/partition/makefs.c +++ b/src/partition/makefs.c @@ -28,12 +28,14 @@ #include "alloc-util.h" #include "dissect-image.h" +#include "process-util.h" #include "signal-util.h" #include "string-util.h" static int makefs(const char *type, const char *device) { const char *mkfs; pid_t pid; + int r; if (streq(type, "swap")) mkfs = "/sbin/mkswap"; @@ -42,24 +44,19 @@ static int makefs(const char *type, const char *device) { if (access(mkfs, X_OK) != 0) return log_error_errno(errno, "%s is not executable: %m", mkfs); - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "fork(): %m"); - - if (pid == 0) { + r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { const char *cmdline[3] = { mkfs, device, NULL }; /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - execv(cmdline[0], (char**) cmdline); _exit(EXIT_FAILURE); } - return wait_for_terminate_and_warn(mkfs, pid, true); + return wait_for_terminate_and_check(mkfs, pid, WAIT_LOG); } int main(int argc, char *argv[]) { diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c index ec5be21a34..1bf718e4f6 100644 --- a/src/quotacheck/quotacheck.c +++ b/src/quotacheck/quotacheck.c @@ -71,14 +71,6 @@ static void test_files(void) { } int main(int argc, char *argv[]) { - - static const char * const cmdline[] = { - QUOTACHECK, - "-anug", - NULL - }; - - pid_t pid; int r; if (argc > 1) { @@ -106,25 +98,22 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } - pid = fork(); - if (pid < 0) { - r = log_error_errno(errno, "fork(): %m"); + r = safe_fork("(quotacheck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL); + if (r < 0) goto finish; - } - if (pid == 0) { + if (r == 0) { + static const char * const cmdline[] = { + QUOTACHECK, + "-anug", + NULL + }; /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - execv(cmdline[0], (char**) cmdline); - _exit(1); /* Operational error */ + _exit(EXIT_FAILURE); /* Operational error */ } - r = wait_for_terminate_and_warn("quotacheck", pid, true); - finish: return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/src/rc-local-generator/rc-local-generator.c b/src/rc-local-generator/rc-local-generator.c index 196947ca51..2762fa7e89 100644 --- a/src/rc-local-generator/rc-local-generator.c +++ b/src/rc-local-generator/rc-local-generator.c @@ -23,7 +23,6 @@ #include <stdio.h> #include <unistd.h> -#include "alloc-util.h" #include "log.h" #include "mkdir.h" #include "string-util.h" @@ -32,21 +31,16 @@ static const char *arg_dest = "/tmp"; static int add_symlink(const char *service, const char *where) { - _cleanup_free_ char *from = NULL, *to = NULL; + const char *from, *to; int r; assert(service); assert(where); - from = strjoin(SYSTEM_DATA_UNIT_PATH, "/", service); - if (!from) - return log_oom(); + from = strjoina(SYSTEM_DATA_UNIT_PATH "/", service); + to = strjoina(arg_dest, "/", where, ".wants/", service); - to = strjoin(arg_dest, "/", where, ".wants/", service); - if (!to) - return log_oom(); - - mkdir_parents_label(to, 0755); + (void) mkdir_parents_label(to, 0755); r = symlink(from, to); if (r < 0) { @@ -60,7 +54,7 @@ static int add_symlink(const char *service, const char *where) { } int main(int argc, char *argv[]) { - int r = EXIT_SUCCESS; + int ret = EXIT_SUCCESS; if (argc > 1 && argc != 4) { log_error("This program takes three or no arguments."); @@ -70,7 +64,8 @@ int main(int argc, char *argv[]) { if (argc > 1) arg_dest = argv[1]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); @@ -80,15 +75,15 @@ int main(int argc, char *argv[]) { log_debug("Automatically adding rc-local.service."); if (add_symlink("rc-local.service", "multi-user.target") < 0) - r = EXIT_FAILURE; + ret = EXIT_FAILURE; } if (access(RC_LOCAL_SCRIPT_PATH_STOP, X_OK) >= 0) { log_debug("Automatically adding halt-local.service."); if (add_symlink("halt-local.service", "final.target") < 0) - r = EXIT_FAILURE; + ret = EXIT_FAILURE; } - return r; + return ret; } diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c index 2d7cf723f4..c61777c3fe 100644 --- a/src/remount-fs/remount-fs.c +++ b/src/remount-fs/remount-fs.c @@ -87,19 +87,12 @@ int main(int argc, char *argv[]) { log_debug("Remounting %s", me->mnt_dir); - pid = fork(); - if (pid < 0) { - r = log_error_errno(errno, "Failed to fork: %m"); + r = safe_fork("(remount)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (r < 0) goto finish; - } - - if (pid == 0) { + if (r == 0) { /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - (void) prctl(PR_SET_PDEATHSIG, SIGTERM); - execv(MOUNT_PATH, STRV_MAKE(MOUNT_PATH, me->mnt_dir, "-o", "remount")); log_error_errno(errno, "Failed to execute " MOUNT_PATH ": %m"); diff --git a/src/resolve/dns-type.c b/src/resolve/dns-type.c index 347252a90f..0c366b5e8e 100644 --- a/src/resolve/dns-type.c +++ b/src/resolve/dns-type.c @@ -19,6 +19,7 @@ ***/ #include <sys/socket.h> +#include <errno.h> #include "dns-type.h" #include "parse-util.h" diff --git a/src/resolve/meson.build b/src/resolve/meson.build index ee1acb5166..15752d24ff 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -31,7 +31,7 @@ basic_dns_sources = files(''' dns_type_h = files('dns-type.h')[0] -systemd_resolved_only_sources = files(''' +systemd_resolved_sources = files(''' resolved.c resolved-manager.c resolved-manager.h @@ -80,7 +80,7 @@ systemd_resolved_only_sources = files(''' resolved-etc-hosts.c '''.split()) -systemd_resolve_only_sources = files('resolve-tool.c') +systemd_resolve_sources = files('resolve-tool.c') ############################################################ @@ -141,14 +141,13 @@ resolved_dnssd_gperf_c = custom_target( output : 'resolved-dnssd-gperf.c', command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@']) -systemd_resolved_sources = (basic_dns_sources + - [resolved_gperf_c, resolved_dnssd_gperf_c] + - systemd_resolved_only_sources + - dns_type_headers) +libsystemd_resolve_core = static_library( + 'systemd-resolve-core', + basic_dns_sources, + dns_type_headers, + include_directories : includes) -systemd_resolve_sources = (basic_dns_sources + - systemd_resolve_only_sources + - dns_type_headers) +systemd_resolved_sources += [resolved_gperf_c, resolved_dnssd_gperf_c] if conf.get('ENABLE_RESOLVE') == 1 install_data('org.freedesktop.resolve1.conf', @@ -178,37 +177,37 @@ endif tests += [ [['src/resolve/test-resolve-tables.c', - basic_dns_sources, dns_type_headers, 'src/shared/test-tables.h'], - [], + [libsystemd_resolve_core, + libshared], [libgcrypt, libgpg_error, libm], 'ENABLE_RESOLVE'], [['src/resolve/test-dns-packet.c', - basic_dns_sources, dns_type_headers], - [], + [libsystemd_resolve_core, + libshared], [libgcrypt, libgpg_error, libm], 'ENABLE_RESOLVE'], [['src/resolve/test-resolved-packet.c', - basic_dns_sources, dns_type_headers], - [], + [libsystemd_resolve_core, + libshared], [libgcrypt, libgpg_error, libm], 'ENABLE_RESOLVE'], [['src/resolve/test-dnssec.c', - basic_dns_sources, dns_type_headers], - [], + [libsystemd_resolve_core, + libshared], [libgcrypt, libgpg_error, libm], diff --git a/src/resolve/resolve-tool.c b/src/resolve/resolve-tool.c index 0252bdfcd7..2a6bf94070 100644 --- a/src/resolve/resolve-tool.c +++ b/src/resolve/resolve-tool.c @@ -41,8 +41,6 @@ #include "strv.h" #include "terminal-util.h" -#define DNS_CALL_TIMEOUT_USEC (90*USEC_PER_SEC) - static int arg_family = AF_UNSPEC; static int arg_ifindex = 0; static uint16_t arg_type = 0; @@ -175,7 +173,7 @@ static int resolve_host(sd_bus *bus, const char *name) { ts = now(CLOCK_MONOTONIC); - r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply); + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); if (r < 0) return log_error_errno(r, "%s: resolve call failed: %s", name, bus_error_message(&error, r)); @@ -306,7 +304,7 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a ts = now(CLOCK_MONOTONIC); - r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply); + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); if (r < 0) { log_error("%s: resolve call failed: %s", pretty, bus_error_message(&error, r)); return r; @@ -442,7 +440,7 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_ ts = now(CLOCK_MONOTONIC); - r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply); + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); if (r < 0) { if (warn_missing || r != -ENXIO) log_error("%s: resolve call failed: %s", name, bus_error_message(&error, r)); @@ -685,7 +683,7 @@ static int resolve_service(sd_bus *bus, const char *name, const char *type, cons ts = now(CLOCK_MONOTONIC); - r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply); + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); if (r < 0) return log_error_errno(r, "Resolve call failed: %s", bus_error_message(&error, r)); diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 9157d9ea68..ffd7c4824e 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -1844,18 +1844,6 @@ static const sd_bus_vtable resolve_vtable[] = { SD_BUS_VTABLE_END, }; -static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) { - Manager *m = userdata; - - assert(s); - assert(m); - - m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source); - - manager_connect_bus(m); - return 0; -} - static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { Manager *m = userdata; int b, r; @@ -1886,20 +1874,9 @@ int manager_connect_bus(Manager *m) { if (m->bus) return 0; - r = sd_bus_default_system(&m->bus); - if (r < 0) { - /* We failed to connect? Yuck, we must be in early - * boot. Let's try in 5s again. */ - - log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m"); - - r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m); - if (r < 0) - return log_error_errno(r, "Failed to install bus reconnect time event: %m"); - - (void) sd_event_source_set_description(m->bus_retry_event_source, "bus-retry"); - return 0; - } + r = bus_open_system_watch_bind(&m->bus); + if (r < 0) + return log_error_errno(r, "Failed to connect to system bus: %m"); r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m); if (r < 0) @@ -1921,24 +1898,26 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to register dnssd enumerator: %m"); - r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0); + r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.resolve1", 0, NULL, NULL); if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); + return log_error_errno(r, "Failed to request name: %m"); r = sd_bus_attach_event(m->bus, m->event, 0); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); - r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot, - "type='signal'," - "sender='org.freedesktop.login1'," - "interface='org.freedesktop.login1.Manager'," - "member='PrepareForSleep'," - "path='/org/freedesktop/login1'", - match_prepare_for_sleep, - m); - if (r < 0) - log_error_errno(r, "Failed to add match for PrepareForSleep: %m"); + r = sd_bus_match_signal_async( + m->bus, + &m->prepare_for_sleep_slot, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "PrepareForSleep", + match_prepare_for_sleep, + NULL, + m); + if (r < 0) + log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m"); return 0; } diff --git a/src/resolve/resolved-def.h b/src/resolve/resolved-def.h index 64c2b1503e..96f93107ad 100644 --- a/src/resolve/resolved-def.h +++ b/src/resolve/resolved-def.h @@ -22,6 +22,8 @@ #include <inttypes.h> +#include "time-util.h" + #define SD_RESOLVED_DNS (UINT64_C(1) << 0) #define SD_RESOLVED_LLMNR_IPV4 (UINT64_C(1) << 1) #define SD_RESOLVED_LLMNR_IPV6 (UINT64_C(1) << 2) @@ -37,3 +39,5 @@ #define SD_RESOLVED_MDNS (SD_RESOLVED_MDNS_IPV4|SD_RESOLVED_MDNS_IPV6) #define SD_RESOLVED_PROTOCOLS_ALL (SD_RESOLVED_MDNS|SD_RESOLVED_LLMNR|SD_RESOLVED_DNS) + +#define SD_RESOLVED_QUERY_TIMEOUT_USEC (120 * USEC_PER_SEC) diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 942956dd71..e9197f1dfd 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -476,7 +476,7 @@ static int dns_cache_put_positive( if (r < 0) return r; - if (log_get_max_level() >= LOG_DEBUG) { + if (DEBUG_LOGGING) { _cleanup_free_ char *t = NULL; (void) in_addr_to_string(i->owner_family, &i->owner_address, &t); diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index d7a839a823..2067dd5182 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -18,6 +18,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#if HAVE_GCRYPT +#include <gcrypt.h> +#endif + #include "alloc-util.h" #include "dns-domain.h" #include "resolved-dns-packet.h" @@ -752,13 +756,20 @@ int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, in static const uint8_t rfc6975[] = { 0, 5, /* OPTION_CODE: DAU */ +#if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600 + 0, 7, /* LIST_LENGTH */ +#else 0, 6, /* LIST_LENGTH */ +#endif DNSSEC_ALGORITHM_RSASHA1, DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1, DNSSEC_ALGORITHM_RSASHA256, DNSSEC_ALGORITHM_RSASHA512, DNSSEC_ALGORITHM_ECDSAP256SHA256, DNSSEC_ALGORITHM_ECDSAP384SHA384, +#if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600 + DNSSEC_ALGORITHM_ED25519, +#endif 0, 6, /* OPTION_CODE: DHU */ 0, 3, /* LIST_LENGTH */ @@ -1837,6 +1848,9 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl if (r < 0) return r; + if (rdlength < 4) + return -EBADMSG; + r = dns_packet_read_memdup(p, rdlength - 4, &rr->ds.digest, &rr->ds.digest_size, NULL); @@ -1859,6 +1873,9 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl if (r < 0) return r; + if (rdlength < 2) + return -EBADMSG; + r = dns_packet_read_memdup(p, rdlength - 2, &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size, NULL); @@ -1883,6 +1900,9 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl if (r < 0) return r; + if (rdlength < 4) + return -EBADMSG; + r = dns_packet_read_memdup(p, rdlength - 4, &rr->dnskey.key, &rr->dnskey.key_size, NULL); @@ -1927,6 +1947,9 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl if (r < 0) return r; + if (rdlength + offset < p->rindex) + return -EBADMSG; + r = dns_packet_read_memdup(p, offset + rdlength - p->rindex, &rr->rrsig.signature, &rr->rrsig.signature_size, NULL); @@ -2016,6 +2039,9 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl if (r < 0) return r; + if (rdlength < 3) + return -EBADMSG; + r = dns_packet_read_memdup(p, rdlength - 3, &rr->tlsa.data, &rr->tlsa.data_size, NULL); @@ -2036,6 +2062,9 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl if (r < 0) return r; + if (rdlength + offset < p->rindex) + return -EBADMSG; + r = dns_packet_read_memdup(p, rdlength + offset - p->rindex, &rr->caa.value, &rr->caa.value_size, NULL); @@ -2111,19 +2140,11 @@ static bool opt_is_good(DnsResourceRecord *rr, bool *rfc6975) { return true; } -int dns_packet_extract(DnsPacket *p) { +static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question) { _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL; - _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; - _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = {}; unsigned n, i; int r; - if (p->extracted) - return 0; - - INIT_REWINDER(rewinder, p); - dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE); - n = DNS_PACKET_QDCOUNT(p); if (n > 0) { question = dns_question_new(n); @@ -2150,107 +2171,146 @@ int dns_packet_extract(DnsPacket *p) { } } + *ret_question = question; + question = NULL; + return 0; +} + +static int dns_packet_extract_answer(DnsPacket *p, DnsAnswer **ret_answer) { + _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; + unsigned n, i; + _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *previous = NULL; + bool bad_opt = false; + int r; + n = DNS_PACKET_RRCOUNT(p); - if (n > 0) { - _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *previous = NULL; - bool bad_opt = false; + if (n == 0) + return 0; - answer = dns_answer_new(n); - if (!answer) - return -ENOMEM; + answer = dns_answer_new(n); + if (!answer) + return -ENOMEM; - for (i = 0; i < n; i++) { - _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL; - bool cache_flush = false; + for (i = 0; i < n; i++) { + _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL; + bool cache_flush = false; - r = dns_packet_read_rr(p, &rr, &cache_flush, NULL); - if (r < 0) - return r; + r = dns_packet_read_rr(p, &rr, &cache_flush, NULL); + if (r < 0) + return r; - /* Try to reduce memory usage a bit */ - if (previous) - dns_resource_key_reduce(&rr->key, &previous->key); + /* Try to reduce memory usage a bit */ + if (previous) + dns_resource_key_reduce(&rr->key, &previous->key); - if (rr->key->type == DNS_TYPE_OPT) { - bool has_rfc6975; + if (rr->key->type == DNS_TYPE_OPT) { + bool has_rfc6975; - if (p->opt || bad_opt) { - /* Multiple OPT RRs? if so, let's ignore all, because there's something wrong - * with the server, and if one is valid we wouldn't know which one. */ - log_debug("Multiple OPT RRs detected, ignoring all."); - bad_opt = true; - continue; - } + if (p->opt || bad_opt) { + /* Multiple OPT RRs? if so, let's ignore all, because there's + * something wrong with the server, and if one is valid we wouldn't + * know which one. */ + log_debug("Multiple OPT RRs detected, ignoring all."); + bad_opt = true; + continue; + } - if (!dns_name_is_root(dns_resource_key_name(rr->key))) { - /* If the OPT RR is not owned by the root domain, then it is bad, let's ignore - * it. */ - log_debug("OPT RR is not owned by root domain, ignoring."); - bad_opt = true; - continue; - } + if (!dns_name_is_root(dns_resource_key_name(rr->key))) { + /* If the OPT RR is not owned by the root domain, then it is bad, + * let's ignore it. */ + log_debug("OPT RR is not owned by root domain, ignoring."); + bad_opt = true; + continue; + } - if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)) { - /* OPT RR is in the wrong section? Some Belkin routers do this. This is a hint - * the EDNS implementation is borked, like the Belkin one is, hence ignore - * it. */ - log_debug("OPT RR in wrong section, ignoring."); - bad_opt = true; - continue; + if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)) { + /* OPT RR is in the wrong section? Some Belkin routers do this. This + * is a hint the EDNS implementation is borked, like the Belkin one + * is, hence ignore it. */ + log_debug("OPT RR in wrong section, ignoring."); + bad_opt = true; + continue; + } + + if (!opt_is_good(rr, &has_rfc6975)) { + log_debug("Malformed OPT RR, ignoring."); + bad_opt = true; + continue; + } + + if (DNS_PACKET_QR(p)) { + /* Additional checks for responses */ + + if (!DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(rr)) { + /* If this is a reply and we don't know the EDNS version + * then something is weird... */ + log_debug("EDNS version newer that our request, bad server."); + return -EBADMSG; } - if (!opt_is_good(rr, &has_rfc6975)) { - log_debug("Malformed OPT RR, ignoring."); + if (has_rfc6975) { + /* If the OPT RR contains RFC6975 algorithm data, then this + * is indication that the server just copied the OPT it got + * from us (which contained that data) back into the reply. + * If so, then it doesn't properly support EDNS, as RFC6975 + * makes it very clear that the algorithm data should only + * be contained in questions, never in replies. Crappy + * Belkin routers copy the OPT data for example, hence let's + * detect this so that we downgrade early. */ + log_debug("OPT RR contained RFC6975 data, ignoring."); bad_opt = true; continue; } + } - if (DNS_PACKET_QR(p)) { - /* Additional checks for responses */ - - if (!DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(rr)) { - /* If this is a reply and we don't know the EDNS version then something - * is weird... */ - log_debug("EDNS version newer that our request, bad server."); - return -EBADMSG; - } - - if (has_rfc6975) { - /* If the OPT RR contains RFC6975 algorithm data, then this is indication that - * the server just copied the OPT it got from us (which contained that data) - * back into the reply. If so, then it doesn't properly support EDNS, as - * RFC6975 makes it very clear that the algorithm data should only be contained - * in questions, never in replies. Crappy Belkin routers copy the OPT data for - * example, hence let's detect this so that we downgrade early. */ - log_debug("OPT RR contained RFC6975 data, ignoring."); - bad_opt = true; - continue; - } - } + p->opt = dns_resource_record_ref(rr); + } else { + /* According to RFC 4795, section 2.9. only the RRs from the Answer section + * shall be cached. Hence mark only those RRs as cacheable by default, but + * not the ones from the Additional or Authority sections. */ + DnsAnswerFlags flags = + (i < DNS_PACKET_ANCOUNT(p) ? DNS_ANSWER_CACHEABLE : 0) | + (p->protocol == DNS_PROTOCOL_MDNS && !cache_flush ? DNS_ANSWER_SHARED_OWNER : 0); + + r = dns_answer_add(answer, rr, p->ifindex, flags); + if (r < 0) + return r; + } - p->opt = dns_resource_record_ref(rr); - } else { + /* Remember this RR, so that we potentically can merge it's ->key object with the + * next RR. Note that we only do this if we actually decided to keep the RR around. + */ + dns_resource_record_unref(previous); + previous = dns_resource_record_ref(rr); + } - /* According to RFC 4795, section 2.9. only the RRs from the Answer section shall be - * cached. Hence mark only those RRs as cacheable by default, but not the ones from the - * Additional or Authority sections. */ + if (bad_opt) + p->opt = dns_resource_record_unref(p->opt); - r = dns_answer_add(answer, rr, p->ifindex, - (i < DNS_PACKET_ANCOUNT(p) ? DNS_ANSWER_CACHEABLE : 0) | - (p->protocol == DNS_PROTOCOL_MDNS && !cache_flush ? DNS_ANSWER_SHARED_OWNER : 0)); - if (r < 0) - return r; - } + *ret_answer = answer; + answer = NULL; + return 0; +} - /* Remember this RR, so that we potentically can merge it's ->key object with the next RR. Note - * that we only do this if we actually decided to keep the RR around. */ - dns_resource_record_unref(previous); - previous = dns_resource_record_ref(rr); - } +int dns_packet_extract(DnsPacket *p) { + _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL; + _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; + _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = {}; + int r; - if (bad_opt) - p->opt = dns_resource_record_unref(p->opt); - } + if (p->extracted) + return 0; + + INIT_REWINDER(rewinder, p); + dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE); + + r = dns_packet_extract_question(p, &question); + if (r < 0) + return r; + + r = dns_packet_extract_answer(p, &answer); + if (r < 0) + return r; p->question = question; question = NULL; diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index 227d0b5d11..5f51340743 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -28,9 +28,6 @@ #include "resolved-etc-hosts.h" #include "string-util.h" -/* How long to wait for the query in total */ -#define QUERY_TIMEOUT_USEC (60 * USEC_PER_SEC) - #define CNAME_MAX 8 #define QUERIES_MAX 2048 #define AUXILIARY_QUERIES_MAX 64 @@ -769,8 +766,8 @@ int dns_query_go(DnsQuery *q) { q->manager->event, &q->timeout_event_source, clock_boottime_or_monotonic(), - now(clock_boottime_or_monotonic()) + QUERY_TIMEOUT_USEC, 0, - on_query_timeout, q); + now(clock_boottime_or_monotonic()) + SD_RESOLVED_QUERY_TIMEOUT_USEC, + 0, on_query_timeout, q); if (r < 0) goto fail; diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index eb5592d3cf..4056bda558 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -517,9 +517,13 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) { case DNS_TYPE_OPENPGPKEY: default: - free(rr->generic.data); + if (!rr->unparseable) + free(rr->generic.data); } + if (rr->unparseable) + free(rr->generic.data); + free(rr->wire_format); dns_resource_key_unref(rr->key); } diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index ea4459a89a..bf6aac8300 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -885,13 +885,17 @@ static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata scope->conflict_event_source = sd_event_source_unref(scope->conflict_event_source); for (;;) { + _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL; _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL; _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; - rr = ordered_hashmap_steal_first(scope->conflict_queue); - if (!rr) + key = ordered_hashmap_first_key(scope->conflict_queue); + if (!key) break; + rr = ordered_hashmap_remove(scope->conflict_queue, key); + assert(rr); + r = dns_scope_make_conflict_packet(scope, rr, &p); if (r < 0) { log_error_errno(r, "Failed to make conflict packet: %m"); @@ -930,6 +934,7 @@ int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) { if (r < 0) return log_debug_errno(r, "Failed to queue conflicting RR: %m"); + dns_resource_key_ref(rr->key); dns_resource_record_ref(rr); if (scope->conflict_event_source) @@ -953,7 +958,7 @@ int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) { } void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) { - unsigned i; + DnsResourceRecord *rr; int r; assert(scope); @@ -984,21 +989,24 @@ void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) { log_debug("Checking for conflicts..."); - for (i = 0; i < p->answer->n_rrs; i++) { + DNS_ANSWER_FOREACH(rr, p->answer) { + /* No conflict if it is DNS-SD RR used for service enumeration. */ + if (dns_resource_key_is_dnssd_ptr(rr->key)) + continue; /* Check for conflicts against the local zone. If we * found one, we won't check any further */ - r = dns_zone_check_conflicts(&scope->zone, p->answer->items[i].rr); + r = dns_zone_check_conflicts(&scope->zone, rr); if (r != 0) continue; /* Check for conflicts against the local cache. If so, * send out an advisory query, to inform everybody */ - r = dns_cache_check_conflicts(&scope->cache, p->answer->items[i].rr, p->family, &p->sender); + r = dns_cache_check_conflicts(&scope->cache, rr, p->family, &p->sender); if (r <= 0) continue; - dns_scope_notify_conflict(scope, p->answer->items[i].rr); + dns_scope_notify_conflict(scope, rr); } } diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index d470a64524..68c5d5c1e3 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -30,7 +30,7 @@ /* After how much time to repeat classic DNS requests */ #define DNS_TIMEOUT_MIN_USEC (750 * USEC_PER_MSEC) -#define DNS_TIMEOUT_MAX_USEC (5 * USEC_PER_SEC) +#define DNS_TIMEOUT_MAX_USEC (SD_RESOLVED_QUERY_TIMEOUT_USEC / DNS_TRANSACTION_ATTEMPTS_MAX) /* The amount of time to wait before retrying with a full feature set */ #define DNS_SERVER_FEATURE_GRACE_PERIOD_MAX_USEC (6 * USEC_PER_HOUR) diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 2dbf432df9..2ee027791a 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -488,7 +488,8 @@ static int manager_watch_hostname(Manager *m) { assert(m); - m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY); + m->hostname_fd = open("/proc/sys/kernel/hostname", + O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); if (m->hostname_fd < 0) { log_warning_errno(errno, "Failed to watch hostname: %m"); return 0; @@ -1410,7 +1411,7 @@ void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResource assert(verdict >= 0); assert(verdict < _DNSSEC_VERDICT_MAX); - if (log_get_max_level() >= LOG_DEBUG) { + if (DEBUG_LOGGING) { char s[DNS_RESOURCE_KEY_STRING_MAX]; log_debug("Found verdict for lookup %s: %s", diff --git a/src/resolve/test-dns-packet.c b/src/resolve/test-dns-packet.c index 458c908fad..c1f118fecc 100644 --- a/src/resolve/test-dns-packet.c +++ b/src/resolve/test-dns-packet.c @@ -21,6 +21,8 @@ #include <net/if.h> #include <glob.h> +#include "sd-id128.h" + #include "alloc-util.h" #include "fileio.h" #include "glob-util.h" diff --git a/src/resolve/test-dnssec-complex.c b/src/resolve/test-dnssec-complex.c index e7b077939f..514f72eeeb 100644 --- a/src/resolve/test-dnssec-complex.c +++ b/src/resolve/test-dnssec-complex.c @@ -27,11 +27,10 @@ #include "bus-common-errors.h" #include "dns-type.h" #include "random-util.h" +#include "resolved-def.h" #include "string-util.h" #include "time-util.h" -#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC) - static void prefix_random(const char *name, char **ret) { uint64_t i, u; char *m = NULL; @@ -75,7 +74,7 @@ static void test_rr_lookup(sd_bus *bus, const char *name, uint16_t type, const c assert_se(sd_bus_message_append(req, "isqqt", 0, name, DNS_CLASS_IN, type, UINT64_C(0)) >= 0); - r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply); + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); if (r < 0) { assert_se(result); @@ -112,7 +111,7 @@ static void test_hostname_lookup(sd_bus *bus, const char *name, int family, cons assert_se(sd_bus_message_append(req, "isit", 0, name, family, UINT64_C(0)) >= 0); - r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply); + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); if (r < 0) { assert_se(result); diff --git a/src/resolve/test-dnssec.c b/src/resolve/test-dnssec.c index 2d2b5e31bf..ebabfba96d 100644 --- a/src/resolve/test-dnssec.c +++ b/src/resolve/test-dnssec.c @@ -19,7 +19,9 @@ ***/ #include <arpa/inet.h> +#if HAVE_GCRYPT #include <gcrypt.h> +#endif #include <netinet/in.h> #include <sys/socket.h> diff --git a/src/run/run.c b/src/run/run.c index 5d7441ac93..a30501169c 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -40,6 +40,7 @@ #include "spawn-polkit-agent.h" #include "strv.h" #include "terminal-util.h" +#include "unit-def.h" #include "unit-name.h" #include "user-util.h" @@ -68,6 +69,8 @@ static enum { ARG_STDIO_DIRECT, /* Directly pass our stdin/stdout/stderr to the activated service, useful for usage in shell pipelines, requested by --pipe */ ARG_STDIO_AUTO, /* If --pipe and --pty are used together we use --pty when invoked on a TTY, and --pipe otherwise */ } arg_stdio = ARG_STDIO_NONE; +static char **arg_path_property = NULL; +static char **arg_socket_property = NULL; static char **arg_timer_property = NULL; static bool with_timer = false; static bool arg_quiet = false; @@ -101,6 +104,10 @@ static void help(void) { " -P --pipe Pass STDIN/STDOUT/STDERR directly to service\n" " -q --quiet Suppress information messages during runtime\n" " -G --collect Unload unit after it ran, even when failed\n\n" + "Path options:\n" + " --path-property=NAME=VALUE Set path unit property\n\n" + "Socket options:\n" + " --socket-property=NAME=VALUE Set socket unit property\n\n" "Timer options:\n" " --on-active=SECONDS Run after SECONDS delay\n" " --on-boot=SECONDS Run SECONDS after machine was booted up\n" @@ -113,7 +120,7 @@ static void help(void) { } static int add_timer_property(const char *name, const char *val) { - _cleanup_free_ char *p = NULL; + char *p; assert(name); assert(val); @@ -125,8 +132,6 @@ static int add_timer_property(const char *name, const char *val) { if (strv_consume(&arg_timer_property, p) < 0) return log_oom(); - p = NULL; - return 0; } @@ -152,6 +157,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_ON_UNIT_INACTIVE, ARG_ON_CALENDAR, ARG_TIMER_PROPERTY, + ARG_PATH_PROPERTY, + ARG_SOCKET_PROPERTY, ARG_NO_BLOCK, ARG_NO_ASK_PASSWORD, ARG_WAIT, @@ -188,12 +195,15 @@ static int parse_argv(int argc, char *argv[]) { { "on-unit-inactive", required_argument, NULL, ARG_ON_UNIT_INACTIVE }, { "on-calendar", required_argument, NULL, ARG_ON_CALENDAR }, { "timer-property", required_argument, NULL, ARG_TIMER_PROPERTY }, + { "path-property", required_argument, NULL, ARG_PATH_PROPERTY }, + { "socket-property", required_argument, NULL, ARG_SOCKET_PROPERTY }, { "no-block", no_argument, NULL, ARG_NO_BLOCK }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, { "collect", no_argument, NULL, 'G' }, {}, }; + bool with_trigger = false; int r, c; assert(argc >= 0); @@ -368,6 +378,20 @@ static int parse_argv(int argc, char *argv[]) { !!startswith(optarg, "OnCalendar="); break; + case ARG_PATH_PROPERTY: + + if (strv_extend(&arg_path_property, optarg) < 0) + return log_oom(); + + break; + + case ARG_SOCKET_PROPERTY: + + if (strv_extend(&arg_socket_property, optarg) < 0) + return log_oom(); + + break; + case ARG_NO_BLOCK: arg_no_block = true; break; @@ -387,6 +411,13 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached("Unhandled option"); } + with_trigger = !!arg_path_property || !!arg_socket_property || with_timer; + + /* currently, only single trigger (path, socket, timer) unit can be created simultaneously */ + if ((int) !!arg_path_property + (int) !!arg_socket_property + (int) with_timer > 1) { + log_error("Only single trigger (path, socket, timer) unit can be created."); + return -EINVAL; + } if (arg_stdio == ARG_STDIO_AUTO) { /* If we both --pty and --pipe are specified we'll automatically pick --pty if we are connected fully @@ -397,7 +428,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_STDIO_DIRECT; } - if ((optind >= argc) && (!arg_unit || !with_timer)) { + if ((optind >= argc) && (!arg_unit || !with_trigger)) { log_error("Command line to execute required."); return -EINVAL; } @@ -417,7 +448,7 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } - if (arg_stdio != ARG_STDIO_NONE && (with_timer || arg_scope)) { + if (arg_stdio != ARG_STDIO_NONE && (with_trigger || arg_scope)) { log_error("--pty/--pipe is not compatible in timer or --scope mode."); return -EINVAL; } @@ -432,8 +463,8 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } - if (arg_scope && with_timer) { - log_error("Timer options are not supported in --scope mode."); + if (arg_scope && with_trigger) { + log_error("Path, socket or timer options are not supported in --scope mode."); return -EINVAL; } @@ -448,8 +479,8 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } - if (with_timer) { - log_error("--wait may not be combined with timer operations."); + if (with_trigger) { + log_error("--wait may not be combined with path, socket or timer operations."); return -EINVAL; } @@ -462,7 +493,7 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -static int transient_unit_set_properties(sd_bus_message *m, char **properties) { +static int transient_unit_set_properties(sd_bus_message *m, UnitType t, char **properties) { int r; r = sd_bus_message_append(m, "(sv)", "Description", "s", arg_description); @@ -475,7 +506,7 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) { return bus_log_create_error(r); } - r = bus_append_unit_property_assignment_many(m, properties); + r = bus_append_unit_property_assignment_many(m, t, properties); if (r < 0) return r; @@ -521,7 +552,7 @@ static int transient_service_set_properties(sd_bus_message *m, char **argv, cons assert(m); - r = transient_unit_set_properties(m, arg_property); + r = transient_unit_set_properties(m, UNIT_SERVICE, arg_property); if (r < 0) return r; @@ -694,7 +725,7 @@ static int transient_scope_set_properties(sd_bus_message *m) { assert(m); - r = transient_unit_set_properties(m, arg_property); + r = transient_unit_set_properties(m, UNIT_SCOPE, arg_property); if (r < 0) return r; @@ -718,7 +749,7 @@ static int transient_timer_set_properties(sd_bus_message *m) { assert(m); - r = transient_unit_set_properties(m, arg_timer_property); + r = transient_unit_set_properties(m, UNIT_TIMER, arg_timer_property); if (r < 0) return r; @@ -1028,7 +1059,6 @@ static int start_transient_service( .inactive_enter_usec = USEC_INFINITY, }; _cleanup_free_ char *path = NULL; - const char *mt; c.bus = sd_bus_ref(bus); @@ -1058,18 +1088,20 @@ static int start_transient_service( if (!path) return log_oom(); - mt = strjoina("type='signal'," - "sender='org.freedesktop.systemd1'," - "path='", path, "'," - "interface='org.freedesktop.DBus.Properties'," - "member='PropertiesChanged'"); - r = sd_bus_add_match(bus, &c.match, mt, on_properties_changed, &c); + r = sd_bus_match_signal_async( + bus, + &c.match, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + on_properties_changed, NULL, &c); if (r < 0) - return log_error_errno(r, "Failed to add properties changed signal."); + return log_error_errno(r, "Failed to request properties changed signal match: %m"); r = sd_bus_attach_event(bus, c.event, SD_EVENT_PRIORITY_NORMAL); if (r < 0) - return log_error_errno(r, "Failed to attach bus to event loop."); + return log_error_errno(r, "Failed to attach bus to event loop: %m"); r = run_context_update(&c, path); if (r < 0) @@ -1282,14 +1314,15 @@ static int start_transient_scope( return log_error_errno(errno, "Failed to execute: %m"); } -static int start_transient_timer( +static int start_transient_trigger( sd_bus *bus, - char **argv) { + char **argv, + const char *suffix) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; - _cleanup_free_ char *timer = NULL, *service = NULL; + _cleanup_free_ char *trigger = NULL, *service = NULL; const char *object = NULL; int r; @@ -1308,17 +1341,17 @@ static int start_transient_timer( if (!service) return log_oom(); - r = unit_name_change_suffix(service, ".timer", &timer); + r = unit_name_change_suffix(service, suffix, &trigger); if (r < 0) return log_error_errno(r, "Failed to change unit suffix: %m"); break; case UNIT_TIMER: - timer = strdup(arg_unit); - if (!timer) + trigger = strdup(arg_unit); + if (!trigger) return log_oom(); - r = unit_name_change_suffix(timer, ".service", &service); + r = unit_name_change_suffix(trigger, ".service", &service); if (r < 0) return log_error_errno(r, "Failed to change unit suffix: %m"); break; @@ -1328,7 +1361,7 @@ static int start_transient_timer( if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); - r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".timer", &timer); + r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, suffix, &trigger); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); @@ -1339,7 +1372,7 @@ static int start_transient_timer( if (r < 0) return r; - r = unit_name_change_suffix(service, ".timer", &timer); + r = unit_name_change_suffix(service, suffix, &trigger); if (r < 0) return log_error_errno(r, "Failed to change unit suffix: %m"); } @@ -1359,7 +1392,7 @@ static int start_transient_timer( return bus_log_create_error(r); /* Name and Mode */ - r = sd_bus_message_append(m, "ss", timer, "fail"); + r = sd_bus_message_append(m, "ss", trigger, "fail"); if (r < 0) return bus_log_create_error(r); @@ -1368,7 +1401,14 @@ static int start_transient_timer( if (r < 0) return bus_log_create_error(r); - r = transient_timer_set_properties(m); + if (streq(suffix, ".path")) + r = transient_unit_set_properties(m, UNIT_PATH, arg_path_property); + else if (streq(suffix, ".socket")) + r = transient_unit_set_properties(m, UNIT_SOCKET, arg_socket_property); + else if (streq(suffix, ".timer")) + r = transient_timer_set_properties(m); + else + assert_not_reached("Invalid suffix"); if (r < 0) return r; @@ -1414,7 +1454,7 @@ static int start_transient_timer( r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { - log_error("Failed to start transient timer unit: %s", bus_error_message(&error, -r)); + log_error("Failed to start transient %s unit: %s", suffix + 1, bus_error_message(&error, -r)); return r; } @@ -1427,7 +1467,7 @@ static int start_transient_timer( return r; if (!arg_quiet) { - log_info("Running timer as unit: %s", timer); + log_info("Running %s as unit: %s", suffix + 1, trigger); if (argv[0]) log_info("Will run service as unit: %s", service); } @@ -1488,14 +1528,20 @@ int main(int argc, char* argv[]) { if (arg_scope) r = start_transient_scope(bus, argv + optind); + else if (arg_path_property) + r = start_transient_trigger(bus, argv + optind, ".path"); + else if (arg_socket_property) + r = start_transient_trigger(bus, argv + optind, ".socket"); else if (with_timer) - r = start_transient_timer(bus, argv + optind); + r = start_transient_trigger(bus, argv + optind, ".timer"); else r = start_transient_service(bus, argv + optind, &retval); finish: strv_free(arg_environment); strv_free(arg_property); + strv_free(arg_path_property); + strv_free(arg_socket_property); strv_free(arg_timer_property); return r < 0 ? EXIT_FAILURE : retval; diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index 17928a9732..99d6a9b143 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -316,7 +316,7 @@ int ask_password_tty( } if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0) - flush_fd(notify); + (void) flush_fd(notify); if (pollfd[POLL_TTY].revents == 0) continue; @@ -656,7 +656,7 @@ int ask_password_agent( goto finish; } - if (strv_length(l) <= 0) { + if (strv_isempty(l)) { l = strv_free(l); log_debug("Invalid packet"); continue; diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c index c0a10417d8..9c3bdd47de 100644 --- a/src/shared/bootspec.c +++ b/src/shared/bootspec.c @@ -20,6 +20,8 @@ #include <stdio.h> #include <linux/magic.h> +#include "sd-id128.h" + #include "alloc-util.h" #include "blkid-util.h" #include "bootspec.h" @@ -52,22 +54,30 @@ void boot_entry_free(BootEntry *entry) { } int boot_entry_load(const char *path, BootEntry *entry) { + _cleanup_(boot_entry_free) BootEntry tmp = {}; _cleanup_fclose_ FILE *f = NULL; unsigned line = 1; - _cleanup_(boot_entry_free) BootEntry tmp = {}; + char *b, *c; int r; assert(path); assert(entry); - f = fopen(path, "re"); - if (!f) - return log_error_errno(errno, "Failed to open \"%s\": %m", path); + c = endswith_no_case(path, ".conf"); + if (!c) { + log_error("Invalid loader entry filename: %s", path); + return -EINVAL; + } - tmp.filename = strdup(basename(path)); + b = basename(path); + tmp.filename = strndup(b, c - b); if (!tmp.filename) return log_oom(); + f = fopen(path, "re"); + if (!f) + return log_error_errno(errno, "Failed to open \"%s\": %m", path); + for (;;) { _cleanup_free_ char *buf = NULL; char *p; @@ -195,67 +205,8 @@ int boot_loader_read_conf(const char *path, BootConfig *config) { return 0; } -/* This is a direct translation of str_verscmp from boot.c */ -static bool is_digit(int c) { - return c >= '0' && c <= '9'; -} - -static int c_order(int c) { - if (c == '\0') - return 0; - if (is_digit(c)) - return 0; - else if ((c >= 'a') && (c <= 'z')) - return c; - else - return c + 0x10000; -} - -static int str_verscmp(const char *s1, const char *s2) { - const char *os1 = s1; - const char *os2 = s2; - - while (*s1 || *s2) { - int first; - - while ((*s1 && !is_digit(*s1)) || (*s2 && !is_digit(*s2))) { - int order; - - order = c_order(*s1) - c_order(*s2); - if (order) - return order; - s1++; - s2++; - } - - while (*s1 == '0') - s1++; - while (*s2 == '0') - s2++; - - first = 0; - while (is_digit(*s1) && is_digit(*s2)) { - if (first == 0) - first = *s1 - *s2; - s1++; - s2++; - } - - if (is_digit(*s1)) - return 1; - if (is_digit(*s2)) - return -1; - - if (first != 0) - return first; - } - - return strcmp(os1, os2); -} - static int boot_entry_compare(const void *a, const void *b) { - const BootEntry *aa = a; - const BootEntry *bb = b; + const BootEntry *aa = a, *bb = b; return str_verscmp(aa->filename, bb->filename); } diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index b58abed2b5..bc77c3abdb 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -24,6 +24,7 @@ #include "bus-util.h" #include "cap-list.h" #include "cgroup-util.h" +#include "condition.h" #include "cpu-set-util.h" #include "env-util.h" #include "errno-list.h" @@ -42,9 +43,11 @@ #include "rlimit-util.h" #include "securebits-util.h" #include "signal-util.h" +#include "socket-protocol-list.h" #include "string-util.h" #include "syslog-util.h" #include "terminal-util.h" +#include "unit-def.h" #include "user-util.h" #include "utf8.h" #include "util.h" @@ -70,478 +73,456 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) { &u->job_path); } -static int bus_append_ip_address_access(sd_bus_message *m, int family, const union in_addr_union *prefix, unsigned char prefixlen) { +#define DEFINE_BUS_APPEND_PARSE_PTR(bus_type, cast_type, type, parse_func) \ + static int bus_append_##parse_func( \ + sd_bus_message *m, \ + const char *field, \ + const char *eq) { \ + type val; \ + int r; \ + \ + r = parse_func(eq, &val); \ + if (r < 0) \ + return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq); \ + \ + r = sd_bus_message_append(m, "(sv)", field, \ + bus_type, (cast_type) val); \ + if (r < 0) \ + return bus_log_create_error(r); \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define DEFINE_BUS_APPEND_PARSE(bus_type, parse_func) \ + static int bus_append_##parse_func( \ + sd_bus_message *m, \ + const char *field, \ + const char *eq) { \ + int r; \ + \ + r = parse_func(eq); \ + if (r < 0) { \ + log_error("Failed to parse %s: %s", field, eq); \ + return -EINVAL; \ + } \ + \ + r = sd_bus_message_append(m, "(sv)", field, \ + bus_type, (int32_t) r); \ + if (r < 0) \ + return bus_log_create_error(r); \ + \ + return 1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +DEFINE_BUS_APPEND_PARSE("b", parse_boolean); +DEFINE_BUS_APPEND_PARSE("i", ioprio_class_from_string); +DEFINE_BUS_APPEND_PARSE("i", ip_tos_from_string); +DEFINE_BUS_APPEND_PARSE("i", log_facility_unshifted_from_string); +DEFINE_BUS_APPEND_PARSE("i", log_level_from_string); +DEFINE_BUS_APPEND_PARSE("i", parse_errno); +DEFINE_BUS_APPEND_PARSE("i", sched_policy_from_string); +DEFINE_BUS_APPEND_PARSE("i", secure_bits_from_string); +DEFINE_BUS_APPEND_PARSE("i", signal_from_string_try_harder); +DEFINE_BUS_APPEND_PARSE("i", socket_protocol_from_name); +DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, ioprio_parse_priority); +DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, parse_nice); +DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, safe_atoi); +DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, nsec_t, parse_nsec); +DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_blkio_weight_parse); +DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_shares_parse); +DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_weight_parse); +DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, unsigned long, mount_propagation_flags_from_string); +DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64); +DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode); +DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou); +DEFINE_BUS_APPEND_PARSE_PTR("x", int64_t, int64_t, safe_atoi64); + +static inline int bus_append_string(sd_bus_message *m, const char *field, const char *eq) { int r; - assert(m); - assert(prefix); - - r = sd_bus_message_open_container(m, 'r', "iayu"); + r = sd_bus_message_append(m, "(sv)", field, "s", eq); if (r < 0) - return r; + return bus_log_create_error(r); - r = sd_bus_message_append(m, "i", family); + return 1; +} + +static int bus_append_strv(sd_bus_message *m, const char *field, const char *eq, ExtractFlags flags) { + const char *p; + int r; + + r = sd_bus_message_open_container(m, 'r', "sv"); if (r < 0) - return r; + return bus_log_create_error(r); - r = sd_bus_message_append_array(m, 'y', prefix, FAMILY_ADDRESS_SIZE(family)); + r = sd_bus_message_append_basic(m, 's', field); if (r < 0) - return r; + return bus_log_create_error(r); - r = sd_bus_message_append(m, "u", prefixlen); + r = sd_bus_message_open_container(m, 'v', "as"); if (r < 0) - return r; + return bus_log_create_error(r); - return sd_bus_message_close_container(m); -} + r = sd_bus_message_open_container(m, 'a', "s"); + if (r < 0) + return bus_log_create_error(r); -int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) { - const char *eq, *field; - UnitDependency dep; - int r, rl; + for (p = eq;;) { + _cleanup_free_ char *word = NULL; - assert(m); - assert(assignment); + r = extract_first_word(&p, &word, NULL, flags); + if (r == 0) + break; + if (r == -ENOMEM) + return log_oom(); + if (r < 0) + return log_error_errno(r, "Invalid syntax: %s", eq); - eq = strchr(assignment, '='); - if (!eq) { - log_error("Not an assignment: %s", assignment); - return -EINVAL; + r = sd_bus_message_append_basic(m, 's', word); + if (r < 0) + return bus_log_create_error(r); } - r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); + r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); - field = strndupa(assignment, eq - assignment); - eq++; + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - if (streq(field, "CPUQuota")) { + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - if (isempty(eq)) - r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", USEC_INFINITY); - else { - r = parse_percent_unbounded(eq); - if (r <= 0) { - log_error_errno(r, "CPU quota '%s' invalid.", eq); - return -EINVAL; - } + return 1; +} - r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC / 100U); - } +static int bus_append_byte_array(sd_bus_message *m, const char *field, const void *buf, size_t n) { + int r; - goto finish; + r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); + if (r < 0) + return bus_log_create_error(r); - } else if (streq(field, "EnvironmentFile")) { + r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); + if (r < 0) + return bus_log_create_error(r); - if (isempty(eq)) - r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 0); - else - r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 1, - eq[0] == '-' ? eq + 1 : eq, - eq[0] == '-'); - goto finish; + r = sd_bus_message_open_container(m, 'v', "ay"); + if (r < 0) + return bus_log_create_error(r); - } else if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec", "RuntimeMaxSec")) { - char *n; - usec_t t; - size_t l; + r = sd_bus_message_append_array(m, 'y', buf, n); + if (r < 0) + return bus_log_create_error(r); - r = parse_sec(eq, &t); - if (r < 0) - return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq); + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - l = strlen(field); - n = newa(char, l + 2); - if (!n) - return log_oom(); + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - /* Change suffix Sec → USec */ - strcpy(mempcpy(n, field, l - 3), "USec"); - r = sd_bus_message_append(m, "sv", n, "t", t); - goto finish; + return 1; +} - } else if (streq(field, "LogExtraFields")) { +static int bus_append_parse_sec_rename(sd_bus_message *m, const char *field, const char *eq) { + char *n; + usec_t t; + size_t l; + int r; - r = sd_bus_message_append(m, "s", "LogExtraFields"); - if (r < 0) - goto finish; + r = parse_sec(eq, &t); + if (r < 0) + return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq); - r = sd_bus_message_open_container(m, 'v', "aay"); - if (r < 0) - goto finish; + l = strlen(field); + n = newa(char, l + 2); + /* Change suffix Sec → USec */ + strcpy(mempcpy(n, field, l - 3), "USec"); - r = sd_bus_message_open_container(m, 'a', "ay"); - if (r < 0) - goto finish; + r = sd_bus_message_append(m, "(sv)", n, "t", t); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_append_array(m, 'y', eq, strlen(eq)); - if (r < 0) - goto finish; + return 1; +} - r = sd_bus_message_close_container(m); - if (r < 0) - goto finish; +static int bus_append_parse_size(sd_bus_message *m, const char *field, const char *eq, uint64_t base) { + uint64_t v; + int r; - r = sd_bus_message_close_container(m); - goto finish; + r = parse_size(eq, base, &v); + if (r < 0) + return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq); - } else if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit")) { - uint64_t bytes; + r = sd_bus_message_append(m, "(sv)", field, "t", v); + if (r < 0) + return bus_log_create_error(r); - if (isempty(eq) || streq(eq, "infinity")) - bytes = CGROUP_LIMIT_MAX; - else { - r = parse_percent(eq); - if (r >= 0) { - char *n; + return 1; +} - /* When this is a percentage we'll convert this into a relative value in the range - * 0…UINT32_MAX and pass it in the MemoryLowScale property (and related - * ones). This way the physical memory size can be determined server-side */ +static int bus_append_exec_command(sd_bus_message *m, const char *field, const char *eq) { + bool ignore_failure = false, explicit_path = false, done = false; + _cleanup_strv_free_ char **l = NULL; + _cleanup_free_ char *path = NULL; + int r; - n = strjoina(field, "Scale"); - r = sd_bus_message_append(m, "sv", n, "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U)); - goto finish; + do { + switch (*eq) { - } else { - r = parse_size(eq, 1024, &bytes); - if (r < 0) - return log_error_errno(r, "Failed to parse bytes specification %s", assignment); + case '-': + if (ignore_failure) + done = true; + else { + ignore_failure = true; + eq++; } - } - - r = sd_bus_message_append(m, "sv", field, "t", bytes); - goto finish; - - } else if (streq(field, "Delegate")) { - - r = parse_boolean(eq); - if (r < 0) { - const char *p = eq; - - r = sd_bus_message_append(m, "s", "DelegateControllers"); - if (r < 0) - goto finish; - - r = sd_bus_message_open_container(m, 'v', "as"); - if (r < 0) - goto finish; - - r = sd_bus_message_open_container(m, 'a', "s"); - if (r < 0) - goto finish; - - for (;;) { - _cleanup_free_ char *word = NULL; - - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); - if (r == 0) - break; - if (r == -ENOMEM) - return log_oom(); - if (r < 0) - return log_error_errno(r, "Invalid syntax: %s", eq); + break; - r = sd_bus_message_append(m, "s", word); - if (r < 0) - goto finish; + case '@': + if (explicit_path) + done = true; + else { + explicit_path = true; + eq++; } + break; - r = sd_bus_message_close_container(m); - if (r < 0) - goto finish; - - r = sd_bus_message_close_container(m); - } else - r = sd_bus_message_append(m, "sv", "Delegate", "b", r); - - goto finish; - - } else if (streq(field, "TasksMax")) { - uint64_t t; - - if (isempty(eq) || streq(eq, "infinity")) - t = (uint64_t) -1; - else { - r = parse_percent(eq); - if (r >= 0) { - r = sd_bus_message_append(m, "sv", "TasksMaxScale", "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U)); - goto finish; - } else { - r = safe_atou64(eq, &t); - if (r < 0) - return log_error_errno(r, "Failed to parse maximum tasks specification %s", assignment); - } + case '+': + case '!': + /* The bus API doesn't support +, ! and !! currently, unfortunately. :-( */ + log_error("Sorry, but +, ! and !! are currently not supported for transient services."); + return -EOPNOTSUPP; + default: + done = true; + break; } + } while (!done); - r = sd_bus_message_append(m, "sv", "TasksMax", "t", t); - goto finish; - - } else if (STR_IN_SET(field, "StandardInput", "StandardOutput", "StandardError")) { - const char *n, *appended; + if (explicit_path) { + r = extract_first_word(&eq, &path, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE); + if (r < 0) + return log_error_errno(r, "Failed to parse path: %m"); + } - n = startswith(eq, "fd:"); - if (n) { - appended = strjoina(field, "FileDescriptorName"); - r = sd_bus_message_append(m, "sv", appended, "s", n); + r = strv_split_extract(&l, eq, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE); + if (r < 0) + return log_error_errno(r, "Failed to parse command line: %m"); - } else if ((n = startswith(eq, "file:"))) { - appended = strjoina(field, "File"); - r = sd_bus_message_append(m, "sv", appended, "s", n); - } else - r = sd_bus_message_append(m, "sv", field, "s", eq); + r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); + if (r < 0) + return bus_log_create_error(r); - goto finish; + r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); + if (r < 0) + return bus_log_create_error(r); - } else if (streq(field, "StandardInputText")) { - _cleanup_free_ char *unescaped = NULL; + r = sd_bus_message_open_container(m, 'v', "a(sasb)"); + if (r < 0) + return bus_log_create_error(r); - r = cunescape(eq, 0, &unescaped); - if (r < 0) - return log_error_errno(r, "Failed to unescape text '%s': %m", eq); + r = sd_bus_message_open_container(m, 'a', "(sasb)"); + if (r < 0) + return bus_log_create_error(r); - if (!strextend(&unescaped, "\n", NULL)) - return log_oom(); + if (!strv_isempty(l)) { - /* Note that we don't expand specifiers here, but that should be OK, as this is a programmatic - * interface anyway */ + r = sd_bus_message_open_container(m, 'r', "sasb"); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_append(m, "s", "StandardInputData"); + r = sd_bus_message_append(m, "s", path ?: l[0]); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_open_container(m, 'v', "ay"); + r = sd_bus_message_append_strv(m, l); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append_array(m, 'y', unescaped, strlen(unescaped)); + r = sd_bus_message_append(m, "b", ignore_failure); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_close_container(m); - goto finish; + if (r < 0) + return bus_log_create_error(r); } - r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); + r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); - rl = rlimit_from_string(field); - if (rl >= 0) { - const char *sn; - struct rlimit l; - - r = rlimit_parse(rl, eq, &l); - if (r < 0) - return log_error_errno(r, "Failed to parse resource limit: %s", eq); - - r = sd_bus_message_append(m, "v", "t", l.rlim_max); - if (r < 0) - return bus_log_create_error(r); + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_close_container(m); - if (r < 0) - return bus_log_create_error(r); + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); - if (r < 0) - return bus_log_create_error(r); + return 1; +} - sn = strjoina(field, "Soft"); - r = sd_bus_message_append(m, "sv", sn, "t", l.rlim_cur); - - } else if (STR_IN_SET(field, - "CPUAccounting", "MemoryAccounting", "IOAccounting", "BlockIOAccounting", - "TasksAccounting", "IPAccounting", "SendSIGHUP", "SendSIGKILL", "WakeSystem", - "DefaultDependencies", "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate", - "RemainAfterExit", "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers", - "NoNewPrivileges", "SyslogLevelPrefix", "RemainAfterElapse", "Persistent", - "MemoryDenyWriteExecute", "RestrictRealtime", "DynamicUser", "RemoveIPC", - "ProtectKernelTunables", "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS", - "CPUSchedulingResetOnFork", "LockPersonality")) { +static int bus_append_ip_address_access(sd_bus_message *m, int family, const union in_addr_union *prefix, unsigned char prefixlen) { + int r; - r = parse_boolean(eq); - if (r < 0) - return log_error_errno(r, "Failed to parse boolean assignment %s.", assignment); + assert(m); + assert(prefix); - r = sd_bus_message_append(m, "v", "b", r); + r = sd_bus_message_open_container(m, 'r', "iayu"); + if (r < 0) + return r; - } else if (STR_IN_SET(field, "CPUWeight", "StartupCPUWeight")) { - uint64_t u; + r = sd_bus_message_append(m, "i", family); + if (r < 0) + return r; - r = cg_weight_parse(eq, &u); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); + r = sd_bus_message_append_array(m, 'y', prefix, FAMILY_ADDRESS_SIZE(family)); + if (r < 0) + return r; - r = sd_bus_message_append(m, "v", "t", u); + r = sd_bus_message_append(m, "u", prefixlen); + if (r < 0) + return r; - } else if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")) { - uint64_t u; + return sd_bus_message_close_container(m); +} - r = cg_cpu_shares_parse(eq, &u); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); +static int bus_append_cgroup_property(sd_bus_message *m, const char *field, const char *eq) { + int r; - r = sd_bus_message_append(m, "v", "t", u); + if (STR_IN_SET(field, "DevicePolicy", "Slice")) - } else if (STR_IN_SET(field, "IOWeight", "StartupIOWeight")) { - uint64_t u; + return bus_append_string(m, field, eq); - r = cg_weight_parse(eq, &u); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); + if (STR_IN_SET(field, + "CPUAccounting", "MemoryAccounting", "IOAccounting", "BlockIOAccounting", + "TasksAccounting", "IPAccounting")) - r = sd_bus_message_append(m, "v", "t", u); + return bus_append_parse_boolean(m, field, eq); - } else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) { - uint64_t u; + if (STR_IN_SET(field, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight")) - r = cg_blkio_weight_parse(eq, &u); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); + return bus_append_cg_weight_parse(m, field, eq); - r = sd_bus_message_append(m, "v", "t", u); + if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")) - } else if (STR_IN_SET(field, - "User", "Group", "DevicePolicy", "KillMode", - "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath", - "Description", "Slice", "Type", "WorkingDirectory", - "RootDirectory", "SyslogIdentifier", "ProtectSystem", - "ProtectHome", "SELinuxContext", "Restart", "RootImage", - "NotifyAccess", "RuntimeDirectoryPreserve", "Personality", - "KeyringMode", "CollectMode", "FailureAction", "SuccessAction", - "OnCalendar")) + return bus_append_cg_cpu_shares_parse(m, field, eq); - r = sd_bus_message_append(m, "v", "s", eq); + if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) - else if (streq(field, "StandardInputData")) { - _cleanup_free_ void *decoded = NULL; - size_t sz; + return bus_append_cg_blkio_weight_parse(m, field, eq); - r = unbase64mem(eq, (size_t) -1, &decoded, &sz); - if (r < 0) - return log_error_errno(r, "Failed to decode base64 data '%s': %m", eq); + if (streq(field, "Delegate")) { - r = sd_bus_message_open_container(m, 'v', "ay"); + r = parse_boolean(eq); if (r < 0) - return bus_log_create_error(r); + return bus_append_strv(m, "DelegateControllers", eq, EXTRACT_QUOTES); - r = sd_bus_message_append_array(m, 'y', decoded, sz); + r = sd_bus_message_append(m, "(sv)", "Delegate", "b", r); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_close_container(m); + return 1; + } - } else if (STR_IN_SET(field, "AppArmorProfile", "SmackProcessLabel")) { - bool ignore; - const char *s; + if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) { - if (eq[0] == '-') { - ignore = true; - s = eq + 1; - } else { - ignore = false; - s = eq; + if (isempty(eq) || streq(eq, "infinity")) { + r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX); + if (r < 0) + return bus_log_create_error(r); + return 1; } - r = sd_bus_message_append(m, "v", "(bs)", ignore, s); - - } else if (STR_IN_SET(field, "SyslogLevel", "LogLevelMax")) { - int level; + r = parse_percent(eq); + if (r >= 0) { + char *n; - level = log_level_from_string(eq); - if (level < 0) { - log_error("Failed to parse %s value %s.", field, eq); - return -EINVAL; - } + /* When this is a percentage we'll convert this into a relative value in the range + * 0…UINT32_MAX and pass it in the MemoryLowScale property (and related + * ones). This way the physical memory size can be determined server-side */ - r = sd_bus_message_append(m, "v", "i", level); - - } else if (streq(field, "SyslogFacility")) { - int facility; + n = strjoina(field, "Scale"); + r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U)); + if (r < 0) + return bus_log_create_error(r); - facility = log_facility_unshifted_from_string(eq); - if (facility < 0) { - log_error("Failed to parse %s value %s.", field, eq); - return -EINVAL; + return 1; } - r = sd_bus_message_append(m, "v", "i", facility); + if (streq(field, "TasksMax")) + return bus_append_safe_atou64(m, field, eq); - } else if (streq(field, "SecureBits")) { + return bus_append_parse_size(m, field, eq, 1024); - r = secure_bits_from_string(eq); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); + } - r = sd_bus_message_append(m, "v", "i", r); + if (streq(field, "CPUQuota")) { - } else if (STR_IN_SET(field, "CapabilityBoundingSet", "AmbientCapabilities")) { - uint64_t sum = 0; - bool invert = false; - const char *p; + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", USEC_INFINITY); + else { + r = parse_percent_unbounded(eq); + if (r <= 0) { + log_error_errno(r, "CPU quota '%s' invalid.", eq); + return -EINVAL; + } - p = eq; - if (*p == '~') { - invert = true; - p++; + r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC / 100U); } - r = capability_set_from_string(p, &sum); if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); - - sum = invert ? ~sum : sum; + return bus_log_create_error(r); - r = sd_bus_message_append(m, "v", "t", sum); + return 1; + } - } else if (streq(field, "DeviceAllow")) { + if (streq(field, "DeviceAllow")) { if (isempty(eq)) - r = sd_bus_message_append(m, "v", "a(ss)", 0); + r = sd_bus_message_append(m, "(sv)", field, "a(ss)", 0); else { - const char *path, *rwm, *e; + const char *path = eq, *rwm = NULL, *e; e = strchr(eq, ' '); if (e) { path = strndupa(eq, e - eq); rwm = e+1; - } else { - path = eq; - rwm = ""; - } - - if (!is_deviceallow_pattern(path)) { - log_error("%s is not a device file in /dev.", path); - return -EINVAL; } - r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm); + r = sd_bus_message_append(m, "(sv)", field, "a(ss)", 1, path, strempty(rwm)); } - } else if (cgroup_io_limit_type_from_string(field) >= 0 || STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) { + if (r < 0) + return bus_log_create_error(r); + + return 1; + } + + if (cgroup_io_limit_type_from_string(field) >= 0 || STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) { if (isempty(eq)) - r = sd_bus_message_append(m, "v", "a(st)", 0); + r = sd_bus_message_append(m, "(sv)", field, "a(st)", 0); else { const char *path, *bandwidth, *e; uint64_t bytes; e = strchr(eq, ' '); - if (e) { - path = strndupa(eq, e - eq); - bandwidth = e+1; - } else { + if (!e) { log_error("Failed to parse %s value %s.", field, eq); return -EINVAL; } - if (!path_startswith(path, "/dev")) { - log_error("%s is not a device file in /dev.", path); - return -EINVAL; - } + path = strndupa(eq, e - eq); + bandwidth = e+1; if (streq(bandwidth, "infinity")) { bytes = CGROUP_LIMIT_MAX; @@ -551,315 +532,290 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen return log_error_errno(r, "Failed to parse byte value %s: %m", bandwidth); } - r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes); + r = sd_bus_message_append(m, "(sv)", field, "a(st)", 1, path, bytes); } - } else if (STR_IN_SET(field, "IODeviceWeight", "BlockIODeviceWeight")) { + if (r < 0) + return bus_log_create_error(r); + + return 1; + } + + if (STR_IN_SET(field, "IODeviceWeight", "BlockIODeviceWeight")) { if (isempty(eq)) - r = sd_bus_message_append(m, "v", "a(st)", 0); + r = sd_bus_message_append(m, "(sv)", field, "a(st)", 0); else { const char *path, *weight, *e; uint64_t u; e = strchr(eq, ' '); - if (e) { - path = strndupa(eq, e - eq); - weight = e+1; - } else { + if (!e) { log_error("Failed to parse %s value %s.", field, eq); return -EINVAL; } - if (!path_startswith(path, "/dev")) { - log_error("%s is not a device file in /dev.", path); - return -EINVAL; - } + path = strndupa(eq, e - eq); + weight = e+1; r = safe_atou64(weight, &u); if (r < 0) return log_error_errno(r, "Failed to parse %s value %s: %m", field, weight); - r = sd_bus_message_append(m, "v", "a(st)", 1, path, u); + r = sd_bus_message_append(m, "(sv)", field, "a(st)", 1, path, u); } - } else if (STR_IN_SET(field, "IPAddressAllow", "IPAddressDeny")) { + if (r < 0) + return bus_log_create_error(r); - if (isempty(eq)) - r = sd_bus_message_append(m, "v", "a(iayu)", 0); - else { - unsigned char prefixlen; - union in_addr_union prefix = {}; - int family; + return 1; + } - r = sd_bus_message_open_container(m, 'v', "a(iayu)"); - if (r < 0) - return bus_log_create_error(r); + if (STR_IN_SET(field, "IPAddressAllow", "IPAddressDeny")) { + unsigned char prefixlen; + union in_addr_union prefix = {}; + int family; - r = sd_bus_message_open_container(m, 'a', "(iayu)"); + if (isempty(eq)) { + r = sd_bus_message_append(m, "(sv)", field, "a(iayu)", 0); if (r < 0) return bus_log_create_error(r); - if (streq(eq, "any")) { - /* "any" is a shortcut for 0.0.0.0/0 and ::/0 */ + return 1; + } - r = bus_append_ip_address_access(m, AF_INET, &prefix, 0); - if (r < 0) - return bus_log_create_error(r); + r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); + if (r < 0) + return bus_log_create_error(r); - r = bus_append_ip_address_access(m, AF_INET6, &prefix, 0); - if (r < 0) - return bus_log_create_error(r); + r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); + if (r < 0) + return bus_log_create_error(r); - } else if (is_localhost(eq)) { - /* "localhost" is a shortcut for 127.0.0.0/8 and ::1/128 */ + r = sd_bus_message_open_container(m, 'v', "a(iayu)"); + if (r < 0) + return bus_log_create_error(r); - prefix.in.s_addr = htobe32(0x7f000000); - r = bus_append_ip_address_access(m, AF_INET, &prefix, 8); - if (r < 0) - return bus_log_create_error(r); + r = sd_bus_message_open_container(m, 'a', "(iayu)"); + if (r < 0) + return bus_log_create_error(r); - prefix.in6 = (struct in6_addr) IN6ADDR_LOOPBACK_INIT; - r = bus_append_ip_address_access(m, AF_INET6, &prefix, 128); - if (r < 0) - return r; + if (streq(eq, "any")) { + /* "any" is a shortcut for 0.0.0.0/0 and ::/0 */ - } else if (streq(eq, "link-local")) { + r = bus_append_ip_address_access(m, AF_INET, &prefix, 0); + if (r < 0) + return bus_log_create_error(r); - /* "link-local" is a shortcut for 169.254.0.0/16 and fe80::/64 */ + r = bus_append_ip_address_access(m, AF_INET6, &prefix, 0); + if (r < 0) + return bus_log_create_error(r); - prefix.in.s_addr = htobe32((UINT32_C(169) << 24 | UINT32_C(254) << 16)); - r = bus_append_ip_address_access(m, AF_INET, &prefix, 16); - if (r < 0) - return bus_log_create_error(r); + } else if (is_localhost(eq)) { + /* "localhost" is a shortcut for 127.0.0.0/8 and ::1/128 */ - prefix.in6 = (struct in6_addr) { - .s6_addr32[0] = htobe32(0xfe800000) - }; - r = bus_append_ip_address_access(m, AF_INET6, &prefix, 64); - if (r < 0) - return bus_log_create_error(r); + prefix.in.s_addr = htobe32(0x7f000000); + r = bus_append_ip_address_access(m, AF_INET, &prefix, 8); + if (r < 0) + return bus_log_create_error(r); - } else if (streq(eq, "multicast")) { + prefix.in6 = (struct in6_addr) IN6ADDR_LOOPBACK_INIT; + r = bus_append_ip_address_access(m, AF_INET6, &prefix, 128); + if (r < 0) + return r; - /* "multicast" is a shortcut for 224.0.0.0/4 and ff00::/8 */ + } else if (streq(eq, "link-local")) { + /* "link-local" is a shortcut for 169.254.0.0/16 and fe80::/64 */ - prefix.in.s_addr = htobe32((UINT32_C(224) << 24)); - r = bus_append_ip_address_access(m, AF_INET, &prefix, 4); - if (r < 0) - return bus_log_create_error(r); + prefix.in.s_addr = htobe32((UINT32_C(169) << 24 | UINT32_C(254) << 16)); + r = bus_append_ip_address_access(m, AF_INET, &prefix, 16); + if (r < 0) + return bus_log_create_error(r); - prefix.in6 = (struct in6_addr) { - .s6_addr32[0] = htobe32(0xff000000) - }; - r = bus_append_ip_address_access(m, AF_INET6, &prefix, 8); - if (r < 0) - return bus_log_create_error(r); + prefix.in6 = (struct in6_addr) { + .s6_addr32[0] = htobe32(0xfe800000) + }; + r = bus_append_ip_address_access(m, AF_INET6, &prefix, 64); + if (r < 0) + return bus_log_create_error(r); - } else { - r = in_addr_prefix_from_string_auto(eq, &family, &prefix, &prefixlen); - if (r < 0) - return log_error_errno(r, "Failed to parse IP address prefix: %s", eq); + } else if (streq(eq, "multicast")) { + /* "multicast" is a shortcut for 224.0.0.0/4 and ff00::/8 */ - r = bus_append_ip_address_access(m, family, &prefix, prefixlen); - if (r < 0) - return bus_log_create_error(r); - } + prefix.in.s_addr = htobe32((UINT32_C(224) << 24)); + r = bus_append_ip_address_access(m, AF_INET, &prefix, 4); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_close_container(m); + prefix.in6 = (struct in6_addr) { + .s6_addr32[0] = htobe32(0xff000000) + }; + r = bus_append_ip_address_access(m, AF_INET6, &prefix, 8); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_close_container(m); + } else { + r = in_addr_prefix_from_string_auto(eq, &family, &prefix, &prefixlen); + if (r < 0) + return log_error_errno(r, "Failed to parse IP address prefix: %s", eq); + + r = bus_append_ip_address_access(m, family, &prefix, prefixlen); if (r < 0) return bus_log_create_error(r); } - } else if (streq(field, "CPUSchedulingPolicy")) { - int n; + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - n = sched_policy_from_string(eq); - if (n < 0) - return log_error_errno(r, "Failed to parse CPUSchedulingPolicy: %s", eq); + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_append(m, "v", "i", (int32_t) n); + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - } else if (streq(field, "CPUSchedulingPriority")) { - int n; + return 1; + } - r = safe_atoi(eq, &n); - if (r < 0) - return log_error_errno(r, "Failed to parse CPUSchedulingPriority: %s", eq); - if (!sched_priority_is_valid(n)) - return log_error_errno(r, "Invalid CPUSchedulingPriority: %s", eq); + return 0; +} - r = sd_bus_message_append(m, "v", "i", (int32_t) n); +static int bus_append_automount_property(sd_bus_message *m, const char *field, const char *eq) { - } else if (streq(field, "CPUAffinity")) { - _cleanup_cpu_free_ cpu_set_t *cpuset = NULL; - int ncpus; + if (streq(field, "Where")) - ncpus = parse_cpu_set(eq, &cpuset); - if (ncpus < 0) - return log_error_errno(r, "Failed to parse %s value: %s", field, eq); + return bus_append_string(m, field, eq); - r = sd_bus_message_open_container(m, 'v', "ay"); - if (r < 0) - return bus_log_create_error(r); + if (streq(field, "DirectoryMode")) - r = sd_bus_message_append_array(m, 'y', cpuset, CPU_ALLOC_SIZE(ncpus)); - if (r < 0) - return bus_log_create_error(r); + return bus_append_parse_mode(m, field, eq); - r = sd_bus_message_close_container(m); + if (streq(field, "TimeoutIdleSec")) - } else if (streq(field, "Nice")) { - int n; + return bus_append_parse_sec_rename(m, field, eq); - r = parse_nice(eq, &n); - if (r < 0) - return log_error_errno(r, "Failed to parse nice value: %s", eq); + return 0; +} - r = sd_bus_message_append(m, "v", "i", (int32_t) n); +static int bus_append_execute_property(sd_bus_message *m, const char *field, const char *eq) { + int r, rl; - } else if (streq(field, "SystemCallFilter")) { - int whitelist; - _cleanup_strv_free_ char **l = NULL; - const char *p; + if (STR_IN_SET(field, + "User", "Group", + "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath", + "WorkingDirectory", "RootDirectory", "SyslogIdentifier", + "ProtectSystem", "ProtectHome", "SELinuxContext", "RootImage", + "RuntimeDirectoryPreserve", "Personality", "KeyringMode")) - p = eq; - if (*p == '~') { - whitelist = 0; - p++; - } else - whitelist = 1; + return bus_append_string(m, field, eq); - if (whitelist != 0) { - r = strv_extend(&l, "@default"); - if (r < 0) - return log_oom(); - } + if (STR_IN_SET(field, + "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate", + "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers", + "NoNewPrivileges", "SyslogLevelPrefix", + "MemoryDenyWriteExecute", "RestrictRealtime", "DynamicUser", "RemoveIPC", + "ProtectKernelTunables", "ProtectKernelModules", "ProtectControlGroups", + "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality")) - for (;;) { - _cleanup_free_ char *word = NULL; + return bus_append_parse_boolean(m, field, eq); - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value: %s", field, eq); - if (r == 0) - break; + if (STR_IN_SET(field, + "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories", + "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths", + "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory", + "SupplementaryGroups", "SystemCallArchitectures")) - r = strv_extend(&l, word); - if (r < 0) - return log_oom(); - } + return bus_append_strv(m, field, eq, EXTRACT_QUOTES); - r = sd_bus_message_open_container(m, 'v', "(bas)"); - if (r < 0) - return bus_log_create_error(r); + if (STR_IN_SET(field, "SyslogLevel", "LogLevelMax")) - r = sd_bus_message_open_container(m, 'r', "bas"); - if (r < 0) - return bus_log_create_error(r); + return bus_append_log_level_from_string(m, field, eq); - r = sd_bus_message_append_basic(m, 'b', &whitelist); - if (r < 0) - return bus_log_create_error(r); + if (streq(field, "SyslogFacility")) - r = sd_bus_message_append_strv(m, l); - if (r < 0) - return bus_log_create_error(r); + return bus_append_log_facility_unshifted_from_string(m, field, eq); - r = sd_bus_message_close_container(m); - if (r < 0) - return bus_log_create_error(r); + if (streq(field, "SecureBits")) - r = sd_bus_message_close_container(m); - if (r < 0) - return bus_log_create_error(r); + return bus_append_secure_bits_from_string(m, field, eq); - } else if (streq(field, "SystemCallArchitectures")) { - const char *p; + if (streq(field, "CPUSchedulingPolicy")) - r = sd_bus_message_open_container(m, 'v', "as"); - if (r < 0) - return bus_log_create_error(r); + return bus_append_sched_policy_from_string(m, field, eq); - r = sd_bus_message_open_container(m, 'a', "s"); - if (r < 0) - return bus_log_create_error(r); + if (STR_IN_SET(field, "CPUSchedulingPriority", "OOMScoreAdjust")) - for (p = eq;;) { - _cleanup_free_ char *word = NULL; + return bus_append_safe_atoi(m, field, eq); - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value: %s", field, eq); - if (r == 0) - break; + if (streq(field, "Nice")) - r = sd_bus_message_append_basic(m, 's', word); - if (r < 0) - return bus_log_create_error(r); - } + return bus_append_parse_nice(m, field, eq); - r = sd_bus_message_close_container(m); - if (r < 0) - return bus_log_create_error(r); + if (streq(field, "SystemCallErrorNumber")) - r = sd_bus_message_close_container(m); + return bus_append_parse_errno(m, field, eq); - } else if (streq(field, "SystemCallErrorNumber")) { - int n; + if (streq(field, "IOSchedulingClass")) - n = parse_errno(eq); - if (n <= 0) - return log_error_errno(r, "Failed to parse %s value: %s", field, eq); + return bus_append_ioprio_class_from_string(m, field, eq); - r = sd_bus_message_append(m, "v", "i", (int32_t) n); + if (streq(field, "IOSchedulingPriority")) - } else if (streq(field, "RestrictAddressFamilies")) { - int whitelist; - _cleanup_strv_free_ char **l = NULL; - const char *p = eq; + return bus_append_ioprio_parse_priority(m, field, eq); - if (*p == '~') { - whitelist = 0; - p++; - } else - whitelist = 1; + if (STR_IN_SET(field, + "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", + "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")) - for (;;) { - _cleanup_free_ char *word = NULL; + return bus_append_parse_mode(m, field, eq); - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value: %s", field, eq); - if (r == 0) - break; + if (streq(field, "TimerSlackNSec")) - r = strv_extend(&l, word); - if (r < 0) - return log_oom(); - } + return bus_append_parse_nsec(m, field, eq); - r = sd_bus_message_open_container(m, 'v', "(bas)"); + if (streq(field, "MountFlags")) + + return bus_append_mount_propagation_flags_from_string(m, field, eq); + + if (STR_IN_SET(field, "Environment", "UnsetEnvironment", "PassEnvironment")) + + return bus_append_strv(m, field, eq, EXTRACT_QUOTES|EXTRACT_CUNESCAPE); + + if (streq(field, "EnvironmentFile")) { + + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", "EnvironmentFiles", "a(sb)", 0); + else + r = sd_bus_message_append(m, "(sv)", "EnvironmentFiles", "a(sb)", 1, + eq[0] == '-' ? eq + 1 : eq, + eq[0] == '-'); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_open_container(m, 'r', "bas"); + return 1; + } + + if (streq(field, "LogExtraFields")) { + + r = sd_bus_message_open_container(m, 'r', "sv"); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append_basic(m, 'b', &whitelist); + r = sd_bus_message_append_basic(m, 's', "LogExtraFields"); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append_strv(m, l); + r = sd_bus_message_open_container(m, 'v', "aay"); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_close_container(m); + r = sd_bus_message_open_container(m, 'a', "ay"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append_array(m, 'y', eq, strlen(eq)); if (r < 0) return bus_log_create_error(r); @@ -867,165 +823,158 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen if (r < 0) return bus_log_create_error(r); - } else if (streq(field, "FileDescriptorStoreMax")) { - unsigned u; + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - r = safe_atou(eq, &u); + r = sd_bus_message_close_container(m); if (r < 0) - return log_error_errno(r, "Failed to parse file descriptor store limit: %s", eq); + return bus_log_create_error(r); - r = sd_bus_message_append(m, "v", "u", (uint32_t) u); + return 1; + } - } else if (streq(field, "IOSchedulingClass")) { - int c; + if (STR_IN_SET(field, "StandardInput", "StandardOutput", "StandardError")) { + const char *n, *appended; + + if ((n = startswith(eq, "fd:"))) { + appended = strjoina(field, "FileDescriptorName"); + r = sd_bus_message_append(m, "(sv)", appended, "s", n); + } else if ((n = startswith(eq, "file:"))) { + appended = strjoina(field, "File"); + r = sd_bus_message_append(m, "(sv)", appended, "s", n); + } else + r = sd_bus_message_append(m, "(sv)", field, "s", eq); - c = ioprio_class_from_string(eq); - if (c < 0) - return log_error_errno(r, "Failed to parse IO scheduling class: %s", eq); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_append(m, "v", "i", (int32_t) c); + return 1; + } - } else if (streq(field, "IOSchedulingPriority")) { - int q; + if (streq(field, "StandardInputText")) { + _cleanup_free_ char *unescaped = NULL; - r = ioprio_parse_priority(eq, &q); + r = cunescape(eq, 0, &unescaped); if (r < 0) - return log_error_errno(r, "Failed to parse IO scheduling priority: %s", eq); + return log_error_errno(r, "Failed to unescape text '%s': %m", eq); - r = sd_bus_message_append(m, "v", "i", (int32_t) q); + if (!strextend(&unescaped, "\n", NULL)) + return log_oom(); - } else if (STR_IN_SET(field, "Environment", "UnsetEnvironment", "PassEnvironment")) { - const char *p; + /* Note that we don't expand specifiers here, but that should be OK, as this is a programmatic + * interface anyway */ - r = sd_bus_message_open_container(m, 'v', "as"); - if (r < 0) - return bus_log_create_error(r); + return bus_append_byte_array(m, field, unescaped, strlen(unescaped)); + } - r = sd_bus_message_open_container(m, 'a', "s"); + if (streq(field, "StandardInputData")) { + _cleanup_free_ void *decoded = NULL; + size_t sz; + + r = unbase64mem(eq, (size_t) -1, &decoded, &sz); if (r < 0) - return bus_log_create_error(r); + return log_error_errno(r, "Failed to decode base64 data '%s': %m", eq); - for (p = eq;;) { - _cleanup_free_ char *word = NULL; + return bus_append_byte_array(m, field, decoded, sz); + } - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE); - if (r < 0) - return log_error_errno(r, "Failed to parse Environment value %s: %m", eq); - if (r == 0) - break; + rl = rlimit_from_string(field); + if (rl >= 0) { + const char *sn; + struct rlimit l; - if (streq(field, "Environment")) { - if (!env_assignment_is_valid(word)) { - log_error("Invalid environment assignment: %s", word); - return -EINVAL; - } - } else if (streq(field, "UnsetEnvironment")) { - if (!env_assignment_is_valid(word) && !env_name_is_valid(word)) { - log_error("Invalid environment name or assignment: %s", word); - return -EINVAL; - } - } else { /* PassEnvironment */ - if (!env_name_is_valid(word)) { - log_error("Invalid environment variable name: %s", word); - return -EINVAL; - } - } + r = rlimit_parse(rl, eq, &l); + if (r < 0) + return log_error_errno(r, "Failed to parse resource limit: %s", eq); - r = sd_bus_message_append_basic(m, 's', word); - if (r < 0) - return bus_log_create_error(r); - } + r = sd_bus_message_append(m, "(sv)", field, "t", l.rlim_max); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_close_container(m); + sn = strjoina(field, "Soft"); + r = sd_bus_message_append(m, "(sv)", sn, "t", l.rlim_cur); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_close_container(m); + return 1; + } - } else if (streq(field, "KillSignal")) { - int sig; + if (STR_IN_SET(field, "AppArmorProfile", "SmackProcessLabel")) { + int ignore = 0; + const char *s = eq; - sig = signal_from_string_try_harder(eq); - if (sig < 0) { - log_error("Failed to parse %s value %s.", field, eq); - return -EINVAL; + if (eq[0] == '-') { + ignore = 1; + s = eq + 1; } - r = sd_bus_message_append(m, "v", "i", sig); - - } else if (streq(field, "TimerSlackNSec")) { - nsec_t n; - - r = parse_nsec(eq, &n); + r = sd_bus_message_append(m, "(sv)", field, "(bs)", ignore, s); if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); + return bus_log_create_error(r); - r = sd_bus_message_append(m, "v", "t", n); - } else if (streq(field, "OOMScoreAdjust")) { - int oa; + return 1; + } - r = safe_atoi(eq, &oa); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); + if (STR_IN_SET(field, "CapabilityBoundingSet", "AmbientCapabilities")) { + uint64_t sum = 0; + bool invert = false; + const char *p = eq; - if (!oom_score_adjust_is_valid(oa)) { - log_error("OOM score adjust value out of range"); - return -EINVAL; + if (*p == '~') { + invert = true; + p++; } - r = sd_bus_message_append(m, "v", "i", oa); - } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories", - "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) { - const char *p; - - r = sd_bus_message_open_container(m, 'v', "as"); + r = capability_set_from_string(p, &sum); if (r < 0) - return bus_log_create_error(r); + return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); - r = sd_bus_message_open_container(m, 'a', "s"); + sum = invert ? ~sum : sum; + + r = sd_bus_message_append(m, "(sv)", field, "t", sum); if (r < 0) return bus_log_create_error(r); - for (p = eq;;) { - _cleanup_free_ char *word = NULL; - size_t offset; - - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); - if (r == 0) - break; + return 1; + } - if (!utf8_is_valid(word)) { - log_error("Failed to parse %s value %s", field, eq); - return -EINVAL; - } + if (streq(field, "CPUAffinity")) { + _cleanup_cpu_free_ cpu_set_t *cpuset = NULL; - offset = word[0] == '-'; - offset += word[offset] == '+'; + r = parse_cpu_set(eq, &cpuset); + if (r < 0) + return log_error_errno(r, "Failed to parse %s value: %s", field, eq); - if (!path_is_absolute(word + offset)) { - log_error("Failed to parse %s value %s", field, eq); - return -EINVAL; - } + return bus_append_byte_array(m, field, cpuset, CPU_ALLOC_SIZE(r)); + } - path_kill_slashes(word + offset); + if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) { + int whitelist = 1; + const char *p = eq; - r = sd_bus_message_append_basic(m, 's', word); - if (r < 0) - return bus_log_create_error(r); + if (*p == '~') { + whitelist = 0; + p++; } - r = sd_bus_message_close_container(m); + r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_close_container(m); + r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); + if (r < 0) + return bus_log_create_error(r); - } else if (streq(field, "SupplementaryGroups")) { - const char *p; + r = sd_bus_message_open_container(m, 'v', "(bas)"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_open_container(m, 'r', "bas"); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_open_container(m, 'v', "as"); + r = sd_bus_message_append_basic(m, 'b', &whitelist); if (r < 0) return bus_log_create_error(r); @@ -1037,15 +986,12 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen _cleanup_free_ char *word = NULL; r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq); if (r == 0) break; - - if (!valid_user_group_name_or_id(word)) { - log_error("Failed to parse %s value %s", field, eq); - return -EINVAL; - } + if (r == -ENOMEM) + return log_oom(); + if (r < 0) + return log_error_errno(r, "Invalid syntax: %s", eq); r = sd_bus_message_append_basic(m, 's', word); if (r < 0) @@ -1057,50 +1003,21 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen return bus_log_create_error(r); r = sd_bus_message_close_container(m); - - } else if (STR_IN_SET(field, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")) { - mode_t mode; - - r = parse_mode(eq, &mode); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s", field, eq); - - r = sd_bus_message_append(m, "v", "u", mode); - - } else if (STR_IN_SET(field, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) { - const char *p; - - r = sd_bus_message_open_container(m, 'v', "as"); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_open_container(m, 'a', "s"); + r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); - for (p = eq;;) { - _cleanup_free_ char *word = NULL; - - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) - return log_error_errno(r, "Failed to parse %s value %s", field, eq); - if (r == 0) - break; - - r = sd_bus_message_append_basic(m, 's', word); - if (r < 0) - return bus_log_create_error(r); - } - r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_close_container(m); + return 1; + } - } else if (streq(field, "RestrictNamespaces")) { + if (streq(field, "RestrictNamespaces")) { bool invert = false; unsigned long flags = 0; @@ -1123,27 +1040,31 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen if (invert) flags = (~flags) & NAMESPACE_FLAGS_ALL; - r = sd_bus_message_append(m, "v", "t", (uint64_t) flags); - } else if ((dep = unit_dependency_from_string(field)) >= 0) - r = sd_bus_message_append(m, "v", "as", 1, eq); - else if (streq(field, "MountFlags")) { - unsigned long f; - - r = mount_propagation_flags_from_string(eq, &f); + r = sd_bus_message_append(m, "(sv)", field, "t", (uint64_t) flags); if (r < 0) - return log_error_errno(r, "Failed to parse mount propagation flags: %s", eq); + return bus_log_create_error(r); - r = sd_bus_message_append(m, "v", "t", (uint64_t) f); - } else if (STR_IN_SET(field, "BindPaths", "BindReadOnlyPaths")) { + return 1; + } + + if (STR_IN_SET(field, "BindPaths", "BindReadOnlyPaths")) { const char *p = eq; + r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); + if (r < 0) + return bus_log_create_error(r); + r = sd_bus_message_open_container(m, 'v', "a(ssbt)"); if (r < 0) - return r; + return bus_log_create_error(r); r = sd_bus_message_open_container(m, 'a', "(ssbt)"); if (r < 0) - return r; + return bus_log_create_error(r); for (;;) { _cleanup_free_ char *source = NULL, *destination = NULL; @@ -1196,137 +1117,528 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, "(ssbt)", s, d, ignore_enoent, flags); if (r < 0) - return r; + return bus_log_create_error(r); } r = sd_bus_message_close_container(m); if (r < 0) - return r; + return bus_log_create_error(r); r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - } else if (STR_IN_SET(field, "ExecStartPre", "ExecStart", "ExecStartPost", - "ExecReload", "ExecStop", "ExecStopPost")) { + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - bool ignore_failure = false, explicit_path = false, done = false; - _cleanup_strv_free_ char **l = NULL; - _cleanup_free_ char *path = NULL; + return 1; + } - do { - switch (*eq) { + return 0; +} - case '-': - if (ignore_failure) - done = true; - else { - ignore_failure = true; - eq++; - } - break; +static int bus_append_kill_property(sd_bus_message *m, const char *field, const char *eq) { - case '@': - if (explicit_path) - done = true; - else { - explicit_path = true; - eq++; - } - break; + if (streq(field, "KillMode")) - case '+': - case '!': - /* The bus API doesn't support +, ! and !! currently, unfortunately. :-( */ - log_error("Sorry, but +, ! and !! are currently not supported for transient services."); - return -EOPNOTSUPP; + return bus_append_string(m, field, eq); - default: - done = true; - break; - } - } while (!done); + if (STR_IN_SET(field, "SendSIGHUP", "SendSIGKILL")) - if (explicit_path) { - r = extract_first_word(&eq, &path, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE); - if (r < 0) - return log_error_errno(r, "Failed to parse path: %m"); - } + return bus_append_parse_boolean(m, field, eq); - r = strv_split_extract(&l, eq, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE); - if (r < 0) - return log_error_errno(r, "Failed to parse command line: %m"); + if (streq(field, "KillSignal")) + + return bus_append_signal_from_string_try_harder(m, field, eq); + + return 0; +} + +static int bus_append_mount_property(sd_bus_message *m, const char *field, const char *eq) { + + if (STR_IN_SET(field, "What", "Where", "Options", "Type")) + + return bus_append_string(m, field, eq); + + if (streq(field, "TimeoutSec")) + + return bus_append_parse_sec_rename(m, field, eq); + + if (streq(field, "DirectoryMode")) + + return bus_append_parse_mode(m, field, eq); + + if (STR_IN_SET(field, "SloppyOptions", "LazyUnmount", "ForceUnmount")) + + return bus_append_parse_boolean(m, field, eq); + + return 0; +} + +static int bus_append_path_property(sd_bus_message *m, const char *field, const char *eq) { + int r; + + if (streq(field, "MakeDirectory")) + + return bus_append_parse_boolean(m, field, eq); + + if (streq(field, "DirectoryMode")) + + return bus_append_parse_mode(m, field, eq); + + if (STR_IN_SET(field, + "PathExists", "PathExistsGlob", "PathChanged", + "PathModified", "DirectoryNotEmpty")) { - r = sd_bus_message_open_container(m, 'v', "a(sasb)"); + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 0); + else + r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 1, field, eq); if (r < 0) - return r; + return bus_log_create_error(r); + + return 1; + } + + return 0; +} + +static int bus_append_service_property(sd_bus_message *m, const char *field, const char *eq) { + int r; + + if (STR_IN_SET(field, + "PIDFile", "Type", "Restart", "BusName", "NotifyAccess", + "USBFunctionDescriptors", "USBFunctionStrings")) + + return bus_append_string(m, field, eq); + + if (STR_IN_SET(field, "PermissionsStartOnly", "RootDirectoryStartOnly", "RemainAfterExit", "GuessMainPID")) + + return bus_append_parse_boolean(m, field, eq); - r = sd_bus_message_open_container(m, 'a', "(sasb)"); + if (STR_IN_SET(field, "RestartSec", "TimeoutStartSec", "TimeoutStopSec", "RuntimeMaxSec", "WatchdogSec")) + + return bus_append_parse_sec_rename(m, field, eq); + + if (streq(field, "TimeoutSec")) { + + r = bus_append_parse_sec_rename(m, "TimeoutStartSec", eq); if (r < 0) return r; - if (strv_length(l) > 0) { + return bus_append_parse_sec_rename(m, "TimeoutStopSec", eq); + } - r = sd_bus_message_open_container(m, 'r', "sasb"); - if (r < 0) - return r; + if (streq(field, "FileDescriptorStoreMax")) - r = sd_bus_message_append(m, "s", path ?: l[0]); - if (r < 0) - return r; + return bus_append_safe_atou(m, field, eq); - r = sd_bus_message_append_strv(m, l); - if (r < 0) - return r; + if (STR_IN_SET(field, + "ExecStartPre", "ExecStart", "ExecStartPost", + "ExecReload", "ExecStop", "ExecStopPost")) - r = sd_bus_message_append(m, "b", ignore_failure); - if (r < 0) - return r; + return bus_append_exec_command(m, field, eq); + + if (STR_IN_SET(field, "RestartPreventExitStatus", "RestartForceExitStatus", "SuccessExitStatus")) { + _cleanup_free_ int *status = NULL, *signal = NULL; + size_t sz_status = 0, sz_signal = 0; + const char *p; - r = sd_bus_message_close_container(m); + for (p = eq;;) { + _cleanup_free_ char *word = NULL; + int val; + + r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); + if (r == 0) + break; + if (r == -ENOMEM) + return log_oom(); if (r < 0) - return r; + return log_error_errno(r, "Invalid syntax in %s: %s", field, eq); + + r = safe_atoi(word, &val); + if (r < 0) { + val = signal_from_string_try_harder(word); + if (val < 0) + return log_error_errno(r, "Invalid status or signal %s in %s: %m", word, field); + + signal = realloc_multiply(signal, sizeof(int), sz_signal + 1); + if (!signal) + return log_oom(); + + signal[sz_signal++] = val; + } else { + status = realloc_multiply(status, sizeof(int), sz_status + 1); + if (!status) + return log_oom(); + + status[sz_status++] = val; + } } + r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_open_container(m, 'v', "(aiai)"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_open_container(m, 'r', "aiai"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append_array(m, 'i', status, sz_status); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append_array(m, 'i', signal, sz_signal); + if (r < 0) + return bus_log_create_error(r); + r = sd_bus_message_close_container(m); if (r < 0) - return r; + return bus_log_create_error(r); r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); + + return 1; + } + + return 0; +} + +static int bus_append_socket_property(sd_bus_message *m, const char *field, const char *eq) { + int r; + + if (STR_IN_SET(field, + "Accept", "Writable", "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast", + "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet")) + + return bus_append_parse_boolean(m, field, eq); + + if (STR_IN_SET(field, "Priority", "IPTTL", "Mark")) + + return bus_append_safe_atoi(m, field, eq); + + if (streq(field, "IPTOS")) + + return bus_append_ip_tos_from_string(m, field, eq); + + if (STR_IN_SET(field, "Backlog", "MaxConnections", "MaxConnectionsPerSource", "KeepAliveProbes", "TriggerLimitBurst")) - } else if (STR_IN_SET(field, - "OnActiveSec", "OnBootSec", "OnStartupSec", - "OnUnitActiveSec","OnUnitInactiveSec")) { - usec_t t; + return bus_append_safe_atou(m, field, eq); - r = parse_sec(eq, &t); + if (STR_IN_SET(field, "SocketMode", "DirectoryMode")) + + return bus_append_parse_mode(m, field, eq); + + if (STR_IN_SET(field, "MessageQueueMaxMessages", "MessageQueueMessageSize")) + + return bus_append_safe_atoi64(m, field, eq); + + if (STR_IN_SET(field, "TimeoutSec", "KeepAliveTimeSec", "KeepAliveIntervalSec", "DeferAcceptSec", "TriggerLimitIntervalSec")) + + return bus_append_parse_sec_rename(m, field, eq); + + if (STR_IN_SET(field, "ReceiveBuffer", "SendBuffer", "PipeSize")) + + return bus_append_parse_size(m, field, eq, 1024); + + if (STR_IN_SET(field, "ExecStartPre", "ExecStartPost", "ExecReload", "ExecStopPost")) + + return bus_append_exec_command(m, field, eq); + + if (STR_IN_SET(field, + "SmackLabel", "SmackLabelIPIn", "SmackLabelIPOut", "TCPCongestion", + "BindToDevice", "BindIPv6Only", "FileDescriptorName", + "SocketUser", "SocketGroup")) + + return bus_append_string(m, field, eq); + + if (streq(field, "Symlinks")) + + return bus_append_strv(m, field, eq, EXTRACT_QUOTES); + + if (streq(field, "SocketProtocol")) + + return bus_append_socket_protocol_from_name(m, field, eq); + + if (STR_IN_SET(field, + "ListenStream", "ListenDatagram", "ListenSequentialPacket", "ListenNetlink", + "ListenSpecial", "ListenMessageQueue", "ListenFIFO", "ListenUSBFunction")) { + + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 0); + else + r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 1, field + STRLEN("Listen"), eq); if (r < 0) - return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq); + return bus_log_create_error(r); - r = sd_bus_message_append(m, "v", "t", t); + return 1; + } - } else { - log_error("Unknown assignment: %s", assignment); - return -EINVAL; + return 0; +} +static int bus_append_timer_property(sd_bus_message *m, const char *field, const char *eq) { + int r; + + if (STR_IN_SET(field, "WakeSystem", "RemainAfterElapse", "Persistent")) + + return bus_append_parse_boolean(m, field, eq); + + if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec")) + + return bus_append_parse_sec_rename(m, field, eq); + + if (STR_IN_SET(field, + "OnActiveSec", "OnBootSec", "OnStartupSec", + "OnUnitActiveSec","OnUnitInactiveSec")) { + + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 0); + else { + usec_t t; + r = parse_sec(eq, &t); + if (r < 0) + return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq); + + r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 1, field, t); + } + if (r < 0) + return bus_log_create_error(r); + + return 1; } -finish: - if (r < 0) - return bus_log_create_error(r); + if (streq(field, "OnCalendar")) { - r = sd_bus_message_close_container(m); - if (r < 0) - return bus_log_create_error(r); + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 0); + else + r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 1, field, eq); + if (r < 0) + return bus_log_create_error(r); + + return 1; + } + + return 0; +} + +static int bus_append_unit_property(sd_bus_message *m, const char *field, const char *eq) { + ConditionType t = _CONDITION_TYPE_INVALID; + bool is_condition = false; + int r; + + if (STR_IN_SET(field, + "Description", "SourcePath", "OnFailureJobMode", + "JobTimeoutAction", "JobTimeoutRebootArgument", + "StartLimitAction", "FailureAction", "SuccessAction", + "RebootArgument", "CollectMode")) + + return bus_append_string(m, field, eq); + + if (STR_IN_SET(field, + "StopWhenUnneeded", "RefuseManualStart", "RefuseManualStop", + "AllowIsolate", "IgnoreOnIsolate", "DefaultDependencies")) + + return bus_append_parse_boolean(m, field, eq); + + if (STR_IN_SET(field, "JobTimeoutSec", "JobRunningTimeoutSec", "StartLimitIntervalSec")) + + return bus_append_parse_sec_rename(m, field, eq); + + if (streq(field, "StartLimitBurst")) + + return bus_append_safe_atou(m, field, eq); + + if (unit_dependency_from_string(field) >= 0 || + STR_IN_SET(field, "Documentation", "RequiresMountsFor")) + + return bus_append_strv(m, field, eq, EXTRACT_QUOTES); + + t = condition_type_from_string(field); + if (t >= 0) + is_condition = true; + else + t = assert_type_from_string(field); + if (t >= 0) { + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", is_condition ? "Conditions" : "Asserts", "a(sbbs)", 0); + else { + const char *p = eq; + int trigger, negate; + + trigger = *p == '|'; + if (trigger) + p++; + + negate = *p == '!'; + if (negate) + p++; + + r = sd_bus_message_append(m, "(sv)", is_condition ? "Conditions" : "Asserts", "a(sbbs)", 1, + field, trigger, negate, p); + } + if (r < 0) + return bus_log_create_error(r); + + return 1; + } return 0; } -int bus_append_unit_property_assignment_many(sd_bus_message *m, char **l) { +int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const char *assignment) { + const char *eq, *field; + int r; + + assert(m); + assert(assignment); + + eq = strchr(assignment, '='); + if (!eq) { + log_error("Not an assignment: %s", assignment); + return -EINVAL; + } + + field = strndupa(assignment, eq - assignment); + eq++; + + switch (t) { + case UNIT_SERVICE: + r = bus_append_cgroup_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_execute_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_kill_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_service_property(m, field, eq); + if (r != 0) + return r; + break; + + case UNIT_SOCKET: + r = bus_append_cgroup_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_execute_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_kill_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_socket_property(m, field, eq); + if (r != 0) + return r; + break; + + case UNIT_TIMER: + r = bus_append_timer_property(m, field, eq); + if (r != 0) + return r; + break; + + case UNIT_PATH: + r = bus_append_path_property(m, field, eq); + if (r != 0) + return r; + break; + + case UNIT_SLICE: + r = bus_append_cgroup_property(m, field, eq); + if (r != 0) + return r; + break; + + case UNIT_SCOPE: + + if (streq(field, "TimeoutStopSec")) + return bus_append_parse_sec_rename(m, field, eq); + + r = bus_append_cgroup_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_kill_property(m, field, eq); + if (r != 0) + return r; + break; + + case UNIT_MOUNT: + r = bus_append_cgroup_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_execute_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_kill_property(m, field, eq); + if (r != 0) + return r; + + r = bus_append_mount_property(m, field, eq); + if (r != 0) + return r; + + break; + + case UNIT_AUTOMOUNT: + r = bus_append_automount_property(m, field, eq); + if (r != 0) + return r; + + break; + + case UNIT_TARGET: + case UNIT_DEVICE: + case UNIT_SWAP: + log_error("Not supported unit type"); + return -EINVAL; + + default: + log_error("Invalid unit type"); + return -EINVAL; + } + + r = bus_append_unit_property(m, field, eq); + if (r != 0) + return r; + + log_error("Unknown assignment: %s", assignment); + return -EINVAL; +} + +int bus_append_unit_property_assignment_many(sd_bus_message *m, UnitType t, char **l) { char **i; int r; assert(m); STRV_FOREACH(i, l) { - r = bus_append_unit_property_assignment(m, *i); + r = bus_append_unit_property_assignment(m, t, *i); if (r < 0) return r; } @@ -1418,31 +1730,25 @@ int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) { /* When we are a bus client we match by sender. Direct * connections OTOH have no initialized sender field, and * hence we ignore the sender then */ - r = sd_bus_add_match( + r = sd_bus_match_signal_async( bus, &d->slot_job_removed, - bus->bus_client ? - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Manager'," - "member='JobRemoved'," - "path='/org/freedesktop/systemd1'" : - "type='signal'," - "interface='org.freedesktop.systemd1.Manager'," - "member='JobRemoved'," - "path='/org/freedesktop/systemd1'", - match_job_removed, d); + bus->bus_client ? "org.freedesktop.systemd1" : NULL, + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "JobRemoved", + match_job_removed, NULL, d); if (r < 0) return r; - r = sd_bus_add_match( + r = sd_bus_match_signal_async( bus, &d->slot_disconnected, - "type='signal'," - "sender='org.freedesktop.DBus.Local'," - "interface='org.freedesktop.DBus.Local'," - "member='Disconnected'", - match_disconnected, d); + "org.freedesktop.DBus.Local", + NULL, + "org.freedesktop.DBus.Local", + "Disconnected", + match_disconnected, NULL, d); if (r < 0) return r; diff --git a/src/shared/bus-unit-util.h b/src/shared/bus-unit-util.h index 1a137e8b84..514e6edb76 100644 --- a/src/shared/bus-unit-util.h +++ b/src/shared/bus-unit-util.h @@ -20,10 +20,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "sd-bus.h" - -#include "output-mode.h" #include "install.h" +#include "output-mode.h" +#include "sd-bus.h" +#include "unit-def.h" typedef struct UnitInfo { const char *machine; @@ -41,8 +41,8 @@ typedef struct UnitInfo { int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u); -int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment); -int bus_append_unit_property_assignment_many(sd_bus_message *m, char **l); +int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const char *assignment); +int bus_append_unit_property_assignment_many(sd_bus_message *m, UnitType t, char **l); typedef struct BusWaitForJobs BusWaitForJobs; diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 7a185461a3..548e817105 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -68,7 +68,7 @@ static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_ } int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) { - _cleanup_free_ char *match = NULL; + const char *match; const char *unique; int r; @@ -85,23 +85,21 @@ int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) { if (r < 0) return r; - r = asprintf(&match, - "sender='org.freedesktop.DBus'," - "type='signal'," - "interface='org.freedesktop.DBus'," - "member='NameOwnerChanged'," - "path='/org/freedesktop/DBus'," - "arg0='%s'," - "arg1='%s'," - "arg2=''", name, unique); - if (r < 0) - return -ENOMEM; - - r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e); + match = strjoina( + "sender='org.freedesktop.DBus'," + "type='signal'," + "interface='org.freedesktop.DBus'," + "member='NameOwnerChanged'," + "path='/org/freedesktop/DBus'," + "arg0='", name, "',", + "arg1='", unique, "',", + "arg2=''"); + + r = sd_bus_add_match_async(bus, NULL, match, name_owner_change_callback, NULL, e); if (r < 0) return r; - r = sd_bus_release_name(bus, name); + r = sd_bus_release_name_async(bus, NULL, name, NULL, NULL); if (r < 0) return r; @@ -560,8 +558,7 @@ void bus_verify_polkit_async_registry_free(Hashmap *registry) { int bus_check_peercred(sd_bus *c) { struct ucred ucred; - socklen_t l; - int fd; + int fd, r; assert(c); @@ -569,12 +566,9 @@ int bus_check_peercred(sd_bus *c) { if (fd < 0) return fd; - l = sizeof(struct ucred); - if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0) - return -errno; - - if (l != sizeof(struct ucred)) - return -E2BIG; + r = getpeercred(fd, &ucred); + if (r < 0) + return r; if (ucred.uid != 0 && ucred.uid != geteuid()) return -EPERM; @@ -717,7 +711,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b /* Yes, heuristics! But we can change this check * should it turn out to not be sufficient */ - if (endswith(name, "Timestamp")) { + if (endswith(name, "Timestamp") || STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec")) { char timestamp[FORMAT_TIMESTAMP_MAX], *t; t = format_timestamp(timestamp, sizeof(timestamp), u); @@ -1344,6 +1338,25 @@ int bus_property_get_bool( return sd_bus_message_append_basic(reply, 'b', &b); } +int bus_property_set_bool( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *value, + void *userdata, + sd_bus_error *error) { + + int b, r; + + r = sd_bus_message_read(value, "b", &b); + if (r < 0) + return r; + + *(bool *) userdata = !!b; + return 0; +} + int bus_property_get_id128( sd_bus *bus, const char *path, @@ -1604,3 +1617,54 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) { return r; } + +int bus_open_system_watch_bind(sd_bus **ret) { + _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; + const char *e; + int r; + + assert(ret); + + /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal turned on. */ + + r = sd_bus_new(&bus); + if (r < 0) + return r; + + e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS"); + if (!e) + e = DEFAULT_SYSTEM_BUS_ADDRESS; + + r = sd_bus_set_address(bus, e); + if (r < 0) + return r; + + r = sd_bus_set_bus_client(bus, true); + if (r < 0) + return r; + + r = sd_bus_set_trusted(bus, true); + if (r < 0) + return r; + + r = sd_bus_negotiate_creds(bus, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS); + if (r < 0) + return r; + + r = sd_bus_set_watch_bind(bus, true); + if (r < 0) + return r; + + r = sd_bus_set_connected_signal(bus, true); + if (r < 0) + return r; + + r = sd_bus_start(bus); + if (r < 0) + return r; + + *ret = bus; + bus = NULL; + + return 0; +} diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index a9f4969d7d..969a444d83 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -80,6 +80,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool value, bool all); int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); +int bus_property_set_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error); int bus_property_get_id128(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); #define bus_property_get_usec ((sd_bus_property_get_t) NULL) @@ -162,3 +163,5 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send int bus_property_get_rlimit(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); int bus_track_add_name_many(sd_bus_track *t, char **l); + +int bus_open_system_watch_bind(sd_bus **ret); diff --git a/src/shared/condition.c b/src/shared/condition.c index 3f32dfb7b6..a2fd05c425 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -26,6 +26,7 @@ #include <string.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/utsname.h> #include <time.h> #include <unistd.h> @@ -36,6 +37,7 @@ #include "architecture.h" #include "audit-util.h" #include "cap-list.h" +#include "cgroup-util.h" #include "condition.h" #include "extract-word.h" #include "fd-util.h" @@ -142,6 +144,70 @@ static int condition_test_kernel_command_line(Condition *c) { return false; } +static int condition_test_kernel_version(Condition *c) { + enum { + /* Listed in order of checking. Note that some comparators are prefixes of others, hence the longest + * should be listed first. */ + LOWER_OR_EQUAL, + GREATER_OR_EQUAL, + LOWER, + GREATER, + EQUAL, + _ORDER_MAX, + }; + + static const char *const prefix[_ORDER_MAX] = { + [LOWER_OR_EQUAL] = "<=", + [GREATER_OR_EQUAL] = ">=", + [LOWER] = "<", + [GREATER] = ">", + [EQUAL] = "=", + }; + const char *p = NULL; + struct utsname u; + size_t i; + int k; + + assert(c); + assert(c->parameter); + assert(c->type == CONDITION_KERNEL_VERSION); + + assert_se(uname(&u) >= 0); + + for (i = 0; i < _ORDER_MAX; i++) { + p = startswith(c->parameter, prefix[i]); + if (p) + break; + } + + /* No prefix? Then treat as glob string */ + if (!p) + return fnmatch(skip_leading_chars(c->parameter, NULL), u.release, 0) == 0; + + k = str_verscmp(u.release, skip_leading_chars(p, NULL)); + + switch (i) { + + case LOWER: + return k < 0; + + case LOWER_OR_EQUAL: + return k <= 0; + + case EQUAL: + return k == 0; + + case GREATER_OR_EQUAL: + return k >= 0; + + case GREATER: + return k > 0; + + default: + assert_not_reached("Can't compare"); + } +} + static int condition_test_user(Condition *c) { uid_t id; int r; @@ -177,6 +243,30 @@ static int condition_test_user(Condition *c) { return id == getuid() || id == geteuid(); } +static int condition_test_control_group_controller(Condition *c) { + int r; + CGroupMask system_mask, wanted_mask = 0; + + assert(c); + assert(c->parameter); + assert(c->type == CONDITION_CONTROL_GROUP_CONTROLLER); + + r = cg_mask_supported(&system_mask); + if (r < 0) + return log_debug_errno(r, "Failed to determine supported controllers: %m"); + + r = cg_mask_from_string(c->parameter, &wanted_mask); + if (r < 0 || wanted_mask <= 0) { + /* This won't catch the case that we have an unknown controller + * mixed in with valid ones -- these are only assessed on the + * validity of the valid controllers found. */ + log_debug("Failed to parse cgroup string: %s", c->parameter); + return 1; + } + + return (system_mask & wanted_mask) == wanted_mask; +} + static int condition_test_group(Condition *c) { gid_t id; int r; @@ -527,6 +617,7 @@ int condition_test(Condition *c) { [CONDITION_FILE_NOT_EMPTY] = condition_test_file_not_empty, [CONDITION_FILE_IS_EXECUTABLE] = condition_test_file_is_executable, [CONDITION_KERNEL_COMMAND_LINE] = condition_test_kernel_command_line, + [CONDITION_KERNEL_VERSION] = condition_test_kernel_version, [CONDITION_VIRTUALIZATION] = condition_test_virtualization, [CONDITION_SECURITY] = condition_test_security, [CONDITION_CAPABILITY] = condition_test_capability, @@ -537,6 +628,7 @@ int condition_test(Condition *c) { [CONDITION_FIRST_BOOT] = condition_test_first_boot, [CONDITION_USER] = condition_test_user, [CONDITION_GROUP] = condition_test_group, + [CONDITION_CONTROL_GROUP_CONTROLLER] = condition_test_control_group_controller, [CONDITION_NULL] = condition_test_null, }; @@ -561,8 +653,7 @@ void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_ assert(c); assert(f); - if (!prefix) - prefix = ""; + prefix = strempty(prefix); fprintf(f, "%s\t%s: %s%s%s %s\n", @@ -586,6 +677,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = { [CONDITION_VIRTUALIZATION] = "ConditionVirtualization", [CONDITION_HOST] = "ConditionHost", [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine", + [CONDITION_KERNEL_VERSION] = "ConditionKernelVersion", [CONDITION_SECURITY] = "ConditionSecurity", [CONDITION_CAPABILITY] = "ConditionCapability", [CONDITION_AC_POWER] = "ConditionACPower", @@ -602,6 +694,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = { [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable", [CONDITION_USER] = "ConditionUser", [CONDITION_GROUP] = "ConditionGroup", + [CONDITION_CONTROL_GROUP_CONTROLLER] = "ConditionControlGroupController", [CONDITION_NULL] = "ConditionNull" }; @@ -612,6 +705,7 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = { [CONDITION_VIRTUALIZATION] = "AssertVirtualization", [CONDITION_HOST] = "AssertHost", [CONDITION_KERNEL_COMMAND_LINE] = "AssertKernelCommandLine", + [CONDITION_KERNEL_VERSION] = "AssertKernelVersion", [CONDITION_SECURITY] = "AssertSecurity", [CONDITION_CAPABILITY] = "AssertCapability", [CONDITION_AC_POWER] = "AssertACPower", @@ -628,6 +722,7 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = { [CONDITION_FILE_IS_EXECUTABLE] = "AssertFileIsExecutable", [CONDITION_USER] = "AssertUser", [CONDITION_GROUP] = "AssertGroup", + [CONDITION_CONTROL_GROUP_CONTROLLER] = "AssertControlGroupController", [CONDITION_NULL] = "AssertNull" }; diff --git a/src/shared/condition.h b/src/shared/condition.h index 534906b6d6..a84d993370 100644 --- a/src/shared/condition.h +++ b/src/shared/condition.h @@ -31,6 +31,7 @@ typedef enum ConditionType { CONDITION_VIRTUALIZATION, CONDITION_HOST, CONDITION_KERNEL_COMMAND_LINE, + CONDITION_KERNEL_VERSION, CONDITION_SECURITY, CONDITION_CAPABILITY, CONDITION_AC_POWER, @@ -53,6 +54,8 @@ typedef enum ConditionType { CONDITION_USER, CONDITION_GROUP, + CONDITION_CONTROL_GROUP_CONTROLLER, + _CONDITION_TYPE_MAX, _CONDITION_TYPE_INVALID = -1 } ConditionType; @@ -96,3 +99,17 @@ ConditionType assert_type_from_string(const char *s) _pure_; const char* condition_result_to_string(ConditionResult r) _const_; ConditionResult condition_result_from_string(const char *s) _pure_; + +static inline bool condition_takes_path(ConditionType t) { + return IN_SET(t, + CONDITION_PATH_EXISTS, + CONDITION_PATH_EXISTS_GLOB, + CONDITION_PATH_IS_DIRECTORY, + CONDITION_PATH_IS_SYMBOLIC_LINK, + CONDITION_PATH_IS_MOUNT_POINT, + CONDITION_PATH_IS_READ_WRITE, + CONDITION_DIRECTORY_NOT_EMPTY, + CONDITION_FILE_NOT_EMPTY, + CONDITION_FILE_IS_EXECUTABLE, + CONDITION_NEEDS_UPDATE); +} diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index e8d7db8f0c..86114e3dd1 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -22,9 +22,12 @@ #include <sys/prctl.h> #include <sys/wait.h> +#include "sd-id128.h" + #include "architecture.h" #include "ask-password-api.h" #include "blkid-util.h" +#include "blockdev-util.h" #include "copy.h" #include "crypt-util.h" #include "def.h" @@ -38,6 +41,7 @@ #include "hostname-util.h" #include "id128-util.h" #include "linux-3.13/dm-ioctl.h" +#include "missing.h" #include "mount-util.h" #include "path-util.h" #include "process-util.h" @@ -351,7 +355,8 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI /* Filter out weird MMC RPMB partitions, which cannot reasonably be read, see * https://github.com/systemd/systemd/issues/5806 */ sysname = udev_device_get_sysname(q); - if (sysname && startswith(sysname, "mmcblk") && endswith(sysname, "rpmb")) + if (sysname && startswith(sysname, "mmcblk") && + (endswith(sysname, "rpmb") || endswith(sysname, "boot0" ) || endswith(sysname, "boot1"))) continue; node = udev_device_get_devnode(q); @@ -1242,7 +1247,6 @@ int dissected_image_acquire_metadata(DissectedImage *m) { _cleanup_free_ char *hostname = NULL; unsigned n_meta_initialized = 0, k; int fds[2 * _META_MAX], r; - siginfo_t si; BLOCK_SIGNALS(SIGCHLD); @@ -1258,18 +1262,10 @@ int dissected_image_acquire_metadata(DissectedImage *m) { if (r < 0) goto finish; - child = raw_clone(SIGCHLD|CLONE_NEWNS); - if (child < 0) { - r = -errno; + r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_NEW_MOUNTNS, &child); + if (r < 0) goto finish; - } - - if (child == 0) { - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - + if (r == 0) { /* Make sure we never propagate to the host */ if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) _exit(EXIT_FAILURE); @@ -1364,15 +1360,12 @@ int dissected_image_acquire_metadata(DissectedImage *m) { } } - r = wait_for_terminate(child, &si); - if (r < 0) - goto finish; + r = wait_for_terminate_and_check("(sd-dissect)", child, 0); child = 0; - - if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) { - r = -EPROTO; + if (r < 0) goto finish; - } + if (r != EXIT_SUCCESS) + return -EPROTO; free_and_replace(m->hostname, hostname); m->machine_id = machine_id; diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 53a1554a28..10e251ff09 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -22,6 +22,8 @@ #include <stdbool.h> +#include "sd-id128.h" + #include "macro.h" typedef struct DissectedImage DissectedImage; diff --git a/src/shared/efivars.h b/src/shared/efivars.h index 9a4880de7d..5b5951321c 100644 --- a/src/shared/efivars.h +++ b/src/shared/efivars.h @@ -20,6 +20,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#if ! ENABLE_EFI +#include <errno.h> +#endif #include <stdbool.h> #include <stddef.h> #include <stdint.h> diff --git a/src/shared/generator.c b/src/shared/generator.c index 3495a7ef7d..2b0a4ecdc8 100644 --- a/src/shared/generator.c +++ b/src/shared/generator.c @@ -19,6 +19,7 @@ ***/ #include <errno.h> +#include <stdio_ext.h> #include <unistd.h> #include "alloc-util.h" @@ -39,6 +40,39 @@ #include "unit-name.h" #include "util.h" +int generator_open_unit_file( + const char *dest, + const char *source, + const char *name, + FILE **file) { + + const char *unit; + FILE *f; + + unit = strjoina(dest, "/", name); + + f = fopen(unit, "wxe"); + if (!f) { + if (source && errno == EEXIST) + return log_error_errno(errno, + "Failed to create unit file %s, as it already exists. Duplicate entry in %s?", + unit, source); + else + return log_error_errno(errno, + "Failed to create unit file %s: %m", + unit); + } + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + fprintf(f, + "# Automatically generated by %s\n\n", + program_invocation_short_name); + + *file = f; + return 0; +} + int generator_add_symlink(const char *root, const char *dst, const char *dep_type, const char *src) { /* Adds a symlink from <dst>.<dep_type>.d/ to ../<src> */ diff --git a/src/shared/generator.h b/src/shared/generator.h index 32d1ad021c..e1c636a218 100644 --- a/src/shared/generator.h +++ b/src/shared/generator.h @@ -22,6 +22,12 @@ #include <stdio.h> +int generator_open_unit_file( + const char *dest, + const char *source, + const char *name, + FILE **file); + int generator_add_symlink(const char *root, const char *dst, const char *dep_type, const char *src); int generator_write_fsck_deps( diff --git a/src/shared/install.c b/src/shared/install.c index 05ccc586a9..026aa32302 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -2784,6 +2784,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres if (scope == UNIT_FILE_SYSTEM) r = conf_files_list(&files, ".preset", root_dir, 0, "/etc/systemd/system-preset", + "/run/systemd/system-preset", "/usr/local/lib/systemd/system-preset", "/usr/lib/systemd/system-preset", #if HAVE_SPLIT_USR @@ -2793,6 +2794,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres else if (scope == UNIT_FILE_GLOBAL) r = conf_files_list(&files, ".preset", root_dir, 0, "/etc/systemd/user-preset", + "/run/systemd/user-preset", "/usr/local/lib/systemd/user-preset", "/usr/lib/systemd/user-preset", NULL); diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index afc3dcd219..5609e42feb 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -166,8 +166,17 @@ static bool shall_print(const char *p, size_t l, OutputFlags flags) { return true; } -static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, OutputFlags flags, int priority, const char* message, size_t message_len) { - const char *color_on = "", *color_off = ""; +static bool print_multiline( + FILE *f, + unsigned prefix, + unsigned n_columns, + OutputFlags flags, + int priority, + const char* message, + size_t message_len, + size_t highlight[2]) { + + const char *color_on = "", *color_off = "", *highlight_on = ""; const char *pos, *end; bool ellipsized = false; int line = 0; @@ -176,9 +185,11 @@ static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, Output if (priority <= LOG_ERR) { color_on = ANSI_HIGHLIGHT_RED; color_off = ANSI_NORMAL; + highlight_on = ANSI_HIGHLIGHT; } else if (priority <= LOG_NOTICE) { color_on = ANSI_HIGHLIGHT; color_off = ANSI_NORMAL; + highlight_on = ANSI_HIGHLIGHT_RED; } } @@ -209,9 +220,28 @@ static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, Output if (flags & (OUTPUT_FULL_WIDTH | OUTPUT_SHOW_ALL) || (prefix + len + 1 < n_columns && !tail_line)) { - fprintf(f, "%*s%s%.*s%s\n", - continuation * prefix, "", - color_on, len, pos, color_off); + if (highlight && + (size_t) (pos - message) <= highlight[0] && + highlight[0] < (size_t) len) { + + fprintf(f, "%*s%s%.*s", + continuation * prefix, "", + color_on, (int) highlight[0], pos); + fprintf(f, "%s%.*s", + highlight_on, + (int) (MIN((size_t) len, highlight[1]) - highlight[0]), + pos + highlight[0]); + if ((size_t) len > highlight[1]) + fprintf(f, "%s%.*s", + color_on, + (int) (len - highlight[1]), + pos + highlight[1]); + fprintf(f, "%s\n", color_off); + + } else + fprintf(f, "%*s%s%.*s%s\n", + continuation * prefix, "", + color_on, len, pos, color_off); continue; } @@ -369,7 +399,8 @@ static int output_short( OutputMode mode, unsigned n_columns, OutputFlags flags, - Set *output_fields) { + Set *output_fields, + size_t highlight[2]) { int r; const void *data; @@ -390,6 +421,7 @@ static int output_short( PARSE_FIELD_VEC_ENTRY("_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len), PARSE_FIELD_VEC_ENTRY("_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len), }; + size_t highlight_shifted[] = {highlight ? highlight[0] : 0, highlight ? highlight[1] : 0}; assert(f); assert(j); @@ -421,7 +453,7 @@ static int output_short( } if (!(flags & OUTPUT_SHOW_ALL)) - strip_tab_ansi(&message, &message_len); + strip_tab_ansi(&message, &message_len, highlight_shifted); if (priority_len == 1 && *priority >= '0' && *priority <= '7') p = *priority - '0'; @@ -468,7 +500,9 @@ static int output_short( } else { fputs(": ", f); ellipsized |= - print_multiline(f, n + 2, n_columns, flags, p, message, message_len); + print_multiline(f, n + 2, n_columns, flags, p, + message, message_len, + highlight_shifted); } if (flags & OUTPUT_CATALOG) @@ -483,7 +517,8 @@ static int output_verbose( OutputMode mode, unsigned n_columns, OutputFlags flags, - Set *output_fields) { + Set *output_fields, + size_t highlight[2]) { const void *data; size_t length; @@ -561,7 +596,7 @@ static int output_verbose( (((length < PRINT_CHAR_THRESHOLD) || flags & OUTPUT_FULL_WIDTH) && utf8_is_printable(data, length))) { fprintf(f, " %s%.*s=", on, fieldlen, (const char*)data); - print_multiline(f, 4 + fieldlen + 1, 0, OUTPUT_FULL_WIDTH, 0, c + 1, length - fieldlen - 1); + print_multiline(f, 4 + fieldlen + 1, 0, OUTPUT_FULL_WIDTH, 0, c + 1, length - fieldlen - 1, NULL); fputs(off, f); } else { char bytes[FORMAT_BYTES_MAX]; @@ -590,7 +625,8 @@ static int output_export( OutputMode mode, unsigned n_columns, OutputFlags flags, - Set *output_fields) { + Set *output_fields, + size_t highlight[2]) { sd_id128_t boot_id; char sid[33]; @@ -661,6 +697,10 @@ static int output_export( fputc('\n', f); } + if (r == -EBADMSG) { + log_debug_errno(r, "Skipping message we can't read: %m"); + return 0; + } if (r < 0) return r; @@ -728,7 +768,8 @@ static int output_json( OutputMode mode, unsigned n_columns, OutputFlags flags, - Set *output_fields) { + Set *output_fields, + size_t highlight[2]) { uint64_t realtime, monotonic; _cleanup_free_ char *cursor = NULL; @@ -824,6 +865,11 @@ static int output_json( } } + if (r == -EBADMSG) { + log_debug_errno(r, "Skipping message we can't read: %m"); + return 0; + } + if (r < 0) return r; @@ -952,18 +998,29 @@ static int output_cat( OutputMode mode, unsigned n_columns, OutputFlags flags, - Set *output_fields) { + Set *output_fields, + size_t highlight[2]) { const void *data; size_t l; int r; + const char *highlight_on = "", *highlight_off = ""; assert(j); assert(f); + if (flags & OUTPUT_COLOR) { + highlight_on = ANSI_HIGHLIGHT_RED; + highlight_off = ANSI_NORMAL; + } + sd_journal_set_data_threshold(j, 0); r = sd_journal_get_data(j, "MESSAGE", &data, &l); + if (r == -EBADMSG) { + log_debug_errno(r, "Skipping message we can't read: %m"); + return 0; + } if (r < 0) { /* An entry without MESSAGE=? */ if (r == -ENOENT) @@ -974,7 +1031,17 @@ static int output_cat( assert(l >= 8); - fwrite((const char*) data + 8, 1, l - 8, f); + if (highlight && (flags & OUTPUT_COLOR)) { + assert(highlight[0] <= highlight[1]); + assert(highlight[1] <= l - 8); + + fwrite((const char*) data + 8, 1, highlight[0], f); + fwrite(highlight_on, 1, strlen(highlight_on), f); + fwrite((const char*) data + 8 + highlight[0], 1, highlight[1] - highlight[0], f); + fwrite(highlight_off, 1, strlen(highlight_off), f); + fwrite((const char*) data + 8 + highlight[1], 1, l - 8 - highlight[1], f); + } else + fwrite((const char*) data + 8, 1, l - 8, f); fputc('\n', f); return 0; @@ -986,7 +1053,8 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])( OutputMode mode, unsigned n_columns, OutputFlags flags, - Set *output_fields) = { + Set *output_fields, + size_t highlight[2]) = { [OUTPUT_SHORT] = output_short, [OUTPUT_SHORT_ISO] = output_short, @@ -1010,6 +1078,7 @@ int output_journal( unsigned n_columns, OutputFlags flags, char **output_fields, + size_t highlight[2], bool *ellipsized) { int ret; @@ -1030,7 +1099,7 @@ int output_journal( return ret; } - ret = output_funcs[mode](f, j, mode, n_columns, flags, fields); + ret = output_funcs[mode](f, j, mode, n_columns, flags, fields, highlight); if (ellipsized && ret > 0) *ellipsized = true; @@ -1112,7 +1181,7 @@ static int show_journal(FILE *f, line++; maybe_print_begin_newline(f, &flags); - r = output_journal(f, j, mode, n_columns, flags, NULL, ellipsized); + r = output_journal(f, j, mode, n_columns, flags, NULL, NULL, ellipsized); if (r < 0) return r; } @@ -1256,7 +1325,6 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) { _cleanup_close_pair_ int pair[2] = { -1, -1 }; _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1; pid_t pid, child; - siginfo_t si; char buf[37]; ssize_t k; int r; @@ -1278,11 +1346,10 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) { if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0) return -errno; - child = fork(); - if (child < 0) - return -errno; - - if (child == 0) { + r = safe_fork("(sd-bootid)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child); + if (r < 0) + return r; + if (r == 0) { int fd; pair[0] = safe_close(pair[0]); @@ -1309,9 +1376,11 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) { pair[1] = safe_close(pair[1]); - r = wait_for_terminate(child, &si); - if (r < 0 || si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) - return r < 0 ? r : -EIO; + r = wait_for_terminate_and_check("(sd-bootid)", child, 0); + if (r < 0) + return r; + if (r != EXIT_SUCCESS) + return -EIO; k = recv(pair[0], buf, 36, 0); if (k != 36) @@ -1392,7 +1461,7 @@ int show_journal_by_unit( if (r < 0) return log_error_errno(r, "Failed to add unit matches: %m"); - if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) { + if (DEBUG_LOGGING) { _cleanup_free_ char *filter; filter = journal_make_match_string(j); diff --git a/src/shared/logs-show.h b/src/shared/logs-show.h index eaa69b6e90..c876dcc46a 100644 --- a/src/shared/logs-show.h +++ b/src/shared/logs-show.h @@ -39,6 +39,7 @@ int output_journal( unsigned n_columns, OutputFlags flags, char **output_fields, + size_t highlight[2], bool *ellipsized); int add_match_this_boot(sd_journal *j, const char *machine); diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index 097de690e5..37b8479f88 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <fcntl.h> #include <linux/loop.h> #include <sys/ioctl.h> diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c index 167bcfad36..031d443e9e 100644 --- a/src/shared/machine-pool.c +++ b/src/shared/machine-pool.c @@ -42,6 +42,7 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" +#include "label.h" #include "lockfile-util.h" #include "log.h" #include "machine-pool.h" @@ -78,7 +79,6 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) { _cleanup_close_ int fd = -1; struct statvfs ss; pid_t pid = 0; - siginfo_t si; int r; /* We want to be able to make use of btrfs-specific file @@ -122,20 +122,15 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) { goto fail; } - pid = fork(); - if (pid < 0) { - r = sd_bus_error_set_errnof(error, errno, "Failed to fork mkfs.btrfs: %m"); + r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &pid); + if (r < 0) { + sd_bus_error_set_errnof(error, r, "Failed to fork mkfs.btrfs: %m"); goto fail; } - - if (pid == 0) { + if (r == 0) { /* Child */ - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - fd = safe_close(fd); execlp("mkfs.btrfs", "-Lvar-lib-machines", tmp, NULL); @@ -145,24 +140,19 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) { _exit(EXIT_FAILURE); } - r = wait_for_terminate(pid, &si); - if (r < 0) { - sd_bus_error_set_errnof(error, r, "Failed to wait for mkfs.btrfs: %m"); - goto fail; - } - + r = wait_for_terminate_and_check("mkfs", pid, 0); pid = 0; - if (si.si_code != CLD_EXITED) { - r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs died abnormally."); + if (r < 0) { + sd_bus_error_set_errnof(error, r, "Failed to wait for mkfs.btrfs: %m"); goto fail; } - if (si.si_status == 99) { + if (r == 99) { r = sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing"); goto fail; } - if (si.si_status != 0) { - r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs failed with error code %i", si.si_status); + if (r != EXIT_SUCCESS) { + r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs failed with error code %i", r); goto fail; } diff --git a/src/shared/meson.build b/src/shared/meson.build index 06a944c49d..91fecf896c 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -56,8 +56,6 @@ shared_sources = ''' firewall-util.h fstab-util.c fstab-util.h - gcrypt-util.c - gcrypt-util.h generator.c generator.h gpt.h @@ -120,6 +118,7 @@ shared_sources = ''' volatile-util.h watchdog.c watchdog.h + wireguard-netlink.h '''.split() test_tables_h = files('test-tables.h') @@ -159,24 +158,25 @@ libshared_deps = [threads, libshared_sym_path = '@0@/libshared.sym'.format(meson.current_source_dir()) -libshared = shared_library( +libshared_static = static_library( libshared_name, shared_sources, - basic_sources, - journal_internal_sources, - libsystemd_internal_sources, + include_directories : includes, + dependencies : libshared_deps, + c_args : ['-fvisibility=default']) + +libshared = shared_library( + libshared_name, libudev_sources, include_directories : includes, link_args : ['-shared', - '-Wl,--version-script=' + libshared_sym_path], + '-Wl,--version-script=' + libshared_sym_path], + link_whole : [libshared_static, + libbasic, + libbasic_gcrypt, + libsystemd_static, + libjournal_client], c_args : ['-fvisibility=default'], dependencies : libshared_deps, install : true, install_dir : rootlibexecdir) - -libshared_static = static_library( - libshared_name, - shared_sources, - basic_sources, - include_directories : includes, - dependencies : libshared_deps) diff --git a/src/shared/nsflags.h b/src/shared/nsflags.h index dcac6cd0b2..51bc590621 100644 --- a/src/shared/nsflags.h +++ b/src/shared/nsflags.h @@ -42,6 +42,13 @@ unsigned long namespace_flag_from_string(const char *name); int namespace_flag_from_string_many(const char *name, unsigned long *ret); int namespace_flag_to_string_many(unsigned long flags, char **ret); +static inline int namespace_flag_to_string_many_with_check(unsigned long n, char **s) { + if ((n & NAMESPACE_FLAGS_ALL) != n) + return -EINVAL; + + return namespace_flag_to_string_many(n, s); +} + struct namespace_flag_map { unsigned long flag; const char *name; diff --git a/src/shared/pager.c b/src/shared/pager.c index 39997278f1..75db3c985b 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -42,6 +42,11 @@ static pid_t pager_pid = 0; +static int stored_stdout = -1; +static int stored_stderr = -1; +static bool stdout_redirected = false; +static bool stderr_redirected = false; + noreturn static void pager_fallback(void) { int r; @@ -54,15 +59,10 @@ noreturn static void pager_fallback(void) { _exit(EXIT_SUCCESS); } -static int stored_stdout = -1; -static int stored_stderr = -1; -static bool stdout_redirected = false; -static bool stderr_redirected = false; - int pager_open(bool no_pager, bool jump_to_end) { _cleanup_close_pair_ int fd[2] = { -1, -1 }; const char *pager; - pid_t parent_pid; + int r; if (no_pager) return 0; @@ -73,6 +73,9 @@ int pager_open(bool no_pager, bool jump_to_end) { if (terminal_is_dumb()) return 0; + if (!is_main_thread()) + return -EPERM; + pager = getenv("SYSTEMD_PAGER"); if (!pager) pager = getenv("PAGER"); @@ -89,18 +92,13 @@ int pager_open(bool no_pager, bool jump_to_end) { if (pipe2(fd, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to create pager pipe: %m"); - parent_pid = getpid_cached(); - - pager_pid = fork(); - if (pager_pid < 0) - return log_error_errno(errno, "Failed to fork pager: %m"); - - /* In the child start the pager */ - if (pager_pid == 0) { + r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pager_pid); + if (r < 0) + return r; + if (r == 0) { const char* less_opts, *less_charset; - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); + /* In the child start the pager */ (void) dup2(fd[0], STDIN_FILENO); safe_close_pair(fd); @@ -124,15 +122,6 @@ int pager_open(bool no_pager, bool jump_to_end) { setenv("LESSCHARSET", less_charset, 1) < 0) _exit(EXIT_FAILURE); - /* Make sure the pager goes away when the parent dies */ - if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) - _exit(EXIT_FAILURE); - - /* Check whether our parent died before we were able - * to set the death signal */ - if (getppid() != parent_pid) - _exit(EXIT_SUCCESS); - if (pager) { execlp(pager, pager, NULL); execl("/bin/sh", "sh", "-c", pager, NULL); @@ -204,7 +193,6 @@ int show_man_page(const char *desc, bool null_stdio) { pid_t pid; size_t k; int r; - siginfo_t status; k = strlen(desc); @@ -222,33 +210,15 @@ int show_man_page(const char *desc, bool null_stdio) { } else args[1] = desc; - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - - if (pid == 0) { + r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0)|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { /* Child */ - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - - if (null_stdio) { - r = make_null_stdio(); - if (r < 0) { - log_error_errno(r, "Failed to kill stdio: %m"); - _exit(EXIT_FAILURE); - } - } - execvp(args[0], (char**) args); log_error_errno(errno, "Failed to execute man: %m"); _exit(EXIT_FAILURE); } - r = wait_for_terminate(pid, &status); - if (r < 0) - return r; - - log_debug("Exit code %i status %i", status.si_code, status.si_status); - return status.si_status; + return wait_for_terminate_and_check(NULL, pid, 0); } diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 62742858c7..fbb232cd45 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -950,11 +950,70 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u return 0; } +int seccomp_parse_syscall_filter_internal( + bool invert, + const char *name, + int errno_num, + Hashmap *filter, + bool whitelist, + bool warn, + const char *unit, + const char *filename, + unsigned line) { + + int r; + + assert(name); + assert(filter); + + if (name[0] == '@') { + const SyscallFilterSet *set; + const char *i; + + set = syscall_filter_set_find(name); + if (!set) { + if (warn) { + log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown system call group, ignoring: %s", name); + return 0; + } else + return -EINVAL; + } + + NULSTR_FOREACH(i, set->value) { + r = seccomp_parse_syscall_filter_internal(invert, i, errno_num, filter, whitelist, warn, unit, filename, line); + if (r < 0) + return r; + } + } else { + int id; + + id = seccomp_syscall_resolve_name(name); + if (id == __NR_SCMP_ERROR) { + if (warn) { + log_syntax(unit, LOG_WARNING, filename, line, 0, "Failed to parse system call, ignoring: %s", name); + return 0; + } else + return -EINVAL; + } + + /* If we previously wanted to forbid a syscall and now + * we want to allow it, then remove it from the list. */ + if (!invert == whitelist) { + r = hashmap_put(filter, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num)); + if (r < 0) + return warn ? log_oom() : -ENOMEM; + } else + (void) hashmap_remove(filter, INT_TO_PTR(id + 1)); + } + + return 0; +} + int seccomp_restrict_namespaces(unsigned long retain) { uint32_t arch; int r; - if (log_get_max_level() >= LOG_DEBUG) { + if (DEBUG_LOGGING) { _cleanup_free_ char *s = NULL; (void) namespace_flag_to_string_many(retain, &s); @@ -1386,6 +1445,7 @@ int seccomp_memory_deny_write_execute(void) { block_syscall = SCMP_SYS(mmap); break; + case SCMP_ARCH_PPC: case SCMP_ARCH_PPC64: case SCMP_ARCH_PPC64LE: filter_syscall = SCMP_SYS(mmap); @@ -1410,7 +1470,7 @@ int seccomp_memory_deny_write_execute(void) { /* Please add more definitions here, if you port systemd to other architectures! */ -#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) +#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) #warning "Consider adding the right mmap() syscall definitions here!" #endif } diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h index ad2ab7f6b5..0b30cdf388 100644 --- a/src/shared/seccomp-util.h +++ b/src/shared/seccomp-util.h @@ -81,6 +81,24 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action); int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action); +int seccomp_parse_syscall_filter_internal( + bool invert, const char *name, int errno_num, Hashmap *filter, bool whitelist, + bool warn, const char *unit, const char *filename, unsigned line); + +static inline int seccomp_parse_syscall_filter_and_warn( + bool invert, const char *name, int errno_num, Hashmap *filter, bool whitelist, + const char *unit, const char *filename, unsigned line) { + assert(unit); + assert(filename); + + return seccomp_parse_syscall_filter_internal(invert, name, errno_num, filter, whitelist, true, unit, filename, line); +} + +static inline int seccomp_parse_syscall_filter( + bool invert, const char *name, int errno_num, Hashmap *filter, bool whitelist) { + return seccomp_parse_syscall_filter_internal(invert, name, errno_num, filter, whitelist, false, NULL, NULL, 0); +} + int seccomp_restrict_archs(Set *archs); int seccomp_restrict_namespaces(unsigned long retain); int seccomp_protect_sysctl(void); diff --git a/src/shared/spawn-ask-password-agent.c b/src/shared/spawn-ask-password-agent.c index 9af5faa3dd..f78167c25c 100644 --- a/src/shared/spawn-ask-password-agent.c +++ b/src/shared/spawn-ask-password-agent.c @@ -40,8 +40,12 @@ int ask_password_agent_open(void) { if (!isatty(STDIN_FILENO)) return 0; - r = fork_agent(&agent_pid, + if (!is_main_thread()) + return -EPERM; + + r = fork_agent("(sd-askpwagent)", NULL, 0, + &agent_pid, SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, "--watch", NULL); if (r < 0) @@ -56,8 +60,7 @@ void ask_password_agent_close(void) { return; /* Inform agent that we are done */ - (void) kill(agent_pid, SIGTERM); - (void) kill(agent_pid, SIGCONT); + (void) kill_and_sigcont(agent_pid, SIGTERM); (void) wait_for_terminate(agent_pid, NULL); agent_pid = 0; } diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c index 423069fb0e..3c93c79ceb 100644 --- a/src/shared/spawn-polkit-agent.c +++ b/src/shared/spawn-polkit-agent.c @@ -38,9 +38,8 @@ static pid_t agent_pid = 0; int polkit_agent_open(void) { - int r; - int pipe_fd[2]; char notify_fd[DECIMAL_STR_MAX(int) + 1]; + int pipe_fd[2], r; if (agent_pid > 0) return 0; @@ -49,18 +48,21 @@ int polkit_agent_open(void) { if (geteuid() == 0) return 0; - /* We check STDIN here, not STDOUT, since this is about input, - * not output */ + /* We check STDIN here, not STDOUT, since this is about input, not output */ if (!isatty(STDIN_FILENO)) return 0; + if (!is_main_thread()) + return -EPERM; + if (pipe2(pipe_fd, 0) < 0) return -errno; xsprintf(notify_fd, "%i", pipe_fd[1]); - r = fork_agent(&agent_pid, + r = fork_agent("(polkit-agent)", &pipe_fd[1], 1, + &agent_pid, POLKIT_AGENT_BINARY_PATH, POLKIT_AGENT_BINARY_PATH, "--notify-fd", notify_fd, "--fallback", NULL); @@ -84,9 +86,7 @@ void polkit_agent_close(void) { return; /* Inform agent that we are done */ - (void) kill(agent_pid, SIGTERM); - (void) kill(agent_pid, SIGCONT); - + (void) kill_and_sigcont(agent_pid, SIGTERM); (void) wait_for_terminate(agent_pid, NULL); agent_pid = 0; } diff --git a/src/shared/sysctl-util.c b/src/shared/sysctl-util.c index 189580e3ed..0bc81aaa56 100644 --- a/src/shared/sysctl-util.c +++ b/src/shared/sysctl-util.c @@ -18,9 +18,13 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> +#include <fcntl.h> #include <stdio.h> #include <string.h> +#include <unistd.h> +#include "fd-util.h" #include "fileio.h" #include "log.h" #include "macro.h" @@ -53,6 +57,7 @@ char *sysctl_normalize(char *s) { int sysctl_write(const char *property, const char *value) { char *p; + _cleanup_close_ int fd = -1; assert(property); assert(value); @@ -60,7 +65,17 @@ int sysctl_write(const char *property, const char *value) { log_debug("Setting '%s' to '%s'", property, value); p = strjoina("/proc/sys/", property); - return write_string_file(p, value, WRITE_STRING_FILE_DISABLE_BUFFER); + fd = open(p, O_WRONLY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (!endswith(value, "\n")) + value = strjoina(value, "\n"); + + if (write(fd, value, strlen(value)) < 0) + return -errno; + + return 0; } int sysctl_read(const char *property, char **content) { diff --git a/src/shared/test-tables.h b/src/shared/test-tables.h index 6b223b1ee5..dd8bf0b582 100644 --- a/src/shared/test-tables.h +++ b/src/shared/test-tables.h @@ -20,6 +20,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> typedef const char* (*lookup_t)(int); typedef int (*reverse_t)(const char*); diff --git a/src/shared/tests.c b/src/shared/tests.c index d78ab7b069..d4781acabf 100644 --- a/src/shared/tests.c +++ b/src/shared/tests.c @@ -48,7 +48,7 @@ const char* get_testdata_dir(const char *suffix) { if (env) { if (access(env, F_OK) < 0) { fputs("ERROR: $SYSTEMD_TEST_DATA directory does not exist\n", stderr); - exit(1); + exit(EXIT_FAILURE); } strncpy(testdir, env, sizeof(testdir) - 1); } else { @@ -65,7 +65,7 @@ const char* get_testdata_dir(const char *suffix) { /* test this without the suffix, as it may contain a glob */ if (access(testdir, F_OK) < 0) { fputs("ERROR: Cannot find testdata directory, set $SYSTEMD_TEST_DATA\n", stderr); - exit(1); + exit(EXIT_FAILURE); } } diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c index 1715c0fb24..cab1cd6a2d 100644 --- a/src/shared/utmp-wtmp.c +++ b/src/shared/utmp-wtmp.c @@ -330,7 +330,7 @@ static int write_to_terminal(const char *tty, const char *message) { assert(tty); assert(message); - fd = open(tty, O_WRONLY|O_NDELAY|O_NOCTTY|O_CLOEXEC); + fd = open(tty, O_WRONLY|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); if (fd < 0 || !isatty(fd)) return -errno; diff --git a/src/shared/volatile-util.c b/src/shared/volatile-util.c index 85512d00af..c92ad0adc0 100644 --- a/src/shared/volatile-util.c +++ b/src/shared/volatile-util.c @@ -18,6 +18,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> + #include "alloc-util.h" #include "macro.h" #include "parse-util.h" diff --git a/src/shared/wireguard-netlink.h b/src/shared/wireguard-netlink.h new file mode 100644 index 0000000000..eb170915a6 --- /dev/null +++ b/src/shared/wireguard-netlink.h @@ -0,0 +1,179 @@ +#pragma once + +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR MIT) + * + * Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * + * Documentation + * ============= + * + * The below enums and macros are for interfacing with WireGuard, using generic + * netlink, with family WG_GENL_NAME and version WG_GENL_VERSION. It defines two + * methods: get and set. Note that while they share many common attributes, these + * two functions actually accept a slightly different set of inputs and outputs. + * + * WG_CMD_GET_DEVICE + * ----------------- + * + * May only be called via NLM_F_REQUEST | NLM_F_DUMP. The command should contain + * one but not both of: + * + * WGDEVICE_A_IFINDEX: NLA_U32 + * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1 + * + * The kernel will then return several messages (NLM_F_MULTI) containing the following + * tree of nested items: + * + * WGDEVICE_A_IFINDEX: NLA_U32 + * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1 + * WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN + * WGDEVICE_A_PUBLIC_KEY: len WG_KEY_LEN + * WGDEVICE_A_LISTEN_PORT: NLA_U16 + * WGDEVICE_A_FWMARK: NLA_U32 + * WGDEVICE_A_PEERS: NLA_NESTED + * 0: NLA_NESTED + * WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN + * WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN + * WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6 + * WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16 + * WGPEER_A_LAST_HANDSHAKE_TIME: struct timespec + * WGPEER_A_RX_BYTES: NLA_U64 + * WGPEER_A_TX_BYTES: NLA_U64 + * WGPEER_A_ALLOWEDIPS: NLA_NESTED + * 0: NLA_NESTED + * WGALLOWEDIP_A_FAMILY: NLA_U16 + * WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr + * WGALLOWEDIP_A_CIDR_MASK: NLA_U8 + * 1: NLA_NESTED + * ... + * 2: NLA_NESTED + * ... + * ... + * 1: NLA_NESTED + * ... + * ... + * + * It is possible that all of the allowed IPs of a single peer will not + * fit within a single netlink message. In that case, the same peer will + * be written in the following message, except it will only contain + * WGPEER_A_PUBLIC_KEY and WGPEER_A_ALLOWEDIPS. This may occur several + * times in a row for the same peer. It is then up to the receiver to + * coalesce adjacent peers. Likewise, it is possible that all peers will + * not fit within a single message. So, subsequent peers will be sent + * in following messages, except those will only contain WGDEVICE_A_IFNAME + * and WGDEVICE_A_PEERS. It is then up to the receiver to coalesce these + * messages to form the complete list of peers. + * + * Since this is an NLA_F_DUMP command, the final message will always be + * NLMSG_DONE, even if an error occurs. However, this NLMSG_DONE message + * contains an integer error code. It is either zero or a negative error + * code corresponding to the errno. + * + * WG_CMD_SET_DEVICE + * ----------------- + * + * May only be called via NLM_F_REQUEST. The command should contain the following + * tree of nested items, containing one but not both of WGDEVICE_A_IFINDEX + * and WGDEVICE_A_IFNAME: + * + * WGDEVICE_A_IFINDEX: NLA_U32 + * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1 + * WGDEVICE_A_FLAGS: NLA_U32, 0 or WGDEVICE_F_REPLACE_PEERS if all current + * peers should be removed prior to adding the list below. + * WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN, all zeros to remove + * WGDEVICE_A_LISTEN_PORT: NLA_U16, 0 to choose randomly + * WGDEVICE_A_FWMARK: NLA_U32, 0 to disable + * WGDEVICE_A_PEERS: NLA_NESTED + * 0: NLA_NESTED + * WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN + * WGPEER_A_FLAGS: NLA_U32, 0 and/or WGPEER_F_REMOVE_ME if the specified peer + * should be removed rather than added/updated and/or + * WGPEER_F_REPLACE_ALLOWEDIPS if all current allowed IPs of + * this peer should be removed prior to adding the list below. + * WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN, all zeros to remove + * WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6 + * WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16, 0 to disable + * WGPEER_A_ALLOWEDIPS: NLA_NESTED + * 0: NLA_NESTED + * WGALLOWEDIP_A_FAMILY: NLA_U16 + * WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr + * WGALLOWEDIP_A_CIDR_MASK: NLA_U8 + * 1: NLA_NESTED + * ... + * 2: NLA_NESTED + * ... + * ... + * 1: NLA_NESTED + * ... + * ... + * + * It is possible that the amount of configuration data exceeds that of + * the maximum message length accepted by the kernel. In that case, + * several messages should be sent one after another, with each + * successive one filling in information not contained in the prior. Note + * that if WGDEVICE_F_REPLACE_PEERS is specified in the first message, it + * probably should not be specified in fragments that come after, so that + * the list of peers is only cleared the first time but appened after. + * Likewise for peers, if WGPEER_F_REPLACE_ALLOWEDIPS is specified in the + * first message of a peer, it likely should not be specified in subsequent + * fragments. + * + * If an error occurs, NLMSG_ERROR will reply containing an errno. + */ + +#define WG_GENL_NAME "wireguard" +#define WG_GENL_VERSION 1 + +#define WG_KEY_LEN 32 + +enum wg_cmd { + WG_CMD_GET_DEVICE, + WG_CMD_SET_DEVICE, + __WG_CMD_MAX +}; +#define WG_CMD_MAX (__WG_CMD_MAX - 1) + +enum wgdevice_flag { + WGDEVICE_F_REPLACE_PEERS = 1U << 0 +}; +enum wgdevice_attribute { + WGDEVICE_A_UNSPEC, + WGDEVICE_A_IFINDEX, + WGDEVICE_A_IFNAME, + WGDEVICE_A_PRIVATE_KEY, + WGDEVICE_A_PUBLIC_KEY, + WGDEVICE_A_FLAGS, + WGDEVICE_A_LISTEN_PORT, + WGDEVICE_A_FWMARK, + WGDEVICE_A_PEERS, + __WGDEVICE_A_LAST +}; +#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1) + +enum wgpeer_flag { + WGPEER_F_REMOVE_ME = 1U << 0, + WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1 +}; +enum wgpeer_attribute { + WGPEER_A_UNSPEC, + WGPEER_A_PUBLIC_KEY, + WGPEER_A_PRESHARED_KEY, + WGPEER_A_FLAGS, + WGPEER_A_ENDPOINT, + WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, + WGPEER_A_LAST_HANDSHAKE_TIME, + WGPEER_A_RX_BYTES, + WGPEER_A_TX_BYTES, + WGPEER_A_ALLOWEDIPS, + __WGPEER_A_LAST +}; +#define WGPEER_A_MAX (__WGPEER_A_LAST - 1) + +enum wgallowedip_attribute { + WGALLOWEDIP_A_UNSPEC, + WGALLOWEDIP_A_FAMILY, + WGALLOWEDIP_A_IPADDR, + WGALLOWEDIP_A_CIDR_MASK, + __WGALLOWEDIP_A_LAST +}; +#define WGALLOWEDIP_A_MAX (__WGALLOWEDIP_A_LAST - 1) diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c index 70659df417..33dc07c5bd 100644 --- a/src/sulogin-shell/sulogin-shell.c +++ b/src/sulogin-shell/sulogin-shell.c @@ -81,24 +81,19 @@ static int start_default_target(sd_bus *bus) { static int fork_wait(const char* const cmdline[]) { pid_t pid; + int r; - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "fork(): %m"); - if (pid == 0) { - + r = safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { /* Child */ - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - execv(cmdline[0], (char**) cmdline); log_error_errno(errno, "Failed to execute %s: %m", cmdline[0]); _exit(EXIT_FAILURE); /* Operational error */ } - return wait_for_terminate_and_warn(cmdline[0], pid, false); + return wait_for_terminate_and_check(cmdline[0], pid, WAIT_LOG_ABNORMAL); } static void print_mode(const char* mode) { diff --git a/src/system-update-generator/system-update-generator.c b/src/system-update-generator/system-update-generator.c index 1796bae340..ec05e7b9e6 100644 --- a/src/system-update-generator/system-update-generator.c +++ b/src/system-update-generator/system-update-generator.c @@ -79,7 +79,8 @@ int main(int argc, char *argv[]) { if (argc > 1) arg_dest = argv[2]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 18c64241ba..5732d88a17 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -84,6 +84,7 @@ #include "stat-util.h" #include "strv.h" #include "terminal-util.h" +#include "unit-def.h" #include "unit-name.h" #include "user-util.h" #include "util.h" @@ -332,7 +333,7 @@ static bool install_client_side(void) { /* Decides when to execute enable/disable/... operations * client-side rather than server-side. */ - if (running_in_chroot() > 0) + if (running_in_chroot_or_offline()) return true; if (sd_booted() <= 0) @@ -2649,55 +2650,32 @@ static int unit_find_paths( static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *active_state) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; - _cleanup_free_ char *buf = NULL; + _cleanup_free_ char *buf = NULL, *path = NULL; UnitActiveState state; - const char *path; int r; assert(name); assert(active_state); - /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it - * isn't loaded. */ - r = sd_bus_call_method( + path = unit_dbus_path_from_name(name); + if (!path) + return log_oom(); + + r = sd_bus_get_property_string( bus, "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "GetUnit", + path, + "org.freedesktop.systemd1.Unit", + "ActiveState", &error, - &reply, - "s", name); - if (r < 0) { - if (!sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT)) - return log_error_errno(r, "Failed to retrieve unit: %s", bus_error_message(&error, r)); - - /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are - * considered inactive. */ - state = UNIT_INACTIVE; - - } else { - r = sd_bus_message_read(reply, "o", &path); - if (r < 0) - return bus_log_parse_error(r); - - r = sd_bus_get_property_string( - bus, - "org.freedesktop.systemd1", - path, - "org.freedesktop.systemd1.Unit", - "ActiveState", - &error, - &buf); - if (r < 0) - return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); + &buf); + if (r < 0) + return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); - state = unit_active_state_from_string(buf); - if (state == _UNIT_ACTIVE_STATE_INVALID) { - log_error("Invalid unit state '%s' for: %s", buf, name); - return -EINVAL; - } + state = unit_active_state_from_string(buf); + if (state == _UNIT_ACTIVE_STATE_INVALID) { + log_error("Invalid unit state '%s' for: %s", buf, name); + return -EINVAL; } *active_state = state; @@ -2904,7 +2882,6 @@ static int start_unit_one( if (wait_context) { _cleanup_free_ char *unit_path = NULL; - const char* mt; log_debug("Watching for property changes of %s", name); r = sd_bus_call_method( @@ -2927,13 +2904,15 @@ static int start_unit_one( if (r < 0) return log_error_errno(r, "Failed to add unit path %s to set: %m", unit_path); - mt = strjoina("type='signal'," - "interface='org.freedesktop.DBus.Properties'," - "path='", unit_path, "'," - "member='PropertiesChanged'"); - r = sd_bus_add_match(bus, &wait_context->match, mt, on_properties_changed, wait_context); + r = sd_bus_match_signal_async(bus, + &wait_context->match, + NULL, + unit_path, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + on_properties_changed, NULL, wait_context); if (r < 0) - return log_error_errno(r, "Failed to add match for PropertiesChanged signal: %m"); + return log_error_errno(r, "Failed to request match for PropertiesChanged signal: %m"); } log_debug("%s manager for %s on %s, %s", @@ -3149,22 +3128,21 @@ static int start_unit(int argc, char *argv[], void *userdata) { } if (arg_wait) { - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - wait_context.unit_paths = set_new(&string_hash_ops); if (!wait_context.unit_paths) return log_oom(); - r = sd_bus_call_method( + r = sd_bus_call_method_async( bus, + NULL, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Subscribe", - &error, - NULL, NULL); + NULL, NULL, + NULL); if (r < 0) - return log_error_errno(r, "Failed to enable subscription: %s", bus_error_message(&error, r)); + return log_error_errno(r, "Failed to enable subscription: %m"); r = sd_event_default(&wait_context.event); if (r < 0) return log_error_errno(r, "Failed to allocate event loop: %m"); @@ -3538,10 +3516,10 @@ static int load_kexec_kernel(void) { if (arg_dry_run) return 0; - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - else if (pid == 0) { + r = safe_fork("(kexec)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { const char* const args[] = { KEXEC, @@ -3551,15 +3529,11 @@ static int load_kexec_kernel(void) { NULL }; /* Child */ - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - execv(args[0], (char * const *) args); _exit(EXIT_FAILURE); - } else - return wait_for_terminate_and_warn("kexec", pid, true); + } + + return wait_for_terminate_and_check("kexec", pid, WAIT_LOG); } static int set_exit_code(uint8_t code) { @@ -4044,7 +4018,8 @@ static void print_status_info( if (i->load_error != 0) printf(" Loaded: %s%s%s (Reason: %s)\n", on, strna(i->load_state), off, i->load_error); - else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset)) + else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset) && + !STR_IN_SET(i->unit_file_state, "generated", "transient")) printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n", on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset); else if (path && !isempty(i->unit_file_state)) @@ -5582,6 +5557,7 @@ static int set_property(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *n = NULL; + UnitType t; sd_bus *bus; int r; @@ -5605,6 +5581,12 @@ static int set_property(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); + t = unit_name_to_type(n); + if (t < 0) { + log_error("Invalid unit type: %s", n); + return -EINVAL; + } + r = sd_bus_message_append(m, "sb", n, arg_runtime); if (r < 0) return bus_log_create_error(r); @@ -5613,7 +5595,7 @@ static int set_property(int argc, char *argv[], void *userdata) { if (r < 0) return bus_log_create_error(r); - r = bus_append_unit_property_assignment_many(m, strv_skip(argv, 2)); + r = bus_append_unit_property_assignment_many(m, t, strv_skip(argv, 2)); if (r < 0) return r; @@ -6060,7 +6042,6 @@ static int enable_sysv_units(const char *verb, char **args) { _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL; bool found_native = false, found_sysv; - siginfo_t status; const char *name; unsigned c = 1; pid_t pid; @@ -6114,41 +6095,31 @@ static int enable_sysv_units(const char *verb, char **args) { if (!arg_quiet) log_info("Executing: %s", l); - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - else if (pid == 0) { + j = safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); + if (j < 0) + return j; + if (j == 0) { /* Child */ - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - execv(argv[0], (char**) argv); log_error_errno(errno, "Failed to execute %s: %m", argv[0]); _exit(EXIT_FAILURE); } - j = wait_for_terminate(pid, &status); + j = wait_for_terminate_and_check("sysv-install", pid, WAIT_LOG_ABNORMAL); if (j < 0) - return log_error_errno(j, "Failed to wait for child: %m"); - - if (status.si_code == CLD_EXITED) { - if (streq(verb, "is-enabled")) { - if (status.si_status == 0) { - if (!arg_quiet) - puts("enabled"); - r = 1; - } else { - if (!arg_quiet) - puts("disabled"); - } + return j; + if (streq(verb, "is-enabled")) { + if (j == EXIT_SUCCESS) { + if (!arg_quiet) + puts("enabled"); + r = 1; + } else { + if (!arg_quiet) + puts("disabled"); + } - } else if (status.si_status != 0) - return -EBADE; /* We don't warn here, under the assumption the script already showed an explanation */ - } else { - log_error("Unexpected waitid() result."); - return -EPROTO; - } + } else if (j != EXIT_SUCCESS) + return -EBADE; /* We don't warn here, under the assumption the script already showed an explanation */ if (found_native) continue; @@ -6253,7 +6224,6 @@ static int normalize_names(char **names, bool warn_if_path) { } static int unit_exists(LookupPaths *lp, const char *unit) { - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *path = NULL; static const struct bus_properties_map property_map[] = { @@ -6276,22 +6246,10 @@ static int unit_exists(LookupPaths *lp, const char *unit) { if (r < 0) return r; - r = sd_bus_call_method( - bus, - "org.freedesktop.systemd1", - path, - "org.freedesktop.DBus.Properties", - "GetAll", - &error, - &reply, - "s", ""); + r = bus_map_all_properties(bus, "org.freedesktop.systemd1", path, property_map, &error, &info); if (r < 0) return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r)); - r = bus_message_map_all_properties(reply, property_map, &error, &info); - if (r < 0) - return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r)); - return !streq_ptr(info.load_state, "not-found") || !streq_ptr(info.active_state, "inactive"); } @@ -6986,25 +6944,20 @@ static int unit_file_create_copy( } static int run_editor(char **paths) { - pid_t pid; int r; assert(paths); - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - - if (pid == 0) { + r = safe_fork("(editor)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL); + if (r < 0) + return r; + if (r == 0) { const char **args; char *editor, **editor_args = NULL; char **tmp_path, **original_path, *p; unsigned n_editor_args = 0, i = 1; size_t argc; - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - argc = strv_length(paths)/2 + 1; /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL @@ -7060,10 +7013,6 @@ static int run_editor(char **paths) { _exit(EXIT_FAILURE); } - r = wait_for_terminate_and_warn("editor", pid, true); - if (r < 0) - return log_error_errno(r, "Failed to wait for child: %m"); - return 0; } @@ -8380,7 +8329,7 @@ static int talk_initctl(void) { request.runlevel = rl; - fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY); + fd = open(INIT_FIFO, O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY); if (fd < 0) { if (errno == ENOENT) return 0; @@ -8401,72 +8350,72 @@ static int talk_initctl(void) { static int systemctl_main(int argc, char *argv[]) { static const Verb verbs[] = { - { "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_NOCHROOT, list_units }, - { "list-unit-files", VERB_ANY, VERB_ANY, 0, list_unit_files }, - { "list-sockets", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_sockets }, - { "list-timers", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_timers }, - { "list-jobs", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_jobs }, - { "list-machines", VERB_ANY, VERB_ANY, VERB_NOCHROOT|VERB_MUSTBEROOT, list_machines }, - { "clear-jobs", VERB_ANY, 1, VERB_NOCHROOT, trivial_method }, - { "cancel", VERB_ANY, VERB_ANY, VERB_NOCHROOT, cancel_job }, - { "start", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, - { "stop", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, - { "condstop", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with ALTLinux */ - { "reload", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, - { "restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, - { "try-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, - { "reload-or-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, - { "reload-or-try-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatbility with old systemctl <= 228 */ - { "try-reload-or-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, - { "force-reload", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with SysV */ - { "condreload", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with ALTLinux */ - { "condrestart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with RH */ - { "isolate", 2, 2, VERB_NOCHROOT, start_unit }, - { "kill", 2, VERB_ANY, VERB_NOCHROOT, kill_unit }, - { "is-active", 2, VERB_ANY, VERB_NOCHROOT, check_unit_active }, - { "check", 2, VERB_ANY, VERB_NOCHROOT, check_unit_active }, - { "is-failed", 2, VERB_ANY, VERB_NOCHROOT, check_unit_failed }, - { "show", VERB_ANY, VERB_ANY, VERB_NOCHROOT, show }, - { "cat", 2, VERB_ANY, VERB_NOCHROOT, cat }, - { "status", VERB_ANY, VERB_ANY, VERB_NOCHROOT, show }, - { "help", VERB_ANY, VERB_ANY, VERB_NOCHROOT, show }, - { "daemon-reload", VERB_ANY, 1, VERB_NOCHROOT, daemon_reload }, - { "daemon-reexec", VERB_ANY, 1, VERB_NOCHROOT, daemon_reload }, - { "show-environment", VERB_ANY, 1, VERB_NOCHROOT, show_environment }, - { "set-environment", 2, VERB_ANY, VERB_NOCHROOT, set_environment }, - { "unset-environment", 2, VERB_ANY, VERB_NOCHROOT, set_environment }, - { "import-environment", VERB_ANY, VERB_ANY, VERB_NOCHROOT, import_environment }, - { "halt", VERB_ANY, 1, VERB_NOCHROOT, start_system_special }, - { "poweroff", VERB_ANY, 1, VERB_NOCHROOT, start_system_special }, - { "reboot", VERB_ANY, 2, VERB_NOCHROOT, start_system_special }, - { "kexec", VERB_ANY, 1, VERB_NOCHROOT, start_system_special }, - { "suspend", VERB_ANY, 1, VERB_NOCHROOT, start_system_special }, - { "hibernate", VERB_ANY, 1, VERB_NOCHROOT, start_system_special }, - { "hybrid-sleep", VERB_ANY, 1, VERB_NOCHROOT, start_system_special }, - { "default", VERB_ANY, 1, VERB_NOCHROOT, start_special }, - { "rescue", VERB_ANY, 1, VERB_NOCHROOT, start_system_special }, - { "emergency", VERB_ANY, 1, VERB_NOCHROOT, start_system_special }, - { "exit", VERB_ANY, 2, VERB_NOCHROOT, start_special }, - { "reset-failed", VERB_ANY, VERB_ANY, VERB_NOCHROOT, reset_failed }, - { "enable", 2, VERB_ANY, 0, enable_unit }, - { "disable", 2, VERB_ANY, 0, enable_unit }, - { "is-enabled", 2, VERB_ANY, 0, unit_is_enabled }, - { "reenable", 2, VERB_ANY, 0, enable_unit }, - { "preset", 2, VERB_ANY, 0, enable_unit }, - { "preset-all", VERB_ANY, 1, 0, preset_all }, - { "mask", 2, VERB_ANY, 0, enable_unit }, - { "unmask", 2, VERB_ANY, 0, enable_unit }, - { "link", 2, VERB_ANY, 0, enable_unit }, - { "revert", 2, VERB_ANY, 0, enable_unit }, - { "switch-root", 2, VERB_ANY, VERB_NOCHROOT, switch_root }, - { "list-dependencies", VERB_ANY, 2, VERB_NOCHROOT, list_dependencies }, - { "set-default", 2, 2, 0, set_default }, - { "get-default", VERB_ANY, 1, 0, get_default }, - { "set-property", 3, VERB_ANY, VERB_NOCHROOT, set_property }, - { "is-system-running", VERB_ANY, 1, 0, is_system_running }, - { "add-wants", 3, VERB_ANY, 0, add_dependency }, - { "add-requires", 3, VERB_ANY, 0, add_dependency }, - { "edit", 2, VERB_ANY, VERB_NOCHROOT, edit }, + { "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_units }, + { "list-unit-files", VERB_ANY, VERB_ANY, 0, list_unit_files }, + { "list-sockets", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_sockets }, + { "list-timers", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_timers }, + { "list-jobs", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_jobs }, + { "list-machines", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY|VERB_MUST_BE_ROOT, list_machines }, + { "clear-jobs", VERB_ANY, 1, VERB_ONLINE_ONLY, trivial_method }, + { "cancel", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, cancel_job }, + { "start", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, + { "stop", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, + { "condstop", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatibility with ALTLinux */ + { "reload", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, + { "restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, + { "try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, + { "reload-or-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, + { "reload-or-try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatbility with old systemctl <= 228 */ + { "try-reload-or-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, + { "force-reload", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatibility with SysV */ + { "condreload", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatibility with ALTLinux */ + { "condrestart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatibility with RH */ + { "isolate", 2, 2, VERB_ONLINE_ONLY, start_unit }, + { "kill", 2, VERB_ANY, VERB_ONLINE_ONLY, kill_unit }, + { "is-active", 2, VERB_ANY, VERB_ONLINE_ONLY, check_unit_active }, + { "check", 2, VERB_ANY, VERB_ONLINE_ONLY, check_unit_active }, /* deprecated alias of is-active */ + { "is-failed", 2, VERB_ANY, VERB_ONLINE_ONLY, check_unit_failed }, + { "show", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show }, + { "cat", 2, VERB_ANY, VERB_ONLINE_ONLY, cat }, + { "status", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show }, + { "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show }, + { "daemon-reload", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload }, + { "daemon-reexec", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload }, + { "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, show_environment }, + { "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment }, + { "unset-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment }, + { "import-environment", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, import_environment }, + { "halt", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special }, + { "poweroff", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special }, + { "reboot", VERB_ANY, 2, VERB_ONLINE_ONLY, start_system_special }, + { "kexec", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special }, + { "suspend", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special }, + { "hibernate", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special }, + { "hybrid-sleep", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special }, + { "default", VERB_ANY, 1, VERB_ONLINE_ONLY, start_special }, + { "rescue", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special }, + { "emergency", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special }, + { "exit", VERB_ANY, 2, VERB_ONLINE_ONLY, start_special }, + { "reset-failed", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, reset_failed }, + { "enable", 2, VERB_ANY, 0, enable_unit }, + { "disable", 2, VERB_ANY, 0, enable_unit }, + { "is-enabled", 2, VERB_ANY, 0, unit_is_enabled }, + { "reenable", 2, VERB_ANY, 0, enable_unit }, + { "preset", 2, VERB_ANY, 0, enable_unit }, + { "preset-all", VERB_ANY, 1, 0, preset_all }, + { "mask", 2, VERB_ANY, 0, enable_unit }, + { "unmask", 2, VERB_ANY, 0, enable_unit }, + { "link", 2, VERB_ANY, 0, enable_unit }, + { "revert", 2, VERB_ANY, 0, enable_unit }, + { "switch-root", 2, VERB_ANY, VERB_ONLINE_ONLY, switch_root }, + { "list-dependencies", VERB_ANY, 2, VERB_ONLINE_ONLY, list_dependencies }, + { "set-default", 2, 2, 0, set_default }, + { "get-default", VERB_ANY, 1, 0, get_default }, + { "set-property", 3, VERB_ANY, VERB_ONLINE_ONLY, set_property }, + { "is-system-running", VERB_ANY, 1, 0, is_system_running }, + { "add-wants", 3, VERB_ANY, 0, add_dependency }, + { "add-requires", 3, VERB_ANY, 0, add_dependency }, + { "edit", 2, VERB_ANY, VERB_ONLINE_ONLY, edit }, {} }; diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index c5c7096d55..82e7d445d2 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -33,6 +33,10 @@ _SD_BEGIN_DECLARATIONS; +#define SD_BUS_DEFAULT ((sd_bus *) 1) +#define SD_BUS_DEFAULT_USER ((sd_bus *) 2) +#define SD_BUS_DEFAULT_SYSTEM ((sd_bus *) 3) + /* Types */ typedef struct sd_bus sd_bus; @@ -150,8 +154,14 @@ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b); int sd_bus_get_allow_interactive_authorization(sd_bus *bus); int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b); int sd_bus_get_exit_on_disconnect(sd_bus *bus); +int sd_bus_set_watch_bind(sd_bus *bus, int b); +int sd_bus_get_watch_bind(sd_bus *bus); +int sd_bus_set_connected_signal(sd_bus *bus, int b); +int sd_bus_get_connected_signal(sd_bus *bus); +int sd_bus_set_sender(sd_bus *bus, const char *sender); +int sd_bus_get_sender(sd_bus *bus, const char **ret); -int sd_bus_start(sd_bus *ret); +int sd_bus_start(sd_bus *bus); int sd_bus_try_close(sd_bus *bus); void sd_bus_close(sd_bus *bus); @@ -163,6 +173,7 @@ sd_bus *sd_bus_flush_close_unref(sd_bus *bus); void sd_bus_default_flush_close(void); int sd_bus_is_open(sd_bus *bus); +int sd_bus_is_ready(sd_bus *bus); int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id); int sd_bus_get_scope(sd_bus *bus, const char **scope); @@ -193,6 +204,7 @@ sd_event *sd_bus_get_event(sd_bus *bus); int sd_bus_add_filter(sd_bus *bus, sd_bus_slot **slot, sd_bus_message_handler_t callback, void *userdata); int sd_bus_add_match(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_add_match_async(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata); int sd_bus_add_object(sd_bus *bus, sd_bus_slot **slot, const char *path, sd_bus_message_handler_t callback, void *userdata); int sd_bus_add_fallback(sd_bus *bus, sd_bus_slot **slot, const char *prefix, sd_bus_message_handler_t callback, void *userdata); int sd_bus_add_object_vtable(sd_bus *bus, sd_bus_slot **slot, const char *path, const char *interface, const sd_bus_vtable *vtable, void *userdata); @@ -267,6 +279,7 @@ int sd_bus_message_set_auto_start(sd_bus_message *m, int b); int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b); int sd_bus_message_set_destination(sd_bus_message *m, const char *destination); +int sd_bus_message_set_sender(sd_bus_message *m, const char *sender); int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority); int sd_bus_message_append(sd_bus_message *m, const char *types, ...); @@ -300,7 +313,9 @@ int sd_bus_message_rewind(sd_bus_message *m, int complete); int sd_bus_get_unique_name(sd_bus *bus, const char **unique); int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags); +int sd_bus_request_name_async(sd_bus *bus, sd_bus_slot **ret_slot, const char *name, uint64_t flags, sd_bus_message_handler_t callback, void *userdata); int sd_bus_release_name(sd_bus *bus, const char *name); +int sd_bus_release_name_async(sd_bus *bus, sd_bus_slot **ret_slot, const char *name, sd_bus_message_handler_t callback, void *userdata); int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable); /* free the results */ int sd_bus_get_name_creds(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **creds); /* unref the result! */ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine); @@ -336,6 +351,9 @@ int sd_bus_emit_interfaces_removed(sd_bus *bus, const char *path, const char *in int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **creds); int sd_bus_query_sender_privilege(sd_bus_message *call, int capability); +int sd_bus_match_signal(sd_bus *bus, sd_bus_slot **ret, const char *sender, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const char *sender, const char *path, const char *interface, const char *member, sd_bus_message_handler_t match_callback, sd_bus_message_handler_t add_callback, void *userdata); + /* Credential handling */ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t creds_mask); diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h index 37803c71d8..cadb32a051 100644 --- a/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/sd-dhcp6-client.h @@ -23,6 +23,7 @@ #include <inttypes.h> #include <net/ethernet.h> +#include <stdbool.h> #include <sys/types.h> #include "sd-dhcp6-lease.h" @@ -64,6 +65,8 @@ enum { SD_DHCP6_OPTION_DNS_SERVERS = 23, /* RFC 3646 */ SD_DHCP6_OPTION_DOMAIN_LIST = 24, /* RFC 3646 */ + SD_DHCP6_OPTION_IA_PD = 25, /* RFC 3633, prefix delegation */ + SD_DHCP6_OPTION_IA_PD_PREFIX = 26, /* RFC 3633, prefix delegation */ SD_DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075, deprecated */ @@ -116,6 +119,8 @@ int sd_dhcp6_client_get_information_request( int sd_dhcp6_client_set_request_option( sd_dhcp6_client *client, uint16_t option); +int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client, + bool delegation); int sd_dhcp6_client_get_lease( sd_dhcp6_client *client, diff --git a/src/systemd/sd-dhcp6-lease.h b/src/systemd/sd-dhcp6-lease.h index 5807b1836b..22a5f8ce75 100644 --- a/src/systemd/sd-dhcp6-lease.h +++ b/src/systemd/sd-dhcp6-lease.h @@ -36,6 +36,11 @@ int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *addr, uint32_t *lifetime_preferred, uint32_t *lifetime_valid); +void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease *lease); +int sd_dhcp6_lease_get_pd(sd_dhcp6_lease *lease, struct in6_addr *prefix, + uint8_t *prefix_len, + uint32_t *lifetime_preferred, + uint32_t *lifetime_valid); int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, struct in6_addr **addrs); int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***domains); diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h index 9083d5fa9e..ec4b7bcf69 100644 --- a/src/systemd/sd-event.h +++ b/src/systemd/sd-event.h @@ -26,6 +26,7 @@ #include <sys/epoll.h> #include <sys/signalfd.h> #include <sys/types.h> +#include <time.h> #include "_sd-common.h" @@ -40,6 +41,8 @@ _SD_BEGIN_DECLARATIONS; +#define SD_EVENT_DEFAULT ((sd_event *) 1) + typedef struct sd_event sd_event; typedef struct sd_event_source sd_event_source; @@ -124,6 +127,8 @@ int sd_event_source_get_enabled(sd_event_source *s, int *enabled); int sd_event_source_set_enabled(sd_event_source *s, int enabled); int sd_event_source_get_io_fd(sd_event_source *s); int sd_event_source_set_io_fd(sd_event_source *s, int fd); +int sd_event_source_get_io_fd_own(sd_event_source *s); +int sd_event_source_set_io_fd_own(sd_event_source *s, int own); int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events); int sd_event_source_set_io_events(sd_event_source *s, uint32_t events); int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index d6e3816c64..e742807e92 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -34,7 +34,9 @@ _SD_BEGIN_DECLARATIONS; typedef struct sd_netlink sd_netlink; +typedef struct sd_genl_socket sd_genl_socket; typedef struct sd_netlink_message sd_netlink_message; +typedef enum {SD_GENL_ID_CTRL, SD_GENL_WIREGUARD} sd_genl_family; /* callback */ @@ -94,6 +96,9 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type); int sd_netlink_message_exit_container(sd_netlink_message *m); +int sd_netlink_message_open_array(sd_netlink_message *m, uint16_t type); +int sd_netlink_message_cancel_array(sd_netlink_message *m); + int sd_netlink_message_rewind(sd_netlink_message *m); sd_netlink_message *sd_netlink_message_next(sd_netlink_message *m); @@ -177,6 +182,10 @@ int sd_rtnl_message_routing_policy_rule_get_rtm_type(sd_netlink_message *m, unsi _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink, sd_netlink_unref); _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink_message, sd_netlink_message_unref); +/* genl */ +int sd_genl_socket_open(sd_netlink **nl); +int sd_genl_message_new(sd_netlink *nl, sd_genl_family family, uint8_t cmd, sd_netlink_message **m); + _SD_END_DECLARATIONS; #endif diff --git a/src/systemd/sd-radv.h b/src/systemd/sd-radv.h index 94d5e71e8a..e319a82dbf 100644 --- a/src/systemd/sd-radv.h +++ b/src/systemd/sd-radv.h @@ -24,6 +24,7 @@ #include <inttypes.h> #include <net/ethernet.h> #include <netinet/in.h> +#include <stdbool.h> #include <sys/types.h> #include "sd-ndisc.h" @@ -62,7 +63,9 @@ int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime); int sd_radv_set_managed_information(sd_radv *ra, int managed); int sd_radv_set_other_information(sd_radv *ra, int other); int sd_radv_set_preference(sd_radv *ra, unsigned preference); -int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p); +int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, bool dynamic); +sd_radv_prefix *sd_radv_remove_prefix(sd_radv *ra, struct in6_addr *prefix, + uint8_t prefixlen); int sd_radv_set_rdnss(sd_radv *ra, uint32_t lifetime, const struct in6_addr *dns, size_t n_dns); int sd_radv_set_dnssl(sd_radv *ra, uint32_t lifetime, char **search_list); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index d8009458ee..e06b4b6d5b 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -64,6 +64,7 @@ typedef struct Item { uid_t uid; bool gid_set:1; + bool gid_must_exist:1; bool uid_set:1; bool todo_user:1; @@ -74,9 +75,9 @@ static char *arg_root = NULL; static const char conf_file_dirs[] = CONF_PATHS_NULSTR("sysusers.d"); -static Hashmap *users = NULL, *groups = NULL; -static Hashmap *todo_uids = NULL, *todo_gids = NULL; -static Hashmap *members = NULL; +static OrderedHashmap *users = NULL, *groups = NULL; +static OrderedHashmap *todo_uids = NULL, *todo_gids = NULL; +static OrderedHashmap *members = NULL; static Hashmap *database_uid = NULL, *database_user = NULL; static Hashmap *database_gid = NULL, *database_group = NULL; @@ -256,7 +257,7 @@ static int putgrent_with_members(const struct group *gr, FILE *group) { assert(gr); assert(group); - a = hashmap_get(members, gr->gr_name); + a = ordered_hashmap_get(members, gr->gr_name); if (a) { _cleanup_strv_free_ char **l = NULL; bool added = false; @@ -307,7 +308,7 @@ static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) { assert(sg); assert(gshadow); - a = hashmap_get(members, sg->sg_namp); + a = ordered_hashmap_get(members, sg->sg_namp); if (a) { _cleanup_strv_free_ char **l = NULL; bool added = false; @@ -387,7 +388,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char Item *i; int r; - if (hashmap_size(todo_uids) == 0) + if (ordered_hashmap_size(todo_uids) == 0) return 0; r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp); @@ -405,13 +406,13 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char errno = 0; while ((pw = fgetpwent(original))) { - i = hashmap_get(users, pw->pw_name); + i = ordered_hashmap_get(users, pw->pw_name); if (i && i->todo_user) { log_error("%s: User \"%s\" already exists.", passwd_path, pw->pw_name); return -EEXIST; } - if (hashmap_contains(todo_uids, UID_TO_PTR(pw->pw_uid))) { + if (ordered_hashmap_contains(todo_uids, UID_TO_PTR(pw->pw_uid))) { log_error("%s: Detected collision for UID " UID_FMT ".", passwd_path, pw->pw_uid); return -EEXIST; } @@ -432,7 +433,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char return -errno; } - HASHMAP_FOREACH(i, todo_uids, iterator) { + ORDERED_HASHMAP_FOREACH(i, todo_uids, iterator) { struct passwd n = { .pw_name = i->name, .pw_uid = i->uid, @@ -474,7 +475,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char Item *i; int r; - if (hashmap_size(todo_uids) == 0) + if (ordered_hashmap_size(todo_uids) == 0) return 0; r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp); @@ -494,7 +495,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char errno = 0; while ((sp = fgetspent(original))) { - i = hashmap_get(users, sp->sp_namp); + i = ordered_hashmap_get(users, sp->sp_namp); if (i && i->todo_user) { /* we will update the existing entry */ sp->sp_lstchg = lstchg; @@ -502,7 +503,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char /* only the /etc/shadow stage is left, so we can * safely remove the item from the todo set */ i->todo_user = false; - hashmap_remove(todo_uids, UID_TO_PTR(i->uid)); + ordered_hashmap_remove(todo_uids, UID_TO_PTR(i->uid)); } errno = 0; @@ -521,7 +522,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char return -errno; } - HASHMAP_FOREACH(i, todo_uids, iterator) { + ORDERED_HASHMAP_FOREACH(i, todo_uids, iterator) { struct spwd n = { .sp_namp = i->name, .sp_pwdp = (char*) "!!", @@ -558,7 +559,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** Item *i; int r; - if (hashmap_size(todo_gids) == 0 && hashmap_size(members) == 0) + if (ordered_hashmap_size(todo_gids) == 0 && ordered_hashmap_size(members) == 0) return 0; r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp); @@ -580,13 +581,13 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** * entries anyway here, let's make an extra verification * step that we don't generate duplicate entries. */ - i = hashmap_get(groups, gr->gr_name); + i = ordered_hashmap_get(groups, gr->gr_name); if (i && i->todo_group) { log_error("%s: Group \"%s\" already exists.", group_path, gr->gr_name); return -EEXIST; } - if (hashmap_contains(todo_gids, GID_TO_PTR(gr->gr_gid))) { + if (ordered_hashmap_contains(todo_gids, GID_TO_PTR(gr->gr_gid))) { log_error("%s: Detected collision for GID " GID_FMT ".", group_path, gr->gr_gid); return -EEXIST; } @@ -609,7 +610,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** return -errno; } - HASHMAP_FOREACH(i, todo_gids, iterator) { + ORDERED_HASHMAP_FOREACH(i, todo_gids, iterator) { struct group n = { .gr_name = i->name, .gr_gid = i->gid, @@ -645,7 +646,7 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch Item *i; int r; - if (hashmap_size(todo_gids) == 0 && hashmap_size(members) == 0) + if (ordered_hashmap_size(todo_gids) == 0 && ordered_hashmap_size(members) == 0) return 0; r = fopen_temporary_label("/etc/gshadow", gshadow_path, &gshadow, &gshadow_tmp); @@ -663,7 +664,7 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch errno = 0; while ((sg = fgetsgent(original))) { - i = hashmap_get(groups, sg->sg_namp); + i = ordered_hashmap_get(groups, sg->sg_namp); if (i && i->todo_group) { log_error("%s: Group \"%s\" already exists.", gshadow_path, sg->sg_namp); return -EEXIST; @@ -687,7 +688,7 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch return -errno; } - HASHMAP_FOREACH(i, todo_gids, iterator) { + ORDERED_HASHMAP_FOREACH(i, todo_gids, iterator) { struct sgrp n = { .sg_namp = i->name, .sg_passwd = (char*) "!!", @@ -807,12 +808,12 @@ static int uid_is_ok(uid_t uid, const char *name) { Item *i; /* Let's see if we already have assigned the UID a second time */ - if (hashmap_get(todo_uids, UID_TO_PTR(uid))) + if (ordered_hashmap_get(todo_uids, UID_TO_PTR(uid))) return 0; /* Try to avoid using uids that are already used by a group * that doesn't have the same name as our new user. */ - i = hashmap_get(todo_gids, GID_TO_PTR(uid)); + i = ordered_hashmap_get(todo_gids, GID_TO_PTR(uid)); if (i && !streq(i->name, name)) return 0; @@ -1012,11 +1013,11 @@ static int add_user(Item *i) { i->uid = search_uid; } - r = hashmap_ensure_allocated(&todo_uids, NULL); + r = ordered_hashmap_ensure_allocated(&todo_uids, NULL); if (r < 0) return log_oom(); - r = hashmap_put(todo_uids, UID_TO_PTR(i->uid), i); + r = ordered_hashmap_put(todo_uids, UID_TO_PTR(i->uid), i); if (r < 0) return log_oom(); @@ -1030,11 +1031,11 @@ static int gid_is_ok(gid_t gid) { struct group *g; struct passwd *p; - if (hashmap_get(todo_gids, GID_TO_PTR(gid))) + if (ordered_hashmap_get(todo_gids, GID_TO_PTR(gid))) return 0; /* Avoid reusing gids that are already used by a different user */ - if (hashmap_get(todo_uids, UID_TO_PTR(gid))) + if (ordered_hashmap_get(todo_uids, UID_TO_PTR(gid))) return 0; if (hashmap_contains(database_gid, GID_TO_PTR(gid))) @@ -1098,6 +1099,18 @@ static int add_group(Item *i) { r = gid_is_ok(i->gid); if (r < 0) return log_error_errno(r, "Failed to verify gid " GID_FMT ": %m", i->gid); + if (i->gid_must_exist) { + /* If we require the gid to already exist we can return here: + * r > 0: means the gid does not exist -> fail + * r == 0: means the gid exists -> nothing more to do. + */ + if (r > 0) { + log_error("Failed to create %s: please create GID %d", i->name, i->gid); + return -EINVAL; + } + if (r == 0) + return 0; + } if (r == 0) { log_debug("Suggested group ID " GID_FMT " for %s already used.", i->gid, i->name); i->gid_set = false; @@ -1157,11 +1170,11 @@ static int add_group(Item *i) { i->gid = search_uid; } - r = hashmap_ensure_allocated(&todo_gids, NULL); + r = ordered_hashmap_ensure_allocated(&todo_gids, NULL); if (r < 0) return log_oom(); - r = hashmap_put(todo_gids, GID_TO_PTR(i->gid), i); + r = ordered_hashmap_put(todo_gids, GID_TO_PTR(i->gid), i); if (r < 0) return log_oom(); @@ -1185,30 +1198,8 @@ static int process_item(Item *i) { return add_user(i); - case ADD_GROUP: { - Item *j; - - j = hashmap_get(users, i->name); - if (j) { - /* There's already user to be created for this - * name, let's process that in one step */ - - if (i->gid_set) { - j->gid = i->gid; - j->gid_set = true; - } - - if (i->gid_path) { - r = free_and_strdup(&j->gid_path, i->gid_path); - if (r < 0) - return log_oom(); - } - - return 0; - } - + case ADD_GROUP: return add_group(i); - } default: assert_not_reached("Unknown item type"); @@ -1237,15 +1228,15 @@ static int add_implicit(void) { /* Implicitly create additional users and groups, if they were listed in "m" lines */ - HASHMAP_FOREACH_KEY(l, g, members, iterator) { + ORDERED_HASHMAP_FOREACH_KEY(l, g, members, iterator) { Item *i; char **m; - i = hashmap_get(groups, g); + i = ordered_hashmap_get(groups, g); if (!i) { _cleanup_(item_freep) Item *j = NULL; - r = hashmap_ensure_allocated(&groups, &string_hash_ops); + r = ordered_hashmap_ensure_allocated(&groups, &string_hash_ops); if (r < 0) return log_oom(); @@ -1258,7 +1249,7 @@ static int add_implicit(void) { if (!j->name) return log_oom(); - r = hashmap_put(groups, j->name, j); + r = ordered_hashmap_put(groups, j->name, j); if (r < 0) return log_oom(); @@ -1268,11 +1259,11 @@ static int add_implicit(void) { STRV_FOREACH(m, l) { - i = hashmap_get(users, *m); + i = ordered_hashmap_get(users, *m); if (!i) { _cleanup_(item_freep) Item *j = NULL; - r = hashmap_ensure_allocated(&users, &string_hash_ops); + r = ordered_hashmap_ensure_allocated(&users, &string_hash_ops); if (r < 0) return log_oom(); @@ -1285,7 +1276,7 @@ static int add_implicit(void) { if (!j->name) return log_oom(); - r = hashmap_put(users, j->name, j); + r = ordered_hashmap_put(users, j->name, j); if (r < 0) return log_oom(); @@ -1348,7 +1339,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { _cleanup_free_ char *action = NULL, *name = NULL, *id = NULL, *resolved_name = NULL, *resolved_id = NULL, *description = NULL, *home = NULL; _cleanup_(item_freep) Item *i = NULL; Item *existing; - Hashmap *h; + OrderedHashmap *h; int r; const char *p; @@ -1494,11 +1485,11 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { return -EINVAL; } - r = hashmap_ensure_allocated(&members, &string_hash_ops); + r = ordered_hashmap_ensure_allocated(&members, &string_hash_ops); if (r < 0) return log_oom(); - l = hashmap_get(members, resolved_id); + l = ordered_hashmap_get(members, resolved_id); if (l) { /* A list for this group name already exists, let's append to it */ r = strv_push(&l, resolved_name); @@ -1507,7 +1498,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { resolved_name = NULL; - assert_se(hashmap_update(members, resolved_id, l) >= 0); + assert_se(ordered_hashmap_update(members, resolved_id, l) >= 0); } else { /* No list for this group name exists yet, create one */ @@ -1518,7 +1509,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { l[0] = resolved_name; l[1] = NULL; - r = hashmap_put(members, resolved_id, l); + r = ordered_hashmap_put(members, resolved_id, l); if (r < 0) { free(l); return log_oom(); @@ -1536,7 +1527,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { return -EINVAL; } - r = hashmap_ensure_allocated(&users, &string_hash_ops); + r = ordered_hashmap_ensure_allocated(&users, &string_hash_ops); if (r < 0) return log_oom(); @@ -1551,11 +1542,18 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { path_kill_slashes(i->uid_path); } else { - r = parse_uid(resolved_id, &i->uid); - if (r < 0) { - log_error("Failed to parse UID: %s", id); - return -EBADMSG; + _cleanup_free_ char *uid = NULL, *gid = NULL; + if (split_pair(resolved_id, ":", &uid, &gid) == 0) { + r = parse_gid(gid, &i->gid); + if (r < 0) + return log_error_errno(r, "Failed to parse GID: '%s': %m", id); + i->gid_set = true; + i->gid_must_exist = true; + free_and_replace(resolved_id, uid); } + r = parse_uid(resolved_id, &i->uid); + if (r < 0) + return log_error_errno(r, "Failed to parse UID: '%s': %m", id); i->uid_set = true; } @@ -1586,7 +1584,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { return -EINVAL; } - r = hashmap_ensure_allocated(&groups, &string_hash_ops); + r = ordered_hashmap_ensure_allocated(&groups, &string_hash_ops); if (r < 0) return log_oom(); @@ -1602,10 +1600,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { path_kill_slashes(i->gid_path); } else { r = parse_gid(resolved_id, &i->gid); - if (r < 0) { - log_error("Failed to parse GID: %s", id); - return -EBADMSG; - } + if (r < 0) + return log_error_errno(r, "Failed to parse GID: '%s': %m", id); i->gid_set = true; } @@ -1622,7 +1618,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { i->name = resolved_name; resolved_name = NULL; - existing = hashmap_get(h, i->name); + existing = ordered_hashmap_get(h, i->name); if (existing) { /* Two identical items are fine */ @@ -1632,7 +1628,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { return 0; } - r = hashmap_put(h, i->name, i); + r = ordered_hashmap_put(h, i->name, i); if (r < 0) return log_oom(); @@ -1853,10 +1849,10 @@ int main(int argc, char *argv[]) { goto finish; } - HASHMAP_FOREACH(i, groups, iterator) + ORDERED_HASHMAP_FOREACH(i, groups, iterator) process_item(i); - HASHMAP_FOREACH(i, users, iterator) + ORDERED_HASHMAP_FOREACH(i, users, iterator) process_item(i); r = write_files(); @@ -1864,17 +1860,17 @@ int main(int argc, char *argv[]) { log_error_errno(r, "Failed to write files: %m"); finish: - hashmap_free_with_destructor(groups, item_free); - hashmap_free_with_destructor(users, item_free); + ordered_hashmap_free_with_destructor(groups, item_free); + ordered_hashmap_free_with_destructor(users, item_free); - while ((n = hashmap_first_key(members))) { - strv_free(hashmap_steal_first(members)); + while ((n = ordered_hashmap_first_key(members))) { + strv_free(ordered_hashmap_steal_first(members)); free(n); } - hashmap_free(members); + ordered_hashmap_free(members); - hashmap_free(todo_uids); - hashmap_free(todo_gids); + ordered_hashmap_free(todo_uids); + ordered_hashmap_free(todo_gids); free_database(database_user, database_uid); free_database(database_group, database_gid); diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c index 51306b5625..087ba08559 100644 --- a/src/sysv-generator/sysv-generator.c +++ b/src/sysv-generator/sysv-generator.c @@ -950,7 +950,8 @@ int main(int argc, char *argv[]) { if (argc > 1) arg_dest = argv[3]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); diff --git a/src/test/meson.build b/src/test/meson.build index 6bb5bd629e..1db8aa107d 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -67,7 +67,7 @@ tests += [ 'src/test/test-helper.c'], [libcore, libudev, - libsystemd_internal], + libshared], [threads, librt, libseccomp, @@ -119,6 +119,7 @@ tests += [ [['src/test/test-dns-domain.c'], [libcore, + libshared, libsystemd_network], []], @@ -167,7 +168,7 @@ tests += [ []], [['src/test/test-copy.c'], - [libshared_static], + [], []], [['src/test/test-sigbus.c'], @@ -376,6 +377,17 @@ tests += [ libselinux, libblkid]], + [['src/test/test-watch-pid.c', + 'src/test/test-helper.c'], + [libcore, + libshared], + [libmount, + threads, + librt, + libseccomp, + libselinux, + libblkid]], + [['src/test/test-hashmap.c', 'src/test/test-hashmap-plain.c', test_hashmap_ordered_c], @@ -399,6 +411,10 @@ tests += [ [], []], + [['src/test/test-procfs-util.c'], + [], + []], + [['src/test/test-unaligned.c'], [], []], @@ -410,7 +426,7 @@ tests += [ [libcore, libjournal_core, libudev_core, - libudev_internal, + libudev_static, libsystemd_network, libshared], [threads, @@ -499,7 +515,6 @@ tests += [ [], '', 'manual'], - [['src/test/test-cgroup-mask.c', 'src/test/test-helper.c'], [libcore, @@ -610,7 +625,7 @@ tests += [ [['src/test/test-udev.c'], [libudev_core, - libudev_internal, + libudev_static, libsystemd_network, libshared], [threads, @@ -761,6 +776,10 @@ tests += [ [], [threads]], + [['src/libsystemd/sd-bus/test-bus-watch-bind.c'], + [], + [threads], '', 'timeout=120'], + [['src/libsystemd/sd-bus/test-bus-chat.c'], [], [threads]], @@ -772,7 +791,7 @@ tests += [ [['src/libsystemd/sd-bus/test-bus-error.c'], [libshared_static, - libsystemd_internal], + libsystemd_static], []], [['src/libsystemd/sd-bus/test-bus-track.c'], diff --git a/src/test/test-async.c b/src/test/test-async.c index 2055ce25bf..87906b2e25 100644 --- a/src/test/test-async.c +++ b/src/test/test-async.c @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) { assert_se(asynchronous_job(async_func, NULL) >= 0); - assert_se(asynchronous_sync() >= 0); + assert_se(asynchronous_sync(NULL) >= 0); sleep(1); diff --git a/src/test/test-capability.c b/src/test/test-capability.c index e5db52d404..10cddaf552 100644 --- a/src/test/test-capability.c +++ b/src/test/test-capability.c @@ -80,7 +80,7 @@ static void fork_test(void (*test_func)(void)) { assert_se(pid >= 0); if (pid == 0) { test_func(); - exit(0); + exit(EXIT_SUCCESS); } else if (pid > 0) { int status; diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index 45eb3ef8b1..2248a30635 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -27,6 +27,7 @@ #include "parse-util.h" #include "proc-cmdline.h" #include "process-util.h" +#include "special.h" #include "stat-util.h" #include "string-util.h" #include "test-helper.h" @@ -141,10 +142,10 @@ static void check_p_g_slice(const char *path, int code, const char *result) { static void test_path_get_slice(void) { check_p_g_slice("/user.slice", 0, "user.slice"); - check_p_g_slice("/foobar", 0, "-.slice"); + check_p_g_slice("/foobar", 0, SPECIAL_ROOT_SLICE); check_p_g_slice("/user.slice/user-waldo.slice", 0, "user-waldo.slice"); - check_p_g_slice("", 0, "-.slice"); - check_p_g_slice("foobar", 0, "-.slice"); + check_p_g_slice("", 0, SPECIAL_ROOT_SLICE); + check_p_g_slice("foobar", 0, SPECIAL_ROOT_SLICE); check_p_g_slice("foobar.slice", 0, "foobar.slice"); check_p_g_slice("foo.slice/foo-bar.slice/waldo.service", 0, "foo-bar.slice"); } @@ -165,10 +166,10 @@ static void test_path_get_user_slice(void) { check_p_g_u_slice("foobar.slice", -ENXIO, NULL); check_p_g_u_slice("foo.slice/foo-bar.slice/waldo.service", -ENXIO, NULL); - check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service", 0, "-.slice"); - check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/", 0, "-.slice"); - check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service///", 0, "-.slice"); - check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/waldo.service", 0, "-.slice"); + check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service", 0, SPECIAL_ROOT_SLICE); + check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/", 0, SPECIAL_ROOT_SLICE); + check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service///", 0, SPECIAL_ROOT_SLICE); + check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/waldo.service", 0, SPECIAL_ROOT_SLICE); check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/piep.slice/foo.service", 0, "piep.slice"); check_p_g_u_slice("/foo.slice//foo-bar.slice/user@1000.service/piep.slice//piep-pap.slice//foo.service", 0, "piep-pap.slice"); } @@ -274,7 +275,7 @@ static void test_slice_to_path(void) { test_slice_to_path_one("foobar.slice", "foobar.slice", 0); test_slice_to_path_one("foobar-waldo.slice", "foobar.slice/foobar-waldo.slice", 0); test_slice_to_path_one("foobar-waldo.service", NULL, -EINVAL); - test_slice_to_path_one("-.slice", "", 0); + test_slice_to_path_one(SPECIAL_ROOT_SLICE, "", 0); test_slice_to_path_one("--.slice", NULL, -EINVAL); test_slice_to_path_one("-", NULL, -EINVAL); test_slice_to_path_one("-foo-.slice", NULL, -EINVAL); diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c index 2ae95db162..b2440fc3a9 100644 --- a/src/test/test-cgroup.c +++ b/src/test/test-cgroup.c @@ -23,6 +23,7 @@ #include "cgroup-util.h" #include "path-util.h" +#include "process-util.h" #include "string-util.h" #include "util.h" diff --git a/src/test/test-condition.c b/src/test/test-condition.c index d43db3a7cd..ad64a2bb36 100644 --- a/src/test/test-condition.c +++ b/src/test/test-condition.c @@ -20,6 +20,7 @@ #include <stdio.h> #include <sys/types.h> +#include <sys/utsname.h> #include <unistd.h> #include "sd-id128.h" @@ -28,6 +29,7 @@ #include "apparmor-util.h" #include "architecture.h" #include "audit-util.h" +#include "cgroup-util.h" #include "condition.h" #include "hostname-util.h" #include "id128-util.h" @@ -35,11 +37,13 @@ #include "log.h" #include "macro.h" #include "selinux-util.h" +#include "set.h" #include "smack-util.h" +#include "string-util.h" #include "strv.h" -#include "virt.h" -#include "util.h" #include "user-util.h" +#include "util.h" +#include "virt.h" static void test_condition_test_path(void) { Condition *condition; @@ -125,6 +129,77 @@ static void test_condition_test_path(void) { condition_free(condition); } +static int test_condition_test_control_group_controller(void) { + Condition *condition; + CGroupMask system_mask; + CGroupController controller; + _cleanup_free_ char *controller_name = NULL; + int r; + + r = cg_unified_flush(); + if (r < 0) { + log_notice_errno(r, "Skipping ConditionControlGroupController tests: %m"); + return EXIT_TEST_SKIP; + } + + /* Invalid controllers are ignored */ + condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, true); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + assert_se(cg_mask_supported(&system_mask) >= 0); + + /* Individual valid controllers one by one */ + for (controller = 0; controller < _CGROUP_CONTROLLER_MAX; controller++) { + const char *local_controller_name = cgroup_controller_to_string(controller); + log_info("chosen controller is '%s'", local_controller_name); + if (system_mask & CGROUP_CONTROLLER_TO_MASK(controller)) { + log_info("this controller is available"); + condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + } else { + log_info("this controller is unavailable"); + condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + } + } + + /* Multiple valid controllers at the same time */ + assert_se(cg_mask_to_string(system_mask, &controller_name) >= 0); + + condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, true); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + return EXIT_SUCCESS; +} + static void test_condition_test_ac_power(void) { Condition *condition; @@ -225,6 +300,126 @@ static void test_condition_test_kernel_command_line(void) { condition_free(condition); } +static void test_condition_test_kernel_version(void) { + Condition *condition; + struct utsname u; + const char *v; + + condition = condition_new(CONDITION_KERNEL_VERSION, "*thisreallyshouldntbeinthekernelversion*", false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, "*", false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, "", false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + assert_se(uname(&u) >= 0); + + condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + strshorten(u.release, 4); + strcpy(strchr(u.release, 0), "*"); + + condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + /* 0.1.2 would be a very very very old kernel */ + condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2", false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, ">= 0.1.2", false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, "< 0.1.2", false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, "<= 0.1.2", false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, "= 0.1.2", false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + /* 4711.8.15 is a very very very future kernel */ + condition = condition_new(CONDITION_KERNEL_VERSION, "< 4711.8.15", false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, "<= 4711.8.15", false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, "= 4711.8.15", false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, "> 4711.8.15", false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + condition = condition_new(CONDITION_KERNEL_VERSION, ">= 4711.8.15", false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + assert_se(uname(&u) >= 0); + + v = strjoina(">=", u.release); + condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + v = strjoina("= ", u.release); + condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + v = strjoina("<=", u.release); + condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); + assert_se(condition); + assert_se(condition_test(condition)); + condition_free(condition); + + v = strjoina("> ", u.release); + condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); + + v = strjoina("< ", u.release); + condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); + assert_se(condition); + assert_se(!condition_test(condition)); + condition_free(condition); +} + static void test_condition_test_null(void) { Condition *condition; @@ -483,11 +678,13 @@ int main(int argc, char *argv[]) { test_condition_test_host(); test_condition_test_architecture(); test_condition_test_kernel_command_line(); + test_condition_test_kernel_version(); test_condition_test_null(); test_condition_test_security(); test_condition_test_virtualization(); test_condition_test_user(); test_condition_test_group(); + test_condition_test_control_group_controller(); return 0; } diff --git a/src/test/test-extract-word.c b/src/test/test-extract-word.c index 84ab083e87..3e7c197cfe 100644 --- a/src/test/test-extract-word.c +++ b/src/test/test-extract-word.c @@ -19,6 +19,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <stdlib.h> #include <string.h> diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index 86d963c4c7..9f3a500080 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -22,21 +22,25 @@ #include "alloc-util.h" #include "fd-util.h" +#include "fd-util.h" #include "fileio.h" #include "fs-util.h" +#include "id128-util.h" #include "macro.h" #include "mkdir.h" #include "path-util.h" #include "rm-rf.h" +#include "stdio-util.h" #include "string-util.h" #include "strv.h" +#include "user-util.h" #include "util.h" static void test_chase_symlinks(void) { _cleanup_free_ char *result = NULL; char temp[] = "/tmp/test-chase.XXXXXX"; const char *top, *p, *pslash, *q, *qslash; - int r; + int r, pfd; assert_se(mkdtemp(temp)); @@ -235,6 +239,55 @@ static void test_chase_symlinks(void) { r = chase_symlinks(p, NULL, 0, &result); assert_se(r == -ENOENT); + if (geteuid() == 0) { + p = strjoina(temp, "/priv1"); + assert_se(mkdir(p, 0755) >= 0); + + q = strjoina(p, "/priv2"); + assert_se(mkdir(q, 0755) >= 0); + + assert_se(chase_symlinks(q, NULL, CHASE_SAFE, NULL) >= 0); + + assert_se(chown(q, UID_NOBODY, GID_NOBODY) >= 0); + assert_se(chase_symlinks(q, NULL, CHASE_SAFE, NULL) >= 0); + + assert_se(chown(p, UID_NOBODY, GID_NOBODY) >= 0); + assert_se(chase_symlinks(q, NULL, CHASE_SAFE, NULL) >= 0); + + assert_se(chown(q, 0, 0) >= 0); + assert_se(chase_symlinks(q, NULL, CHASE_SAFE, NULL) == -EPERM); + + assert_se(rmdir(q) >= 0); + assert_se(symlink("/etc/passwd", q) >= 0); + assert_se(chase_symlinks(q, NULL, CHASE_SAFE, NULL) == -EPERM); + + assert_se(chown(p, 0, 0) >= 0); + assert_se(chase_symlinks(q, NULL, CHASE_SAFE, NULL) >= 0); + } + + p = strjoina(temp, "/machine-id-test"); + assert_se(symlink("/usr/../etc/./machine-id", p) >= 0); + + pfd = chase_symlinks(p, NULL, CHASE_OPEN, NULL); + if (pfd != -ENOENT) { + char procfs[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(pfd) + 1]; + _cleanup_close_ int fd = -1; + sd_id128_t a, b; + + assert_se(pfd >= 0); + + xsprintf(procfs, "/proc/self/fd/%i", pfd); + + fd = open(procfs, O_RDONLY|O_CLOEXEC); + assert_se(fd >= 0); + + safe_close(pfd); + + assert_se(id128_read_fd(fd, ID128_PLAIN, &a) >= 0); + assert_se(sd_id128_get_machine(&b) >= 0); + assert_se(sd_id128_equal(a, b)); + } + assert_se(rm_rf(temp, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0); } @@ -273,7 +326,7 @@ static void test_readlink_and_make_absolute(void) { free(r); assert_se(unlink(name_alias) >= 0); - assert_se(pwd = get_current_dir_name()); + assert_se(safe_getcwd(&pwd) >= 0); assert_se(chdir(tempdir) >= 0); assert_se(symlink(name2, name_alias) >= 0); @@ -388,6 +441,92 @@ static void test_access_fd(void) { } } +static void test_touch_file(void) { + uid_t test_uid, test_gid; + _cleanup_(rm_rf_physical_and_freep) char *p = NULL; + struct stat st; + const char *a; + usec_t test_mtime; + + test_uid = geteuid() == 0 ? 65534 : getuid(); + test_gid = geteuid() == 0 ? 65534 : getgid(); + + test_mtime = usec_sub_unsigned(now(CLOCK_REALTIME), USEC_PER_WEEK); + + assert_se(mkdtemp_malloc("/dev/shm/touch-file-XXXXXX", &p) >= 0); + + a = strjoina(p, "/regular"); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); + assert_se(S_ISREG(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + + a = strjoina(p, "/dir"); + assert_se(mkdir(a, 0775) >= 0); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); + assert_se(S_ISDIR(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + + a = strjoina(p, "/fifo"); + assert_se(mkfifo(a, 0775) >= 0); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); + assert_se(S_ISFIFO(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + + a = strjoina(p, "/sock"); + assert_se(mknod(a, 0775 | S_IFSOCK, 0) >= 0); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); + assert_se(S_ISSOCK(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + + if (geteuid() == 0) { + a = strjoina(p, "/cdev"); + assert_se(mknod(a, 0775 | S_IFCHR, makedev(0, 0)) >= 0); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); + assert_se(S_ISCHR(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + + a = strjoina(p, "/bdev"); + assert_se(mknod(a, 0775 | S_IFBLK, makedev(0, 0)) >= 0); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); + assert_se(S_ISBLK(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + } + + a = strjoina(p, "/lnk"); + assert_se(symlink("target", a) >= 0); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); + assert_se(S_ISLNK(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); +} + int main(int argc, char *argv[]) { test_unlink_noerrno(); test_get_files_in_directory(); @@ -396,6 +535,7 @@ int main(int argc, char *argv[]) { test_chase_symlinks(); test_dot_or_dot_dot(); test_access_fd(); + test_touch_file(); return 0; } diff --git a/src/test/test-hash.c b/src/test/test-hash.c index f3b4258d6b..0366727476 100644 --- a/src/test/test-hash.c +++ b/src/test/test-hash.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <stdio.h> #include "alloc-util.h" diff --git a/src/test/test-hexdecoct.c b/src/test/test-hexdecoct.c index 4f19cb406f..3e25a0bac8 100644 --- a/src/test/test-hexdecoct.c +++ b/src/test/test-hexdecoct.c @@ -18,6 +18,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> + #include "alloc-util.h" #include "hexdecoct.h" #include "macro.h" diff --git a/src/test/test-log.c b/src/test/test-log.c index 9468349cba..fd19899480 100644 --- a/src/test/test-log.c +++ b/src/test/test-log.c @@ -23,6 +23,7 @@ #include "format-util.h" #include "log.h" +#include "process-util.h" #include "util.h" assert_cc(LOG_REALM_REMOVE_LEVEL(LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_FTP | LOG_DEBUG)) diff --git a/src/test/test-ns.c b/src/test/test-ns.c index 76e2b38b17..87b4facb85 100644 --- a/src/test/test-ns.c +++ b/src/test/test-ns.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <stdlib.h> #include <unistd.h> diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c index 8259e133c3..9375002133 100644 --- a/src/test/test-parse-util.c +++ b/src/test/test-parse-util.c @@ -19,6 +19,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <locale.h> #include <math.h> diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c index a38f917961..72edcbb7d6 100644 --- a/src/test/test-process-util.c +++ b/src/test/test-process-util.c @@ -38,6 +38,7 @@ #include "macro.h" #include "parse-util.h" #include "process-util.h" +#include "signal-util.h" #include "stdio-util.h" #include "string-util.h" #include "terminal-util.h" @@ -353,7 +354,7 @@ static void test_get_process_cmdline_harder(void) { line = mfree(line); safe_close(fd); - _exit(0); + _exit(EXIT_SUCCESS); } static void test_rename_process_now(const char *p, int ret) { @@ -462,7 +463,7 @@ static void test_getpid_cached(void) { c = getpid(); assert_se(a == b && a == c); - _exit(0); + _exit(EXIT_SUCCESS); } d = raw_getpid(); @@ -497,6 +498,47 @@ static void test_getpid_measure(void) { log_info("getpid_cached(): %llu/s\n", (unsigned long long) (MEASURE_ITERATIONS*USEC_PER_SEC/q)); } +static void test_safe_fork(void) { + siginfo_t status; + pid_t pid; + int r; + + BLOCK_SIGNALS(SIGCHLD); + + r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_NULL_STDIO|FORK_REOPEN_LOG, &pid); + assert_se(r >= 0); + + if (r == 0) { + /* child */ + usleep(100 * USEC_PER_MSEC); + + _exit(88); + } + + assert_se(wait_for_terminate(pid, &status) >= 0); + assert_se(status.si_code == CLD_EXITED); + assert_se(status.si_status == 88); +} + +static void test_pid_to_ptr(void) { + + assert_se(PTR_TO_PID(NULL) == 0); + assert_se(PID_TO_PTR(0) == NULL); + + assert_se(PTR_TO_PID(PID_TO_PTR(1)) == 1); + assert_se(PTR_TO_PID(PID_TO_PTR(2)) == 2); + assert_se(PTR_TO_PID(PID_TO_PTR(-1)) == -1); + assert_se(PTR_TO_PID(PID_TO_PTR(-2)) == -2); + + assert_se(PTR_TO_PID(PID_TO_PTR(INT16_MAX)) == INT16_MAX); + assert_se(PTR_TO_PID(PID_TO_PTR(INT16_MIN)) == INT16_MIN); + +#if SIZEOF_PID_T >= 4 + assert_se(PTR_TO_PID(PID_TO_PTR(INT32_MAX)) == INT32_MAX); + assert_se(PTR_TO_PID(PID_TO_PTR(INT32_MIN)) == INT32_MIN); +#endif +} + int main(int argc, char *argv[]) { log_set_max_level(LOG_DEBUG); @@ -523,6 +565,8 @@ int main(int argc, char *argv[]) { test_rename_process(); test_getpid_cached(); test_getpid_measure(); + test_safe_fork(); + test_pid_to_ptr(); return 0; } diff --git a/src/test/test-procfs-util.c b/src/test/test-procfs-util.c new file mode 100644 index 0000000000..a253182517 --- /dev/null +++ b/src/test/test-procfs-util.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include <errno.h> + +#include "log.h" +#include "procfs-util.h" + +int main(int argc, char *argv[]) { + uint64_t v; + int r; + + log_parse_environment(); + log_open(); + + assert_se(procfs_tasks_get_current(&v) >= 0); + log_info("Current number of tasks: %" PRIu64, v); + + assert_se(procfs_tasks_get_limit(&v) >= 0); + log_info("Limit of tasks: %" PRIu64, v); + assert_se(v > 0); + assert_se(procfs_tasks_set_limit(v) >= 0); + + if (v > 100) { + uint64_t w; + r = procfs_tasks_set_limit(v-1); + assert_se(IN_SET(r, 0, -EPERM, -EACCES, -EROFS)); + + assert_se(procfs_tasks_get_limit(&w) >= 0); + assert_se((r == 0 && w == v - 1) || (r < 0 && w == v)); + + assert_se(procfs_tasks_set_limit(v) >= 0); + + assert_se(procfs_tasks_get_limit(&w) >= 0); + assert_se(v == w); + } + + return 0; +} diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c index 36b49ebc71..aed307077e 100644 --- a/src/test/test-seccomp.c +++ b/src/test/test-seccomp.c @@ -141,7 +141,7 @@ static void test_filter_sets(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn(syscall_filter_sets[i].name, pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check(syscall_filter_sets[i].name, pid, WAIT_LOG) == EXIT_SUCCESS); } } @@ -227,7 +227,7 @@ static void test_restrict_namespace(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn("nsseccomp", pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check("nsseccomp", pid, WAIT_LOG) == EXIT_SUCCESS); } static void test_protect_sysctl(void) { @@ -260,7 +260,7 @@ static void test_protect_sysctl(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn("sysctlseccomp", pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check("sysctlseccomp", pid, WAIT_LOG) == EXIT_SUCCESS); } static void test_restrict_address_families(void) { @@ -343,7 +343,7 @@ static void test_restrict_address_families(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn("socketseccomp", pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check("socketseccomp", pid, WAIT_LOG) == EXIT_SUCCESS); } static void test_restrict_realtime(void) { @@ -381,7 +381,7 @@ static void test_restrict_realtime(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn("realtimeseccomp", pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check("realtimeseccomp", pid, WAIT_LOG) == EXIT_SUCCESS); } static void test_memory_deny_write_execute_mmap(void) { @@ -424,7 +424,7 @@ static void test_memory_deny_write_execute_mmap(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn("memoryseccomp-mmap", pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check("memoryseccomp-mmap", pid, WAIT_LOG) == EXIT_SUCCESS); } static void test_memory_deny_write_execute_shmat(void) { @@ -471,7 +471,7 @@ static void test_memory_deny_write_execute_shmat(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn("memoryseccomp-shmat", pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check("memoryseccomp-shmat", pid, WAIT_LOG) == EXIT_SUCCESS); } static void test_restrict_archs(void) { @@ -505,7 +505,7 @@ static void test_restrict_archs(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn("archseccomp", pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check("archseccomp", pid, WAIT_LOG) == EXIT_SUCCESS); } static void test_load_syscall_filter_set_raw(void) { @@ -596,7 +596,7 @@ static void test_load_syscall_filter_set_raw(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn("syscallrawseccomp", pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check("syscallrawseccomp", pid, WAIT_LOG) == EXIT_SUCCESS); } static void test_lock_personality(void) { @@ -643,7 +643,7 @@ static void test_lock_personality(void) { _exit(EXIT_SUCCESS); } - assert_se(wait_for_terminate_and_warn("lockpersonalityseccomp", pid, true) == EXIT_SUCCESS); + assert_se(wait_for_terminate_and_check("lockpersonalityseccomp", pid, WAIT_LOG) == EXIT_SUCCESS); } static void test_filter_sets_ordered(void) { diff --git a/src/test/test-signal-util.c b/src/test/test-signal-util.c index 13a1d2ba1f..f4b19ed69d 100644 --- a/src/test/test-signal-util.c +++ b/src/test/test-signal-util.c @@ -23,6 +23,7 @@ #include "macro.h" #include "signal-util.h" +#include "process-util.h" static void test_block_signals(void) { sigset_t ss; diff --git a/src/test/test-sizeof.c b/src/test/test-sizeof.c index f472edcfa1..aed6db8423 100644 --- a/src/test/test-sizeof.c +++ b/src/test/test-sizeof.c @@ -19,6 +19,7 @@ ***/ #include <stdio.h> +#include <string.h> #include "time-util.h" @@ -62,6 +63,7 @@ int main(void) { info(usec_t); info(__time_t); info(pid_t); + info(uid_t); info(gid_t); info(enum Enum); diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index 6a91baf6d2..d1ab7486ed 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -18,12 +18,17 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <sys/types.h> +#include <unistd.h> +#include <grp.h> + #include "alloc-util.h" #include "async.h" #include "fd-util.h" #include "in-addr-util.h" #include "log.h" #include "macro.h" +#include "process-util.h" #include "socket-util.h" #include "string-util.h" #include "util.h" @@ -474,6 +479,68 @@ static void test_in_addr_is_multicast(void) { assert_se(in_addr_is_multicast(f, &b) == 0); } +static void test_getpeercred_getpeergroups(void) { + int r; + + r = safe_fork("(getpeercred)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL); + assert_se(r >= 0); + + if (r == 0) { + static const gid_t gids[] = { 3, 4, 5, 6, 7 }; + gid_t *test_gids; + _cleanup_free_ gid_t *peer_groups = NULL; + size_t n_test_gids; + uid_t test_uid; + gid_t test_gid; + struct ucred ucred; + int pair[2]; + + if (geteuid() == 0) { + test_uid = 1; + test_gid = 2; + test_gids = (gid_t*) gids; + n_test_gids = ELEMENTSOF(gids); + + assert_se(setgroups(n_test_gids, test_gids) >= 0); + assert_se(setresgid(test_gid, test_gid, test_gid) >= 0); + assert_se(setresuid(test_uid, test_uid, test_uid) >= 0); + + } else { + long ngroups_max; + + test_uid = getuid(); + test_gid = getgid(); + + ngroups_max = sysconf(_SC_NGROUPS_MAX); + assert(ngroups_max > 0); + + test_gids = newa(gid_t, ngroups_max); + + r = getgroups(ngroups_max, test_gids); + assert_se(r >= 0); + n_test_gids = (size_t) r; + } + + assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) >= 0); + + assert_se(getpeercred(pair[0], &ucred) >= 0); + + assert_se(ucred.uid == test_uid); + assert_se(ucred.gid == test_gid); + assert_se(ucred.pid == getpid_cached()); + + r = getpeergroups(pair[0], &peer_groups); + assert_se(r >= 0 || IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT)); + + if (r >= 0) { + assert_se((size_t) r == n_test_gids); + assert_se(memcmp(peer_groups, test_gids, sizeof(gid_t) * n_test_gids) == 0); + } + + safe_close_pair(pair); + } +} + int main(int argc, char *argv[]) { log_set_max_level(LOG_DEBUG); @@ -502,5 +569,7 @@ int main(int argc, char *argv[]) { test_in_addr_is_multicast(); + test_getpeercred_getpeergroups(); + return 0; } diff --git a/src/test/test-strip-tab-ansi.c b/src/test/test-strip-tab-ansi.c index aabb7c40e7..838a6e4db6 100644 --- a/src/test/test-strip-tab-ansi.c +++ b/src/test/test-strip-tab-ansi.c @@ -28,24 +28,24 @@ int main(int argc, char *argv[]) { char *p; assert_se(p = strdup("\tFoobar\tbar\twaldo\t")); - assert_se(strip_tab_ansi(&p, NULL)); + assert_se(strip_tab_ansi(&p, NULL, NULL)); fprintf(stdout, "<%s>\n", p); assert_se(streq(p, " Foobar bar waldo ")); free(p); assert_se(p = strdup(ANSI_HIGHLIGHT "Hello" ANSI_NORMAL ANSI_HIGHLIGHT_RED " world!" ANSI_NORMAL)); - assert_se(strip_tab_ansi(&p, NULL)); + assert_se(strip_tab_ansi(&p, NULL, NULL)); fprintf(stdout, "<%s>\n", p); assert_se(streq(p, "Hello world!")); free(p); assert_se(p = strdup("\x1B[\x1B[\t\x1B[" ANSI_HIGHLIGHT "\x1B[" "Hello" ANSI_NORMAL ANSI_HIGHLIGHT_RED " world!" ANSI_NORMAL)); - assert_se(strip_tab_ansi(&p, NULL)); + assert_se(strip_tab_ansi(&p, NULL, NULL)); assert_se(streq(p, "\x1B[\x1B[ \x1B[\x1B[Hello world!")); free(p); assert_se(p = strdup("\x1B[waldo")); - assert_se(strip_tab_ansi(&p, NULL)); + assert_se(strip_tab_ansi(&p, NULL, NULL)); assert_se(streq(p, "\x1B[waldo")); free(p); diff --git a/src/test/test-tmpfiles.c b/src/test/test-tmpfiles.c index c479eccb8b..8e57fe0461 100644 --- a/src/test/test-tmpfiles.c +++ b/src/test/test-tmpfiles.c @@ -29,6 +29,7 @@ #include "format-util.h" #include "fs-util.h" #include "log.h" +#include "process-util.h" #include "string-util.h" #include "util.h" diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index e24892b590..416542c83f 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -32,6 +32,7 @@ #include "manager.h" #include "path-util.h" #include "rm-rf.h" +#include "special.h" #include "specifier.h" #include "string-util.h" #include "test-helper.h" @@ -338,7 +339,7 @@ static void test_unit_name_build(void) { } static void test_slice_name_is_valid(void) { - assert_se(slice_name_is_valid("-.slice")); + assert_se(slice_name_is_valid(SPECIAL_ROOT_SLICE)); assert_se(slice_name_is_valid("foo.slice")); assert_se(slice_name_is_valid("foo-bar.slice")); assert_se(slice_name_is_valid("foo-bar-baz.slice")); @@ -356,7 +357,7 @@ static void test_build_subslice(void) { char *a; char *b; - assert_se(slice_build_subslice("-.slice", "foo", &a) >= 0); + assert_se(slice_build_subslice(SPECIAL_ROOT_SLICE, "foo", &a) >= 0); assert_se(slice_build_subslice(a, "bar", &b) >= 0); free(a); assert_se(slice_build_subslice(b, "barfoo", &a) >= 0); @@ -378,8 +379,8 @@ static void test_build_parent_slice_one(const char *name, const char *expect, in } static void test_build_parent_slice(void) { - test_build_parent_slice_one("-.slice", NULL, 0); - test_build_parent_slice_one("foo.slice", "-.slice", 1); + test_build_parent_slice_one(SPECIAL_ROOT_SLICE, NULL, 0); + test_build_parent_slice_one("foo.slice", SPECIAL_ROOT_SLICE, 1); test_build_parent_slice_one("foo-bar.slice", "foo.slice", 1); test_build_parent_slice_one("foo-bar-baz.slice", "foo-bar.slice", 1); test_build_parent_slice_one("foo-bar--baz.slice", NULL, -EINVAL); diff --git a/src/test/test-util.c b/src/test/test-util.c index 2124511bf0..21d90f0888 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -28,6 +28,7 @@ #include "fileio.h" #include "fs-util.h" #include "parse-util.h" +#include "process-util.h" #include "raw-clone.h" #include "rm-rf.h" #include "string-util.h" diff --git a/src/test/test-watch-pid.c b/src/test/test-watch-pid.c new file mode 100644 index 0000000000..ed6c3d05cc --- /dev/null +++ b/src/test/test-watch-pid.c @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "log.h" +#include "manager.h" +#include "rm-rf.h" +#include "test-helper.h" +#include "tests.h" + +int main(int argc, char *argv[]) { + _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL; + Unit *a, *b, *c, *u; + Manager *m; + int r; + + log_set_max_level(LOG_DEBUG); + log_parse_environment(); + log_open(); + + if (getuid() != 0) { + log_notice("Not running as root, skipping kernel related tests."); + return EXIT_TEST_SKIP; + } + + r = enter_cgroup_subroot(); + if (r == -ENOMEDIUM) { + log_notice("cgroupfs not available, skipping tests"); + return EXIT_TEST_SKIP; + } + + assert_se(set_unit_path(get_testdata_dir("")) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + + assert_se(manager_new(UNIT_FILE_USER, true, &m) >= 0); + assert_se(manager_startup(m, NULL, NULL) >= 0); + + assert_se(a = unit_new(m, sizeof(Service))); + assert_se(unit_add_name(a, "a.service") >= 0); + assert_se(set_isempty(a->pids)); + + assert_se(b = unit_new(m, sizeof(Service))); + assert_se(unit_add_name(b, "b.service") >= 0); + assert_se(set_isempty(b->pids)); + + assert_se(c = unit_new(m, sizeof(Service))); + assert_se(unit_add_name(c, "c.service") >= 0); + assert_se(set_isempty(c->pids)); + + assert_se(hashmap_isempty(m->watch_pids)); + assert_se(manager_get_unit_by_pid(m, 4711) == NULL); + + assert_se(unit_watch_pid(a, 4711) >= 0); + assert_se(manager_get_unit_by_pid(m, 4711) == a); + + assert_se(unit_watch_pid(a, 4711) >= 0); + assert_se(manager_get_unit_by_pid(m, 4711) == a); + + assert_se(unit_watch_pid(b, 4711) >= 0); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == b); + + assert_se(unit_watch_pid(b, 4711) >= 0); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == b); + + assert_se(unit_watch_pid(c, 4711) >= 0); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == b || u == c); + + assert_se(unit_watch_pid(c, 4711) >= 0); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == b || u == c); + + unit_unwatch_pid(b, 4711); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == c); + + unit_unwatch_pid(b, 4711); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == c); + + unit_unwatch_pid(a, 4711); + assert_se(manager_get_unit_by_pid(m, 4711) == c); + + unit_unwatch_pid(a, 4711); + assert_se(manager_get_unit_by_pid(m, 4711) == c); + + unit_unwatch_pid(c, 4711); + assert_se(manager_get_unit_by_pid(m, 4711) == NULL); + + unit_unwatch_pid(c, 4711); + assert_se(manager_get_unit_by_pid(m, 4711) == NULL); + + manager_free(m); + + return 0; +} diff --git a/src/test/test-watchdog.c b/src/test/test-watchdog.c index e068d1ddd4..ffcf408f57 100644 --- a/src/test/test-watchdog.c +++ b/src/test/test-watchdog.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <string.h> #include <unistd.h> #include "env-util.h" diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index d80a917870..19a382c1b2 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -129,8 +129,8 @@ static void print_status_info(const StatusInfo *i) { "systemd-timesyncd.service active: %s\n" " RTC in local TZ: %s\n", strna(i->timezone), have_time && n > 0 ? a : "n/a", - i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a", yes_no(i->ntp_synced), + i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a", yes_no(i->rtc_local)); if (i->rtc_local) @@ -473,7 +473,7 @@ static int timedatectl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char *argv[]) { - _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -493,6 +493,9 @@ int main(int argc, char *argv[]) { r = timedatectl_main(bus, argc, argv); finish: + /* make sure we terminate the bus connection first, and then close the + * pager, see issue #3543 for the details. */ + sd_bus_flush_close_unref(bus); pager_close(); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index a55a929a49..822835cce9 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -675,9 +675,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { if (r < 0) return log_error_errno(r, "Failed to register object: %m"); - r = sd_bus_request_name(bus, "org.freedesktop.timedate1", 0); + r = sd_bus_request_name_async(bus, NULL, "org.freedesktop.timedate1", 0, NULL, NULL); if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); + return log_error_errno(r, "Failed to request name: %m"); r = sd_bus_attach_event(bus, event, 0); if (r < 0) diff --git a/src/timesync/timesyncd-gperf.gperf b/src/timesync/timesyncd-gperf.gperf index 7d4cd2808e..b5020276af 100644 --- a/src/timesync/timesyncd-gperf.gperf +++ b/src/timesync/timesyncd-gperf.gperf @@ -10,7 +10,7 @@ struct ConfigPerfItem; %null_strings %language=ANSI-C %define slot-name section_and_lvalue -%define hash-function-name timesyncdd_gperf_hash +%define hash-function-name timesyncd_gperf_hash %define lookup-function-name timesyncd_gperf_lookup %readonly-tables %omit-struct-type diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c index 8bd111fe0c..a6d336c461 100644 --- a/src/timesync/timesyncd-manager.c +++ b/src/timesync/timesyncd-manager.c @@ -552,7 +552,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re /* check our "time cookie" (we just stored nanoseconds in the fraction field) */ if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 || - be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) { + be32toh(ntpmsg.origin_time.frac) != (unsigned long) m->trans_time.tv_nsec) { log_debug("Invalid reply; not our transmit time. Ignoring."); return 0; } diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c index 962285f7b1..bea800171b 100644 --- a/src/timesync/timesyncd.c +++ b/src/timesync/timesyncd.c @@ -66,6 +66,7 @@ static int load_clock_timestamp(uid_t uid, gid_t gid) { if (r < 0) return log_error_errno(errno, "Failed to change file access mode: %m"); r = fchown(fd, uid, gid); + if (r < 0) return log_error_errno(errno, "Failed to change file owner: %m"); } @@ -96,7 +97,7 @@ static int load_clock_timestamp(uid_t uid, gid_t gid) { int main(int argc, char *argv[]) { _cleanup_(manager_freep) Manager *m = NULL; const char *user = "systemd-timesync"; - uid_t uid; + uid_t uid, uid_current; gid_t gid; int r; @@ -113,10 +114,15 @@ int main(int argc, char *argv[]) { goto finish; } - r = get_user_creds(&user, &uid, &gid, NULL, NULL); - if (r < 0) { - log_error_errno(r, "Cannot resolve user name %s: %m", user); - goto finish; + uid = uid_current = geteuid(); + gid = getegid(); + + if (uid_current == 0) { + r = get_user_creds(&user, &uid, &gid, NULL, NULL); + if (r < 0) { + log_error_errno(r, "Cannot resolve user name %s: %m", user); + goto finish; + } } r = load_clock_timestamp(uid, gid); @@ -125,7 +131,7 @@ int main(int argc, char *argv[]) { /* Drop privileges, but only if we have been started as root. If we are not running as root we assume all * privileges are already dropped. */ - if (geteuid() == 0) { + if (uid_current == 0) { r = drop_privileges(uid, gid, (1ULL << CAP_SYS_TIME)); if (r < 0) goto finish; diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index a7ce1a8049..38cbb739c0 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -199,12 +199,12 @@ static const Specifier specifier_table[] = { static int specifier_machine_id_safe(char specifier, void *data, void *userdata, char **ret) { int r; - /* If /etc/machine_id is missing (e.g. in a chroot environment), returns - * a recognizable error so that the caller can skip the rule + /* If /etc/machine_id is missing or empty (e.g. in a chroot environment) + * return a recognizable error so that the caller can skip the rule * gracefully. */ r = specifier_machine_id(specifier, data, userdata, ret); - if (r == -ENOENT) + if (IN_SET(r, -ENOENT, -ENOMEDIUM)) return -ENXIO; return r; @@ -375,35 +375,47 @@ static struct Item* find_glob(OrderedHashmap *h, const char *match) { static void load_unix_sockets(void) { _cleanup_fclose_ FILE *f = NULL; - char line[LINE_MAX]; + int r; if (unix_sockets) return; - /* We maintain a cache of the sockets we found in - * /proc/net/unix to speed things up a little. */ + /* We maintain a cache of the sockets we found in /proc/net/unix to speed things up a little. */ unix_sockets = set_new(&string_hash_ops); if (!unix_sockets) return; f = fopen("/proc/net/unix", "re"); - if (!f) - return; + if (!f) { + log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno, + "Failed to open /proc/net/unix, ignoring: %m"); + goto fail; + } /* Skip header */ - if (!fgets(line, sizeof(line), f)) + r = read_line(f, LONG_LINE_MAX, NULL); + if (r < 0) { + log_warning_errno(r, "Failed to skip /proc/net/unix header line: %m"); + goto fail; + } + if (r == 0) { + log_warning("Premature end of file reading /proc/net/unix."); goto fail; + } for (;;) { + _cleanup_free_ char *line = NULL; char *p, *s; - int k; - if (!fgets(line, sizeof(line), f)) + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) { + log_warning_errno(r, "Failed to read /proc/net/unix line, ignoring: %m"); + goto fail; + } + if (r == 0) /* EOF */ break; - truncate_nl(line); - p = strchr(line, ':'); if (!p) continue; @@ -420,21 +432,24 @@ static void load_unix_sockets(void) { continue; s = strdup(p); - if (!s) + if (!s) { + log_oom(); goto fail; + } path_kill_slashes(s); - k = set_consume(unix_sockets, s); - if (k < 0 && k != -EEXIST) + r = set_consume(unix_sockets, s); + if (r < 0 && r != -EEXIST) { + log_warning_errno(r, "Failed to add AF_UNIX socket to set, ignoring: %m"); goto fail; + } } return; fail: - set_free_free(unix_sockets); - unix_sockets = NULL; + unix_sockets = set_free_free(unix_sockets); } static bool unix_socket_alive(const char *fn) { @@ -532,11 +547,8 @@ static int dir_cleanup( continue; /* FUSE, NFS mounts, SELinux might return EACCES */ - if (errno == EACCES) - log_debug_errno(errno, "stat(%s/%s) failed: %m", p, dent->d_name); - else - log_error_errno(errno, "stat(%s/%s) failed: %m", p, dent->d_name); - r = -errno; + r = log_full_errno(errno == EACCES ? LOG_DEBUG : LOG_ERR, errno, + "stat(%s/%s) failed: %m", p, dent->d_name); continue; } @@ -640,10 +652,8 @@ static int dir_cleanup( log_debug("Removing directory \"%s\".", sub_path); if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0) - if (!IN_SET(errno, ENOENT, ENOTEMPTY)) { - log_error_errno(errno, "rmdir(%s): %m", sub_path); - r = -errno; - } + if (!IN_SET(errno, ENOENT, ENOTEMPTY)) + r = log_error_errno(errno, "rmdir(%s): %m", sub_path); } else { /* Skip files for which the sticky bit is @@ -743,13 +753,50 @@ finish: return r; } +static bool dangerous_hardlinks(void) { + _cleanup_free_ char *value = NULL; + static int cached = -1; + int r; + + /* Check whether the fs.protected_hardlinks sysctl is on. If we can't determine it we assume its off, as that's + * what the upstream default is. */ + + if (cached >= 0) + return cached; + + r = read_one_line_file("/proc/sys/fs/protected_hardlinks", &value); + if (r < 0) { + log_debug_errno(r, "Failed to read fs.protected_hardlinks sysctl: %m"); + return true; + } + + r = parse_boolean(value); + if (r < 0) { + log_debug_errno(r, "Failed to parse fs.protected_hardlinks sysctl: %m"); + return true; + } + + cached = r == 0; + return cached; +} + +static bool hardlink_vulnerable(struct stat *st) { + assert(st); + + return !S_ISDIR(st->st_mode) && st->st_nlink > 1 && dangerous_hardlinks(); +} + static int path_set_perms(Item *i, const char *path) { + char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; _cleanup_close_ int fd = -1; struct stat st; assert(i); assert(path); + if (!i->mode_set && !i->uid_set && !i->gid_set) + goto shortcut; + /* We open the file with O_PATH here, to make the operation * somewhat atomic. Also there's unfortunately no fchmodat() * with AT_SYMLINK_NOFOLLOW, hence we emulate it here via @@ -767,21 +814,23 @@ static int path_set_perms(Item *i, const char *path) { } log_full_errno(level, errno, "Adjusting owner and mode for %s failed: %m", path); - return r; } if (fstatat(fd, "", &st, AT_EMPTY_PATH) < 0) return log_error_errno(errno, "Failed to fstat() file %s: %m", path); - if (S_ISLNK(st.st_mode)) - log_debug("Skipping mode and owner fix for symlink %s.", path); - else { - char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; - xsprintf(fn, "/proc/self/fd/%i", fd); + if (hardlink_vulnerable(&st)) { + log_error("Refusing to set permissions on hardlinked file %s while the fs.protected_hardlinks sysctl is turned off.", path); + return -EPERM; + } - /* not using i->path directly because it may be a glob */ - if (i->mode_set) { + xsprintf(fn, "/proc/self/fd/%i", fd); + + if (i->mode_set) { + if (S_ISLNK(st.st_mode)) + log_debug("Skipping mode fix for symlink %s.", path); + else { mode_t m = i->mode; if (i->mask_perms) { @@ -796,29 +845,32 @@ static int path_set_perms(Item *i, const char *path) { } if (m == (st.st_mode & 07777)) - log_debug("\"%s\" has right mode %o", path, st.st_mode); + log_debug("\"%s\" has correct mode %o already.", path, st.st_mode); else { - log_debug("chmod \"%s\" to mode %o", path, m); + log_debug("Changing \"%s\" to mode %o.", path, m); + if (chmod(fn, m) < 0) return log_error_errno(errno, "chmod() of %s via %s failed: %m", path, fn); } } + } - if ((i->uid != st.st_uid || i->gid != st.st_gid) && - (i->uid_set || i->gid_set)) { - log_debug("chown \"%s\" to "UID_FMT"."GID_FMT, - path, - i->uid_set ? i->uid : UID_INVALID, - i->gid_set ? i->gid : GID_INVALID); - if (chown(fn, - i->uid_set ? i->uid : UID_INVALID, - i->gid_set ? i->gid : GID_INVALID) < 0) - return log_error_errno(errno, "chown() of %s via %s failed: %m", path, fn); - } + if ((i->uid_set && i->uid != st.st_uid) || + (i->gid_set && i->gid != st.st_gid)) { + log_debug("Changing \"%s\" to owner "UID_FMT":"GID_FMT, + path, + i->uid_set ? i->uid : UID_INVALID, + i->gid_set ? i->gid : GID_INVALID); + + if (chown(fn, + i->uid_set ? i->uid : UID_INVALID, + i->gid_set ? i->gid : GID_INVALID) < 0) + return log_error_errno(errno, "chown() of %s via %s failed: %m", path, fn); } fd = safe_close(fd); +shortcut: return label_fix(path, false, false); } @@ -867,11 +919,8 @@ static int path_set_xattrs(Item *i, const char *path) { assert(path); STRV_FOREACH_PAIR(name, value, i->xattrs) { - int n; - - n = strlen(*value); log_debug("Setting extended attribute '%s=%s' on %s.", *name, *value, path); - if (lsetxattr(path, *name, *value, n, 0) < 0) + if (lsetxattr(path, *name, *value, strlen(*value), 0) < 0) return log_error_errno(errno, "Setting extended attribute %s=%s on %s failed: %m", *name, *value, path); } @@ -960,6 +1009,11 @@ static int path_set_acls(Item *item, const char *path) { if (fstatat(fd, "", &st, AT_EMPTY_PATH) < 0) return log_error_errno(errno, "Failed to fstat() file %s: %m", path); + if (hardlink_vulnerable(&st)) { + log_error("Refusing to set ACLs on hardlinked file %s while the fs.protected_hardlinks sysctl is turned off.", path); + return -EPERM; + } + if (S_ISLNK(st.st_mode)) { log_debug("Skipping ACL fix for symlink %s.", path); return 0; @@ -1135,7 +1189,7 @@ static int write_one_file(Item *i, const char *path) { assert(i); assert(path); - flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND|O_NOFOLLOW : + flags = i->type == CREATE_FILE ? O_CREAT|O_EXCL|O_NOFOLLOW : i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC|O_NOFOLLOW : 0; RUN_WITH_UMASK(0000) { @@ -1146,9 +1200,13 @@ static int write_one_file(Item *i, const char *path) { if (fd < 0) { if (i->type == WRITE_FILE && errno == ENOENT) { - log_debug_errno(errno, "Not writing \"%s\": %m", path); + log_debug_errno(errno, "Not writing missing file \"%s\": %m", path); return 0; } + if (i->type == CREATE_FILE && errno == EEXIST) { + log_debug_errno(errno, "Not writing to pre-existing file \"%s\": %m", path); + goto done; + } r = -errno; if (!i->argument && errno == EROFS && stat(path, &st) == 0 && @@ -1169,6 +1227,7 @@ static int write_one_file(Item *i, const char *path) { fd = safe_close(fd); +done: if (stat(path, &st) < 0) return log_error_errno(errno, "stat(%s) failed: %m", path); @@ -1289,14 +1348,24 @@ static int create_item(Item *i) { case CREATE_FILE: case TRUNCATE_FILE: + RUN_WITH_UMASK(0000) + (void) mkdir_parents_label(i->path, 0755); + r = write_one_file(i, i->path); if (r < 0) return r; break; case COPY_FILES: { + + RUN_WITH_UMASK(0000) + (void) mkdir_parents_label(i->path, 0755); + log_debug("Copying tree \"%s\" to \"%s\".", i->argument, i->path); - r = copy_tree(i->argument, i->path, i->uid_set ? i->uid : UID_INVALID, i->gid_set ? i->gid : GID_INVALID, COPY_REFLINK); + r = copy_tree(i->argument, i->path, + i->uid_set ? i->uid : UID_INVALID, + i->gid_set ? i->gid : GID_INVALID, + COPY_REFLINK); if (r == -EROFS && stat(i->path, &st) == 0) r = -EEXIST; @@ -1338,7 +1407,7 @@ static int create_item(Item *i) { case CREATE_SUBVOLUME_INHERIT_QUOTA: case CREATE_SUBVOLUME_NEW_QUOTA: RUN_WITH_UMASK(0000) - mkdir_parents_label(i->path, 0755); + (void) mkdir_parents_label(i->path, 0755); if (IN_SET(i->type, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) { @@ -1420,6 +1489,8 @@ static int create_item(Item *i) { case CREATE_FIFO: RUN_WITH_UMASK(0000) { + (void) mkdir_parents_label(i->path, 0755); + mac_selinux_create_file_prepare(i->path, S_IFIFO); r = mkfifo(i->path, i->mode); mac_selinux_create_file_clear(); @@ -1462,6 +1533,9 @@ static int create_item(Item *i) { } case CREATE_SYMLINK: { + RUN_WITH_UMASK(0000) + (void) mkdir_parents_label(i->path, 0755); + mac_selinux_create_file_prepare(i->path, S_IFLNK); r = symlink(i->argument, i->path); mac_selinux_create_file_clear(); @@ -1520,6 +1594,9 @@ static int create_item(Item *i) { return 0; } + RUN_WITH_UMASK(0000) + (void) mkdir_parents_label(i->path, 0755); + file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR; RUN_WITH_UMASK(0000) { @@ -2254,6 +2331,9 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool } } else { existing = new0(ItemArray, 1); + if (!existing) + return log_oom(); + r = ordered_hashmap_put(h, i.path, existing); if (r < 0) return log_oom(); @@ -2514,7 +2594,7 @@ int main(int argc, char *argv[]) { } } - { + if (DEBUG_LOGGING) { _cleanup_free_ char *t = NULL; t = strv_join(config_dirs, "\n\t"); diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c index 1553655a28..9dfb0d80de 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -159,7 +159,7 @@ static int ask_password_plymouth( } if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0) - flush_fd(notify); + (void) flush_fd(notify); if (pollfd[POLL_SOCKET].revents == 0) continue; @@ -417,8 +417,8 @@ static int wall_tty_block(void) { if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0) return log_oom(); - mkdir_parents_label(p, 0700); - mkfifo(p, 0600); + (void) mkdir_parents_label(p, 0700); + (void) mkfifo(p, 0600); fd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); if (fd < 0) @@ -693,11 +693,13 @@ static int parse_argv(int argc, char *argv[]) { * If one of the tasks does handle a password, the remaining tasks * will be terminated. */ -static int ask_on_this_console(const char *tty, pid_t *pid, int argc, char *argv[]) { +static int ask_on_this_console(const char *tty, pid_t *ret_pid, int argc, char *argv[]) { struct sigaction sig = { .sa_handler = nop_signal_handler, .sa_flags = SA_NOCLDSTOP | SA_RESTART, }; + pid_t pid; + int r; assert_se(sigprocmask_many(SIG_UNBLOCK, NULL, SIGHUP, SIGCHLD, -1) >= 0); @@ -707,18 +709,14 @@ static int ask_on_this_console(const char *tty, pid_t *pid, int argc, char *argv sig.sa_handler = SIG_DFL; assert_se(sigaction(SIGHUP, &sig, NULL) >= 0); - *pid = fork(); - if (*pid < 0) - return log_error_errno(errno, "Failed to fork process: %m"); - - if (*pid == 0) { + r = safe_fork("(sd-passwd)", FORK_RESET_SIGNALS|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { int ac; assert_se(prctl(PR_SET_PDEATHSIG, SIGHUP) >= 0); - reset_signal_mask(); - reset_all_signal_handlers(); - for (ac = 0; ac < argc; ac++) { if (streq(argv[ac], "--console")) { argv[ac] = strjoina("--console=", tty); @@ -731,6 +729,8 @@ static int ask_on_this_console(const char *tty, pid_t *pid, int argc, char *argv execv(SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, argv); _exit(EXIT_FAILURE); } + + *ret_pid = pid; return 0; } diff --git a/src/udev/generate-keyboard-keys-gperf.sh b/src/udev/generate-keyboard-keys-gperf.sh index eb977447e3..efb0da2a84 100755 --- a/src/udev/generate-keyboard-keys-gperf.sh +++ b/src/udev/generate-keyboard-keys-gperf.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu awk ' BEGIN { print "%{\n\ #if __GNUC__ >= 7\n\ diff --git a/src/udev/generate-keyboard-keys-list.sh b/src/udev/generate-keyboard-keys-list.sh index 7a74e0dae1..c055f7c756 100755 --- a/src/udev/generate-keyboard-keys-list.sh +++ b/src/udev/generate-keyboard-keys-list.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu $1 -dM -include linux/input.h - </dev/null | awk ' /\<(KEY_(MAX|MIN_INTERESTING))|(BTN_(MISC|MOUSE|JOYSTICK|GAMEPAD|DIGI|WHEEL|TRIGGER_HAPPY))\>/ { next } diff --git a/src/udev/meson.build b/src/udev/meson.build index d01cf8f194..de2fd2d9c4 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -113,15 +113,36 @@ if get_option('link-udev-shared') udev_rpath = rootlibexecdir else udev_link_with = [libshared_static, - libsystemd_internal] + libsystemd_static] udev_rpath = '' endif -libudev_internal = static_library( - 'udev', +libudev_basic = static_library( + 'udev-basic', libudev_sources, include_directories : includes, - link_with : udev_link_with) + c_args : ['-fvisibility=default']) + +libudev_static = static_library( + 'udev', + 'udev.h', + include_directories : includes, + link_with : udev_link_with, + link_whole : libudev_basic) + +libudev = shared_library( + 'udev', + 'udev.h', # pick a header file at random to work around old meson bug + version : libudev_version, + include_directories : includes, + link_args : ['-shared', + '-Wl,--version-script=' + libudev_sym_path], + link_with : [libsystemd_static, libshared_static], + link_whole : libudev_basic, + dependencies : [threads], + link_depends : libudev_sym, + install : true, + install_dir : rootlibdir) libudev_core_includes = [includes, include_directories('net')] libudev_core = static_library( @@ -130,6 +151,7 @@ libudev_core = static_library( link_config_gperf_c, keyboard_keys_from_name_h, include_directories : libudev_core_includes, + c_args : ['-DLOG_REALM=LOG_REALM_UDEV'], link_with : udev_link_with, dependencies : [libblkid, libkmod]) @@ -149,7 +171,7 @@ foreach prog : [['ata_id/ata_id.c'], prog, include_directories : includes, c_args : ['-DLOG_REALM=LOG_REALM_UDEV'], - link_with : [libudev_internal], + link_with : [libudev_static], install_rpath : udev_rpath, install : true, install_dir : udevlibexecdir) diff --git a/src/udev/mtd_probe/probe_smartmedia.c b/src/udev/mtd_probe/probe_smartmedia.c index eb74fe1eb6..5d58de6a87 100644 --- a/src/udev/mtd_probe/probe_smartmedia.c +++ b/src/udev/mtd_probe/probe_smartmedia.c @@ -28,6 +28,7 @@ #include <sys/types.h> #include <unistd.h> +#include "alloc-util.h" #include "mtd_probe.h" static const uint8_t cis_signature[] = { @@ -35,16 +36,16 @@ static const uint8_t cis_signature[] = { }; -void probe_smart_media(int mtd_fd, mtd_info_t* info) -{ +void probe_smart_media(int mtd_fd, mtd_info_t* info) { int sector_size; int block_size; int size_in_megs; int spare_count; - char* cis_buffer = malloc(SM_SECTOR_SIZE); + _cleanup_free_ uint8_t *cis_buffer = NULL; int offset; int cis_found = 0; + cis_buffer = malloc(SM_SECTOR_SIZE); if (!cis_buffer) return; @@ -89,9 +90,8 @@ void probe_smart_media(int mtd_fd, mtd_info_t* info) goto exit; printf("MTD_FTL=smartmedia\n"); - free(cis_buffer); - exit(0); + exit(EXIT_SUCCESS); + exit: - free(cis_buffer); return; } diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c index 3ed8a51fd4..9bdaef8d90 100644 --- a/src/udev/net/ethtool-util.c +++ b/src/udev/net/ethtool-util.c @@ -25,13 +25,13 @@ #include "conf-parser.h" #include "ethtool-util.h" -#include "log.h" #include "link-config.h" +#include "log.h" +#include "missing.h" #include "socket-util.h" #include "string-table.h" #include "strxcpyx.h" #include "util.h" -#include "missing.h" static const char* const duplex_table[_DUP_MAX] = { [DUP_FULL] = "full", @@ -83,6 +83,7 @@ int ethtool_connect(int *ret) { fd = socket_ioctl_fd(); if (fd < 0) return fd; + *ret = fd; return 0; @@ -265,7 +266,7 @@ int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol) { return 0; } -static int ethtool_get_stringset(int *fd, struct ifreq *ifr, int stringset_id, struct ethtool_gstrings **gstrings) { +static int get_stringset(int fd, struct ifreq *ifr, int stringset_id, struct ethtool_gstrings **gstrings) { _cleanup_free_ struct ethtool_gstrings *strings = NULL; struct { struct ethtool_sset_info info; @@ -281,7 +282,7 @@ static int ethtool_get_stringset(int *fd, struct ifreq *ifr, int stringset_id, s ifr->ifr_data = (void *) &buffer.info; - r = ioctl(*fd, SIOCETHTOOL, ifr); + r = ioctl(fd, SIOCETHTOOL, ifr); if (r < 0) return -errno; @@ -300,7 +301,7 @@ static int ethtool_get_stringset(int *fd, struct ifreq *ifr, int stringset_id, s ifr->ifr_data = (void *) strings; - r = ioctl(*fd, SIOCETHTOOL, ifr); + r = ioctl(fd, SIOCETHTOOL, ifr); if (r < 0) return -errno; @@ -335,7 +336,7 @@ int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features) { strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - r = ethtool_get_stringset(fd, &ifr, ETH_SS_FEATURES, &strings); + r = get_stringset(*fd, &ifr, ETH_SS_FEATURES, &strings); if (r < 0) return log_warning_errno(r, "link_config: could not get ethtool features for %s", ifname); @@ -374,7 +375,7 @@ int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features) { return 0; } -static int get_glinksettings(int *fd, struct ifreq *ifr, struct ethtool_link_usettings **g) { +static int get_glinksettings(int fd, struct ifreq *ifr, struct ethtool_link_usettings **g) { struct ecmd { struct ethtool_link_settings req; __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32]; @@ -395,29 +396,29 @@ static int get_glinksettings(int *fd, struct ifreq *ifr, struct ethtool_link_use ifr->ifr_data = (void *) &ecmd; - r = ioctl(*fd, SIOCETHTOOL, ifr); + r = ioctl(fd, SIOCETHTOOL, ifr); if (r < 0) return -errno; if (ecmd.req.link_mode_masks_nwords >= 0 || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) - return -ENOTSUP; + return -EOPNOTSUPP; ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords; ifr->ifr_data = (void *) &ecmd; - r = ioctl(*fd, SIOCETHTOOL, ifr); + r = ioctl(fd, SIOCETHTOOL, ifr); if (r < 0) return -errno; if (ecmd.req.link_mode_masks_nwords <= 0 || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) - return -ENOTSUP; + return -EOPNOTSUPP; u = new0(struct ethtool_link_usettings , 1); if (!u) return -ENOMEM; - memcpy(&u->base, &ecmd.req, sizeof(struct ethtool_link_settings)); + ecmd.req = u->base; offset = 0; memcpy(u->link_modes.supported, &ecmd.link_mode_data[offset], 4 * ecmd.req.link_mode_masks_nwords); @@ -433,7 +434,7 @@ static int get_glinksettings(int *fd, struct ifreq *ifr, struct ethtool_link_use return 0; } -static int get_gset(int *fd, struct ifreq *ifr, struct ethtool_link_usettings **u) { +static int get_gset(int fd, struct ifreq *ifr, struct ethtool_link_usettings **u) { struct ethtool_link_usettings *e; struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, @@ -442,7 +443,7 @@ static int get_gset(int *fd, struct ifreq *ifr, struct ethtool_link_usettings ** ifr->ifr_data = (void *) &ecmd; - r = ioctl(*fd, SIOCETHTOOL, ifr); + r = ioctl(fd, SIOCETHTOOL, ifr); if (r < 0) return -errno; @@ -469,19 +470,19 @@ static int get_gset(int *fd, struct ifreq *ifr, struct ethtool_link_usettings ** return 0; } -static int set_slinksettings(int *fd, struct ifreq *ifr, const struct ethtool_link_usettings *u) { +static int set_slinksettings(int fd, struct ifreq *ifr, const struct ethtool_link_usettings *u) { struct { struct ethtool_link_settings req; __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32]; - } ecmd = { - .req.cmd = ETHTOOL_SLINKSETTINGS, - }; + } ecmd = {}; unsigned int offset; int r; if (u->base.cmd != ETHTOOL_GLINKSETTINGS || u->base.link_mode_masks_nwords <= 0) return -EINVAL; + ecmd.req = u->base; + ecmd.req.cmd = ETHTOOL_SLINKSETTINGS; offset = 0; memcpy(&ecmd.link_mode_data[offset], u->link_modes.supported, 4 * ecmd.req.link_mode_masks_nwords); @@ -493,14 +494,14 @@ static int set_slinksettings(int *fd, struct ifreq *ifr, const struct ethtool_li ifr->ifr_data = (void *) &ecmd; - r = ioctl(*fd, SIOCETHTOOL, ifr); + r = ioctl(fd, SIOCETHTOOL, ifr); if (r < 0) return -errno; return 0; } -static int set_sset(int *fd, struct ifreq *ifr, const struct ethtool_link_usettings *u) { +static int set_sset(int fd, struct ifreq *ifr, const struct ethtool_link_usettings *u) { struct ethtool_cmd ecmd = { .cmd = ETHTOOL_SSET, }; @@ -523,7 +524,7 @@ static int set_sset(int *fd, struct ifreq *ifr, const struct ethtool_link_usetti ifr->ifr_data = (void *) &ecmd; - r = ioctl(*fd, SIOCETHTOOL, ifr); + r = ioctl(fd, SIOCETHTOOL, ifr); if (r < 0) return -errno; @@ -555,10 +556,9 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *l strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - r = get_glinksettings(fd, &ifr, &u); + r = get_glinksettings(*fd, &ifr, &u); if (r < 0) { - - r = get_gset(fd, &ifr, &u); + r = get_gset(*fd, &ifr, &u); if (r < 0) return log_warning_errno(r, "link_config: Cannot get device settings for %s : %m", ifname); } @@ -570,15 +570,14 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *l u->base.duplex = link->duplex; if (link->port != _NET_DEV_PORT_INVALID) - u->base.port = link->port; + u->base.port = link->port; u->base.autoneg = link->autonegotiation; if (u->base.cmd == ETHTOOL_GLINKSETTINGS) - r = set_slinksettings(fd, &ifr, u); + r = set_slinksettings(*fd, &ifr, u); else - r = set_sset(fd, &ifr, u); - + r = set_sset(*fd, &ifr, u); if (r < 0) return log_warning_errno(r, "link_config: Cannot set device settings for %s : %m", ifname); diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf index 85f0a0625b..5cb126d870 100644 --- a/src/udev/net/link-config-gperf.gperf +++ b/src/udev/net/link-config-gperf.gperf @@ -26,7 +26,8 @@ Match.Driver, config_parse_strv, 0, Match.Type, config_parse_strv, 0, offsetof(link_config, match_type) Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, match_host) Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, match_virt) -Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel) +Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel_cmdline) +Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(link_config, match_kernel_version) Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, match_arch) Link.Description, config_parse_string, 0, offsetof(link_config, description) Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy) diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 89891f9e27..a4368f088d 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -77,7 +77,8 @@ static void link_config_free(link_config *link) { free(link->match_name); free(link->match_host); free(link->match_virt); - free(link->match_kernel); + free(link->match_kernel_cmdline); + free(link->match_kernel_version); free(link->match_arch); free(link->description); @@ -171,7 +172,7 @@ static int load_link(link_config_ctx *ctx, const char *filename) { link->port = _NET_DEV_PORT_INVALID; link->autonegotiation = -1; - memset(&link->features, -1, sizeof(link->features)); + memset(&link->features, 0xFF, sizeof(link->features)); r = config_parse(NULL, filename, file, "Match\0Link\0Ethernet\0", @@ -186,6 +187,8 @@ static int load_link(link_config_ctx *ctx, const char *filename) { return -ERANGE; link->filename = strdup(filename); + if (!link->filename) + return log_oom(); LIST_PREPEND(links, ctx->links, link); link = NULL; @@ -246,7 +249,8 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device, if (net_match_config(link->match_mac, link->match_path, link->match_driver, link->match_type, link->match_name, link->match_host, - link->match_virt, link->match_kernel, link->match_arch, + link->match_virt, link->match_kernel_cmdline, + link->match_kernel_version, link->match_arch, attr_value ? ether_aton(attr_value) : NULL, udev_device_get_property_value(device, "ID_PATH"), udev_device_get_driver(udev_device_get_parent(device)), diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index a413251bd0..dabc3eff8f 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -58,7 +58,8 @@ struct link_config { char **match_name; Condition *match_host; Condition *match_virt; - Condition *match_kernel; + Condition *match_kernel_cmdline; + Condition *match_kernel_version; Condition *match_arch; char *description; diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c index ab4ee7b00b..32c1a8def4 100644 --- a/src/udev/scsi_id/scsi_id.c +++ b/src/udev/scsi_id/scsi_id.c @@ -358,7 +358,7 @@ static int set_options(struct udev *udev, case 'h': help(); - exit(0); + exit(EXIT_SUCCESS); case 'p': if (streq(optarg, "0x80")) @@ -393,7 +393,7 @@ static int set_options(struct udev *udev, case 'V': printf("%s\n", PACKAGE_VERSION); - exit(0); + exit(EXIT_SUCCESS); case 'x': export = true; @@ -608,7 +608,7 @@ int main(int argc, char **argv) * Get command line options (overriding any config file settings). */ if (set_options(udev, argc, argv, maj_min_dev) < 0) - exit(1); + exit(EXIT_FAILURE); if (!dev_specified) { log_error("No device specified."); diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c index b13fdb135b..fa830213ff 100644 --- a/src/udev/udev-builtin-input_id.c +++ b/src/udev/udev-builtin-input_id.c @@ -102,8 +102,7 @@ static void get_cap_mask(struct udev_device *dev, unsigned long val; v = udev_device_get_sysattr_value(pdev, attr); - if (!v) - v = ""; + v = strempty(v); xsprintf(text, "%s", v); log_debug("%s raw kernel attribute: %s", attr, text); diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index f3be27fdd0..945585d82a 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -547,7 +547,7 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) { * verify each bus-ID part... */ bus_id_len = strlen(bus_id); - if (!bus_id_len || bus_id_len < 8 || bus_id_len > 9) + if (!IN_SET(bus_id_len, 8, 9)) return -EINVAL; /* Strip leading zeros from the bus id for aesthetic purposes. This diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 8f7c28f03d..d0befba29c 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -774,10 +774,10 @@ int udev_event_spawn(struct udev_event *event, } } - pid = fork(); - switch(pid) { - case 0: - { + err = safe_fork("(spawn)", FORK_RESET_SIGNALS|FORK_LOG, &pid); + if (err < 0) + goto out; + if (err == 0) { char arg[UTIL_PATH_SIZE]; char *argv[128]; char program[UTIL_PATH_SIZE]; @@ -802,23 +802,18 @@ int udev_event_spawn(struct udev_event *event, _exit(2); } - case -1: - log_error_errno(errno, "fork of '%s' failed: %m", cmd); - err = -1; - goto out; - default: - /* parent closed child's ends of pipes */ - outpipe[WRITE_END] = safe_close(outpipe[WRITE_END]); - errpipe[WRITE_END] = safe_close(errpipe[WRITE_END]); - spawn_read(event, - timeout_usec, - cmd, - outpipe[READ_END], errpipe[READ_END], - result, ressize); + /* parent closed child's ends of pipes */ + outpipe[WRITE_END] = safe_close(outpipe[WRITE_END]); + errpipe[WRITE_END] = safe_close(errpipe[WRITE_END]); - err = spawn_wait(event, timeout_usec, timeout_warn_usec, cmd, pid, accept_failure); - } + spawn_read(event, + timeout_usec, + cmd, + outpipe[READ_END], errpipe[READ_END], + result, ressize); + + err = spawn_wait(event, timeout_usec, timeout_warn_usec, cmd, pid, accept_failure); out: if (outpipe[READ_END] >= 0) diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c index d80d61583d..9546a6ebaf 100644 --- a/src/udev/udevadm-control.c +++ b/src/udev/udevadm-control.c @@ -21,6 +21,7 @@ #include <string.h> #include <unistd.h> +#include "process-util.h" #include "time-util.h" #include "udev-util.h" #include "udev.h" diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 1644935ff9..5c757d513f 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -1700,9 +1700,9 @@ int main(int argc, char *argv[]) { goto exit; } - r = mkdir("/run/udev", 0755); - if (r < 0 && errno != EEXIST) { - r = log_error_errno(errno, "could not create /run/udev: %m"); + r = mkdir_errno_wrapper("/run/udev", 0755); + if (r < 0 && r != -EEXIST) { + log_error_errno(r, "could not create /run/udev: %m"); goto exit; } diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index e19a1637bf..2e0e09d843 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -133,6 +133,7 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m const char *args[8]; unsigned i = 0; pid_t pid; + int r; /* An empty map means kernel map */ if (isempty(map)) @@ -152,19 +153,15 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m log_debug("Executing \"%s\"...", strnull((cmd = strv_join((char**) args, " ")))); - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - else if (pid == 0) { - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - + r = safe_fork("(loadkeys)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { execv(args[0], (char **) args); _exit(EXIT_FAILURE); } - return wait_for_terminate_and_warn(KBD_LOADKEYS, pid, true); + return wait_for_terminate_and_check(KBD_LOADKEYS, pid, WAIT_LOG); } static int font_load_and_wait(const char *vc, const char *font, const char *map, const char *unimap) { @@ -172,6 +169,7 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map, const char *args[9]; unsigned i = 0; pid_t pid; + int r; /* Any part can be set independently */ if (isempty(font) && isempty(map) && isempty(unimap)) @@ -195,19 +193,15 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map, log_debug("Executing \"%s\"...", strnull((cmd = strv_join((char**) args, " ")))); - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - else if (pid == 0) { - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - + r = safe_fork("(setfont)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { execv(args[0], (char **) args); _exit(EXIT_FAILURE); } - return wait_for_terminate_and_warn(KBD_SETFONT, pid, true); + return wait_for_terminate_and_check(KBD_SETFONT, pid, WAIT_LOG); } /* @@ -458,8 +452,8 @@ int main(int argc, char **argv) { log_warning_errno(r, "Failed to read /proc/cmdline: %m"); } - toggle_utf8_sysfs(utf8); - toggle_utf8(vc, fd, utf8); + (void) toggle_utf8_sysfs(utf8); + (void) toggle_utf8(vc, fd, utf8); r = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap); keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) == 0; diff --git a/src/veritysetup/veritysetup-generator.c b/src/veritysetup/veritysetup-generator.c index 5919b1380e..d09f295392 100644 --- a/src/veritysetup/veritysetup-generator.c +++ b/src/veritysetup/veritysetup-generator.c @@ -18,6 +18,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <stdbool.h> #include <stdlib.h> #include <sys/stat.h> @@ -27,6 +28,7 @@ #include "fd-util.h" #include "fileio.h" #include "fstab-util.h" +#include "generator.h" #include "hexdecoct.h" #include "id128-util.h" #include "mkdir.h" @@ -36,6 +38,8 @@ #include "string-util.h" #include "unit-name.h" +#define SYSTEMD_VERITYSETUP_SERVICE "systemd-veritysetup@root.service" + static char *arg_dest = NULL; static bool arg_enabled = true; static char *arg_root_hash = NULL; @@ -45,7 +49,7 @@ static char *arg_hash_what = NULL; static int create_device(void) { _cleanup_free_ char *u = NULL, *v = NULL, *d = NULL, *e = NULL, *u_escaped = NULL, *v_escaped = NULL, *root_hash_escaped = NULL; _cleanup_fclose_ FILE *f = NULL; - const char *p, *to; + const char *to; int r; /* If all three pieces of information are missing, then verity is turned off */ @@ -67,8 +71,6 @@ static int create_device(void) { " hash device %s,\n" " and root hash %s.", arg_data_what, arg_hash_what, arg_root_hash); - p = strjoina(arg_dest, "/systemd-veritysetup@root.service"); - u = fstab_node_to_udev_node(arg_data_what); if (!u) return log_oom(); @@ -94,12 +96,11 @@ static int create_device(void) { if (!root_hash_escaped) return log_oom(); - f = fopen(p, "wxe"); - if (!f) - return log_error_errno(errno, "Failed to create unit file %s: %m", p); + r = generator_open_unit_file(arg_dest, NULL, SYSTEMD_VERITYSETUP_SERVICE, &f); + if (r < 0) + return r; fprintf(f, - "# Automatically generated by systemd-veritysetup-generator\n\n" "[Unit]\n" "Description=Integrity Protection Setup for %%I\n" "Documentation=man:systemd-veritysetup-generator(8) man:systemd-veritysetup@.service(8)\n" @@ -121,12 +122,12 @@ static int create_device(void) { r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write file %s: %m", p); + return log_error_errno(r, "Failed to write file unit "SYSTEMD_VERITYSETUP_SERVICE": %m"); - to = strjoina(arg_dest, "/cryptsetup.target.requires/systemd-veritysetup@root.service"); + to = strjoina(arg_dest, "/cryptsetup.target.requires/" SYSTEMD_VERITYSETUP_SERVICE); (void) mkdir_parents(to, 0755); - if (symlink("../systemd-veritysetup@root.service", to) < 0) + if (symlink("../" SYSTEMD_VERITYSETUP_SERVICE, to) < 0) return log_error_errno(errno, "Failed to create symlink %s: %m", to); return 0; @@ -227,7 +228,8 @@ int main(int argc, char *argv[]) { if (argc > 1) arg_dest = argv[1]; - log_set_target(LOG_TARGET_SAFE); + log_set_prohibit_ipc(true); + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); diff --git a/src/veritysetup/veritysetup.c b/src/veritysetup/veritysetup.c index d3066ca429..3b4e72bf9e 100644 --- a/src/veritysetup/veritysetup.c +++ b/src/veritysetup/veritysetup.c @@ -18,14 +18,15 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <stdio.h> #include <sys/stat.h> +#include "alloc-util.h" #include "crypt-util.h" -#include "log.h" #include "hexdecoct.h" +#include "log.h" #include "string-util.h" -#include "alloc-util.h" static char *arg_root_hash = NULL; static char *arg_data_what = NULL; diff --git a/test/TEST-01-BASIC/Makefile b/test/TEST-01-BASIC/Makefile index 3a212a07a9..34d7cc6cdf 100644 --- a/test/TEST-01-BASIC/Makefile +++ b/test/TEST-01-BASIC/Makefile @@ -1,4 +1,4 @@ -BUILD_DIR=$(exec ../../tools/find-build-dir.sh) +BUILD_DIR=$(shell ../../tools/find-build-dir.sh) all setup clean run: @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ diff --git a/test/TEST-13-NSPAWN-SMOKE/Makefile b/test/TEST-13-NSPAWN-SMOKE/Makefile index ddcbbc302f..7d74b1343a 100644 --- a/test/TEST-13-NSPAWN-SMOKE/Makefile +++ b/test/TEST-13-NSPAWN-SMOKE/Makefile @@ -1,4 +1,4 @@ -BUILD_DIR=$(exec ../../tools/find-build-dir.sh) +BUILD_DIR=$(shell ../../tools/find-build-dir.sh) all setup run: @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh index 239c7e0731..6a0cb42eaf 100755 --- a/test/TEST-13-NSPAWN-SMOKE/test.sh +++ b/test/TEST-13-NSPAWN-SMOKE/test.sh @@ -147,7 +147,7 @@ function run { # test --network-namespace-path works with a network namespace created by "ip netns" ip netns add nspawn_test _netns_opt="--network-namespace-path=/run/netns/nspawn_test" - UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" ip a | grep -E '^1: lo.*DOWN' + UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" /bin/ip a | grep -v -E '^1: lo.*UP' local r=$? ip netns del nspawn_test diff --git a/test/TEST-17-UDEV-WANTS/Makefile b/test/TEST-17-UDEV-WANTS/Makefile index 3a212a07a9..34d7cc6cdf 100644 --- a/test/TEST-17-UDEV-WANTS/Makefile +++ b/test/TEST-17-UDEV-WANTS/Makefile @@ -1,4 +1,4 @@ -BUILD_DIR=$(exec ../../tools/find-build-dir.sh) +BUILD_DIR=$(shell ../../tools/find-build-dir.sh) all setup clean run: @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ diff --git a/test/TEST-18-FAILUREACTION/Makefile b/test/TEST-18-FAILUREACTION/Makefile index 3a212a07a9..34d7cc6cdf 100644 --- a/test/TEST-18-FAILUREACTION/Makefile +++ b/test/TEST-18-FAILUREACTION/Makefile @@ -1,4 +1,4 @@ -BUILD_DIR=$(exec ../../tools/find-build-dir.sh) +BUILD_DIR=$(shell ../../tools/find-build-dir.sh) all setup clean run: @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ diff --git a/test/TEST-19-DELEGATE/Makefile b/test/TEST-19-DELEGATE/Makefile index 3a212a07a9..34d7cc6cdf 100644 --- a/test/TEST-19-DELEGATE/Makefile +++ b/test/TEST-19-DELEGATE/Makefile @@ -1,4 +1,4 @@ -BUILD_DIR=$(exec ../../tools/find-build-dir.sh) +BUILD_DIR=$(shell ../../tools/find-build-dir.sh) all setup clean run: @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ diff --git a/test/TEST-20-MAINPIDGAMES/Makefile b/test/TEST-20-MAINPIDGAMES/Makefile new file mode 100644 index 0000000000..34d7cc6cdf --- /dev/null +++ b/test/TEST-20-MAINPIDGAMES/Makefile @@ -0,0 +1,4 @@ +BUILD_DIR=$(shell ../../tools/find-build-dir.sh) + +all setup clean run: + @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ diff --git a/test/TEST-20-MAINPIDGAMES/test.sh b/test/TEST-20-MAINPIDGAMES/test.sh new file mode 100755 index 0000000000..b14083a256 --- /dev/null +++ b/test/TEST-20-MAINPIDGAMES/test.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +set -e +TEST_DESCRIPTION="test changing main PID" + +. $TEST_BASE_DIR/test-functions + +test_setup() { + create_empty_image + mkdir -p $TESTDIR/root + mount ${LOOPDEV}p1 $TESTDIR/root + + ( + LOG_LEVEL=5 + eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) + + setup_basic_environment + + # setup the testsuite service + cat >$initdir/etc/systemd/system/testsuite.service <<EOF +[Unit] +Description=Testsuite service + +[Service] +ExecStart=/bin/bash -x /testsuite.sh +Type=oneshot +StandardOutput=tty +StandardError=tty +NotifyAccess=all +EOF + cp testsuite.sh $initdir/ + + setup_testsuite + ) || return 1 + setup_nspawn_root + + ddebug "umount $TESTDIR/root" + umount $TESTDIR/root +} + +do_test "$@" diff --git a/test/TEST-20-MAINPIDGAMES/testsuite.sh b/test/TEST-20-MAINPIDGAMES/testsuite.sh new file mode 100755 index 0000000000..0e1a116b07 --- /dev/null +++ b/test/TEST-20-MAINPIDGAMES/testsuite.sh @@ -0,0 +1,141 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +set -ex +set -o pipefail + +systemd-analyze set-log-level debug +systemd-analyze set-log-target console + +test `systemctl show -p MainPID --value testsuite.service` -eq $$ + +# Start a test process inside of our own cgroup +sleep infinity & +INTERNALPID=$! +disown + +# Start a test process outside of our own cgroup +systemd-run -p DynamicUser=1 --unit=sleep.service /bin/sleep infinity +EXTERNALPID=`systemctl show -p MainPID --value sleep.service` + +# Update our own main PID to the external test PID, this should work +systemd-notify MAINPID=$EXTERNALPID +test `systemctl show -p MainPID --value testsuite.service` -eq $EXTERNALPID + +# Update our own main PID to the internal test PID, this should work, too +systemd-notify MAINPID=$INTERNALPID +test `systemctl show -p MainPID --value testsuite.service` -eq $INTERNALPID + +# Update it back to our own PID, this should also work +systemd-notify MAINPID=$$ +test `systemctl show -p MainPID --value testsuite.service` -eq $$ + +# Try to set it to PID 1, which it should ignore, because that's the manager +systemd-notify MAINPID=1 +test `systemctl show -p MainPID --value testsuite.service` -eq $$ + +# Try to set it to PID 0, which is invalid and should be ignored +systemd-notify MAINPID=0 +test `systemctl show -p MainPID --value testsuite.service` -eq $$ + +# Try to set it to a valid but non-existing PID, which should be ignored. (Note +# that we set the PID to a value well above any known /proc/sys/kernel/pid_max, +# which means we can be pretty sure it doesn't exist by coincidence) +systemd-notify MAINPID=1073741824 +test `systemctl show -p MainPID --value testsuite.service` -eq $$ + +# Change it again to the external PID, without priviliges this time. This should be ignored, because the PID is from outside of our cgroup and we lack privileges. +systemd-notify --uid=1000 MAINPID=$EXTERNALPID +test `systemctl show -p MainPID --value testsuite.service` -eq $$ + +# Change it again to the internal PID, without priviliges this time. This should work, as the process is on our cgroup, and that's enough even if we lack privileges. +systemd-notify --uid=1000 MAINPID=$INTERNALPID +test `systemctl show -p MainPID --value testsuite.service` -eq $INTERNALPID + +# Update it back to our own PID, this should also work +systemd-notify --uid=1000 MAINPID=$$ +test `systemctl show -p MainPID --value testsuite.service` -eq $$ + +cat >/tmp/mainpid.sh <<EOF +#!/bin/bash + +set -eux +set -o pipefail + +# Create a number of children, and make one the main one +sleep infinity & +disown + +sleep infinity & +MAINPID=\$! +disown + +sleep infinity & +disown + +echo \$MAINPID > /run/mainpidsh/pid +EOF +chmod +x /tmp/mainpid.sh + +systemd-run --unit=mainpidsh.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh -p PIDFile=/run/mainpidsh/pid /tmp/mainpid.sh +test `systemctl show -p MainPID --value mainpidsh.service` -eq `cat /run/mainpidsh/pid` + +cat >/tmp/mainpid2.sh <<EOF +#!/bin/bash + +set -eux +set -o pipefail + +# Create a number of children, and make one the main one +sleep infinity & +disown + +sleep infinity & +MAINPID=\$! +disown + +sleep infinity & +disown + +echo \$MAINPID > /run/mainpidsh2/pid +chown 1001:1001 /run/mainpidsh2/pid +EOF +chmod +x /tmp/mainpid2.sh + +systemd-run --unit=mainpidsh2.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh2 -p PIDFile=/run/mainpidsh2/pid /tmp/mainpid2.sh +test `systemctl show -p MainPID --value mainpidsh2.service` -eq `cat /run/mainpidsh2/pid` + +cat >/dev/shm/mainpid3.sh <<EOF +#!/bin/bash + +set -eux +set -o pipefail + +sleep infinity & +disown + +sleep infinity & +disown + +sleep infinity & +disown + +# Let's try to play games, and link up a privileged PID file +ln -s ../mainpidsh/pid /run/mainpidsh3/pid + +# Quick assertion that the link isn't dead +test -f /run/mainpidsh3/pid +EOF +chmod 755 /dev/shm/mainpid3.sh + +# This has to fail, as we shouldn't accept the dangerous PID file, and then inotify-wait on it to be corrected which we never do +! systemd-run --unit=mainpidsh3.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh3 -p PIDFile=/run/mainpidsh3/pid -p DynamicUser=1 -p TimeoutStartSec=2s /dev/shm/mainpid3.sh + +# Test that this failed due to timeout, and not some other error +test `systemctl show -p Result --value mainpidsh3.service` = timeout + +systemd-analyze set-log-level info + +echo OK > /testok + +exit 0 diff --git a/test/TEST-21-SYSUSERS/Makefile b/test/TEST-21-SYSUSERS/Makefile new file mode 100644 index 0000000000..34d7cc6cdf --- /dev/null +++ b/test/TEST-21-SYSUSERS/Makefile @@ -0,0 +1,4 @@ +BUILD_DIR=$(shell ../../tools/find-build-dir.sh) + +all setup clean run: + @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ diff --git a/test/TEST-21-SYSUSERS/test-1.expected-group b/test/TEST-21-SYSUSERS/test-1.expected-group new file mode 100644 index 0000000000..cc9093f807 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-1.expected-group @@ -0,0 +1,2 @@ +g1:x:111: +u1:x:222: diff --git a/test/TEST-21-SYSUSERS/test-1.expected-passwd b/test/TEST-21-SYSUSERS/test-1.expected-passwd new file mode 100644 index 0000000000..8d0bfff319 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-1.expected-passwd @@ -0,0 +1 @@ +u1:x:222:222::/:/sbin/nologin diff --git a/test/TEST-21-SYSUSERS/test-1.input b/test/TEST-21-SYSUSERS/test-1.input new file mode 100644 index 0000000000..bffc2cd7ea --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-1.input @@ -0,0 +1,3 @@ +#Type Name ID GECOS HOMEDIR +u u1 222 - - +g g1 111 - - diff --git a/test/TEST-21-SYSUSERS/test-2.expected-group b/test/TEST-21-SYSUSERS/test-2.expected-group new file mode 100644 index 0000000000..f98e85fcf4 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-2.expected-group @@ -0,0 +1 @@ +u1:x:999: diff --git a/test/TEST-21-SYSUSERS/test-2.expected-passwd b/test/TEST-21-SYSUSERS/test-2.expected-passwd new file mode 100644 index 0000000000..d907e483f7 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-2.expected-passwd @@ -0,0 +1 @@ +u1:x:999:999:some gecos:/random/dir:/sbin/nologin diff --git a/test/TEST-21-SYSUSERS/test-2.input b/test/TEST-21-SYSUSERS/test-2.input new file mode 100644 index 0000000000..d8f31347a1 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-2.input @@ -0,0 +1,2 @@ +#Type Name ID GECOS HOMEDIR +u u1 - "some gecos" /random/dir diff --git a/test/TEST-21-SYSUSERS/test-3.expected-group b/test/TEST-21-SYSUSERS/test-3.expected-group new file mode 100644 index 0000000000..c3a63285c6 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-3.expected-group @@ -0,0 +1,4 @@ +hoge:x:300: +baz:x:302: +foo:x:301: +ccc:x:305: diff --git a/test/TEST-21-SYSUSERS/test-3.expected-passwd b/test/TEST-21-SYSUSERS/test-3.expected-passwd new file mode 100644 index 0000000000..a86954f8b3 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-3.expected-passwd @@ -0,0 +1,4 @@ +foo:x:301:301::/:/sbin/nologin +aaa:x:303:302::/:/sbin/nologin +bbb:x:304:302::/:/sbin/nologin +ccc:x:305:305::/:/sbin/nologin diff --git a/test/TEST-21-SYSUSERS/test-3.input b/test/TEST-21-SYSUSERS/test-3.input new file mode 100644 index 0000000000..b4f86a69f1 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-3.input @@ -0,0 +1,7 @@ +g hoge 300 - - +u foo 301 - - + +g baz 302 - - +u aaa 303:302 - - +u bbb 304:302 - - +u ccc 305 - - diff --git a/test/TEST-21-SYSUSERS/test-4.expected-group b/test/TEST-21-SYSUSERS/test-4.expected-group new file mode 100644 index 0000000000..64913a5f50 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-4.expected-group @@ -0,0 +1 @@ +xxx:x:310: diff --git a/test/TEST-21-SYSUSERS/test-4.expected-passwd b/test/TEST-21-SYSUSERS/test-4.expected-passwd new file mode 100644 index 0000000000..e0370a4023 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-4.expected-passwd @@ -0,0 +1,2 @@ +yyy:x:311:310::/:/sbin/nologin +xxx:x:312:310::/:/sbin/nologin diff --git a/test/TEST-21-SYSUSERS/test-4.input b/test/TEST-21-SYSUSERS/test-4.input new file mode 100644 index 0000000000..620423eab4 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test-4.input @@ -0,0 +1,3 @@ +g xxx 310 +u yyy 311:310 +u xxx 312:310 diff --git a/test/TEST-21-SYSUSERS/test.sh b/test/TEST-21-SYSUSERS/test.sh new file mode 100755 index 0000000000..14f2b4ae07 --- /dev/null +++ b/test/TEST-21-SYSUSERS/test.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +set -e +TEST_DESCRIPTION="Sysuser-related tests" + +. $TEST_BASE_DIR/test-functions + +test_setup() { + mkdir -p $TESTDIR/etc $TESTDIR/usr/lib/sysusers.d $TESTDIR/tmp +} + +test_run() { + # ensure our build of systemd-sysusers is run + PATH=${BUILD_DIR}:$PATH + + # happy tests + for f in test-*.input; do + echo "*** Running $f" + rm -f $TESTDIR/etc/* + cp $f $TESTDIR/usr/lib/sysusers.d/test.conf + systemd-sysusers --root=$TESTDIR + + if ! diff -u $TESTDIR/etc/passwd ${f%.*}.expected-passwd; then + echo "**** Unexpected output for $f" + exit 1 + fi + if ! diff -u $TESTDIR/etc/group ${f%.*}.expected-group; then + echo "**** Unexpected output for $f" + exit 1 + fi + done + + # tests for error conditions + for f in unhappy-*.input; do + echo "*** Running test $f" + rm -f $TESTDIR/etc/* + cp $f $TESTDIR/usr/lib/sysusers.d/test.conf + systemd-sysusers --root=$TESTDIR 2> /dev/null + journalctl -t systemd-sysusers -o cat | tail -n1 > $TESTDIR/tmp/err + if ! diff -u $TESTDIR/tmp/err ${f%.*}.expected-err; then + echo "**** Unexpected error output for $f" + cat $TESTDIR/tmp/err + exit 1 + fi + done +} + +do_test "$@" diff --git a/test/TEST-21-SYSUSERS/unhappy-1.expected-err b/test/TEST-21-SYSUSERS/unhappy-1.expected-err new file mode 100644 index 0000000000..d3342402e9 --- /dev/null +++ b/test/TEST-21-SYSUSERS/unhappy-1.expected-err @@ -0,0 +1 @@ +Failed to parse UID: '9999999999': Numerical result out of range diff --git a/test/TEST-21-SYSUSERS/unhappy-1.input b/test/TEST-21-SYSUSERS/unhappy-1.input new file mode 100644 index 0000000000..77390371de --- /dev/null +++ b/test/TEST-21-SYSUSERS/unhappy-1.input @@ -0,0 +1 @@ +u u1 9999999999 - -
\ No newline at end of file diff --git a/test/TEST-21-SYSUSERS/unhappy-2.expected-err b/test/TEST-21-SYSUSERS/unhappy-2.expected-err new file mode 100644 index 0000000000..5db5c20214 --- /dev/null +++ b/test/TEST-21-SYSUSERS/unhappy-2.expected-err @@ -0,0 +1 @@ +Failed to create u1: please create GID 100 diff --git a/test/TEST-21-SYSUSERS/unhappy-2.input b/test/TEST-21-SYSUSERS/unhappy-2.input new file mode 100644 index 0000000000..521c741cb5 --- /dev/null +++ b/test/TEST-21-SYSUSERS/unhappy-2.input @@ -0,0 +1,2 @@ +# it is not allowed to create groups implicitely in the uid:gid syntax +u u1 100:100 -
\ No newline at end of file diff --git a/test/fuzz-corpus/dhcp-server/discover-existing b/test/fuzz-corpus/dhcp-server/discover-existing Binary files differnew file mode 100644 index 0000000000..1e26bf09e2 --- /dev/null +++ b/test/fuzz-corpus/dhcp-server/discover-existing diff --git a/test/fuzz-corpus/dhcp-server/discover-new b/test/fuzz-corpus/dhcp-server/discover-new Binary files differnew file mode 100644 index 0000000000..feeae55e5e --- /dev/null +++ b/test/fuzz-corpus/dhcp-server/discover-new diff --git a/test/fuzz-corpus/dhcp-server/release b/test/fuzz-corpus/dhcp-server/release Binary files differnew file mode 100644 index 0000000000..4f3eadb2f2 --- /dev/null +++ b/test/fuzz-corpus/dhcp-server/release diff --git a/test/fuzz-corpus/dhcp-server/request-existing b/test/fuzz-corpus/dhcp-server/request-existing Binary files differnew file mode 100644 index 0000000000..9f7a0d88f7 --- /dev/null +++ b/test/fuzz-corpus/dhcp-server/request-existing diff --git a/test/fuzz-corpus/dhcp-server/request-new b/test/fuzz-corpus/dhcp-server/request-new Binary files differnew file mode 100644 index 0000000000..fc6f5864a7 --- /dev/null +++ b/test/fuzz-corpus/dhcp-server/request-new diff --git a/test/fuzz-corpus/dhcp-server/request-reboot b/test/fuzz-corpus/dhcp-server/request-reboot Binary files differnew file mode 100644 index 0000000000..fde74b2b91 --- /dev/null +++ b/test/fuzz-corpus/dhcp-server/request-reboot diff --git a/test/fuzz-corpus/dhcp-server/request-renew b/test/fuzz-corpus/dhcp-server/request-renew Binary files differnew file mode 100644 index 0000000000..8dcda2ad88 --- /dev/null +++ b/test/fuzz-corpus/dhcp-server/request-renew diff --git a/test/fuzz-regressions/address/fuzz-dns-packet/issue-7888 b/test/fuzz-regressions/address/fuzz-dns-packet/issue-7888 Binary files differnew file mode 100644 index 0000000000..19e7eedf51 --- /dev/null +++ b/test/fuzz-regressions/address/fuzz-dns-packet/issue-7888 diff --git a/test/fuzz-regressions/address/fuzz-dns-packet/oss-fuzz-5465 b/test/fuzz-regressions/address/fuzz-dns-packet/oss-fuzz-5465 Binary files differnew file mode 100644 index 0000000000..ccd8a4fd6b --- /dev/null +++ b/test/fuzz-regressions/address/fuzz-dns-packet/oss-fuzz-5465 diff --git a/test/fuzz-regressions/meson.build b/test/fuzz-regressions/meson.build new file mode 100644 index 0000000000..de69c941ea --- /dev/null +++ b/test/fuzz-regressions/meson.build @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# Copyright 2018 Zbigniew Jędrzejewski-Szmek +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see <http://www.gnu.org/licenses/>. + +sanitize_address = custom_target( + 'sanitize-address-fuzzers', + output : 'sanitize-address-fuzzers', + command : [meson_build_sh, + meson.source_root(), + '@OUTPUT@', + 'fuzzers', + '-Db_lundef=false -Db_sanitize=address']) + +fuzz_regression_tests = ''' + address/fuzz-dns-packet/oss-fuzz-5465 + address/fuzz-dns-packet/issue-7888 +'''.split() diff --git a/test/meson.build b/test/meson.build index 5c533f4833..4667628b24 100644 --- a/test/meson.build +++ b/test/meson.build @@ -228,3 +228,5 @@ if conf.get('ENABLE_HWDB') == 1 hwdb_test_sh, timeout : 90) endif + +subdir('fuzz-regressions') diff --git a/test/networkd-test.py b/test/networkd-test.py index 3918d85ef0..860c9f1898 100755 --- a/test/networkd-test.py +++ b/test/networkd-test.py @@ -720,7 +720,8 @@ class NetworkdClientTest(ClientTestBase, unittest.TestCase): self.addCleanup(os.remove, script) with os.fdopen(fd, 'w+') as f: f.write('''\ -#!/bin/sh -eu +#!/bin/sh +set -eu mkdir -p /run/systemd/network mkdir -p /run/systemd/netif mount -t tmpfs none /run/systemd/network diff --git a/test/test-functions b/test/test-functions index a2f82725d1..018bdca888 100644 --- a/test/test-functions +++ b/test/test-functions @@ -21,7 +21,7 @@ if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then ROOTLIBDIR=/usr/lib/systemd fi -BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false" +BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln" DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" diff --git a/test/udev-test.pl b/test/udev-test.pl index 0d348e5c08..20f662eb3b 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # udev test # diff --git a/tools/add-git-hook.sh b/tools/add-git-hook.sh index 4ee919faf4..c1db99b18a 100755 --- a/tools/add-git-hook.sh +++ b/tools/add-git-hook.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu cd "$MESON_SOURCE_ROOT" diff --git a/tools/check-includes.pl b/tools/check-includes.pl index bf23929d47..6aae7c1534 100755 --- a/tools/check-includes.pl +++ b/tools/check-includes.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # # checkincludes: Find files included more than once in (other) files. # Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>. diff --git a/tools/find-build-dir.sh b/tools/find-build-dir.sh index 33b40f93f7..06b6297ea5 100755 --- a/tools/find-build-dir.sh +++ b/tools/find-build-dir.sh @@ -1,4 +1,5 @@ -#!/bin/sh -e +#!/bin/sh +set -e # Try to guess the build directory: # we look for subdirectories of the parent directory that look like ninja build dirs. diff --git a/tools/gdb-sd_dump_hashmaps.py b/tools/gdb-sd_dump_hashmaps.py index b3c356b579..7f5d31eca6 100644 --- a/tools/gdb-sd_dump_hashmaps.py +++ b/tools/gdb-sd_dump_hashmaps.py @@ -51,7 +51,7 @@ class sd_dump_hashmaps(gdb.Command): t = ["plain", "ordered", "set"][int(h["type"])] - print "%s, %s, %s, %d, %d, %d, %s (%s:%d)" % (t, h["hash_ops"], bool(h["has_indirect"]), n_entries, d["max_entries"], n_buckets, d["func"], d["file"], d["line"]) + print "{}, {}, {}, {}, {}, {}, {} ({}:{})".format(t, h["hash_ops"], bool(h["has_indirect"]), n_entries, d["max_entries"], n_buckets, d["func"], d["file"], d["line"]) if arg != "" and n_entries > 0: dib_raw_addr = storage_ptr + (all_entry_sizes[h["type"]] * n_buckets) @@ -63,10 +63,10 @@ class sd_dump_hashmaps(gdb.Command): for dib in sorted(iter(histogram)): if dib != 255: - print "%3d %8d %f%% of entries" % (dib, histogram[dib], 100.0*histogram[dib]/n_entries) + print "{:>3} {:>8} {} of entries".format(dib, histogram[dib], 100.0*histogram[dib]/n_entries) else: - print "%3d %8d %f%% of slots" % (dib, histogram[dib], 100.0*histogram[dib]/n_buckets) - print "mean DIB of entries: %f" % (sum([dib*histogram[dib] for dib in iter(histogram) if dib != 255])*1.0/n_entries) + print "{:>3} {:>8} {} of slots".format(dib, histogram[dib], 100.0*histogram[dib]/n_buckets) + print "mean DIB of entries: {}".format(sum([dib*histogram[dib] for dib in iter(histogram) if dib != 255])*1.0/n_entries) blocks = [] current_len = 1 @@ -87,9 +87,9 @@ class sd_dump_hashmaps(gdb.Command): if len(blocks) > 1 and blocks[0][0] == blocks[0][1] and blocks[-1][0] == n_buckets - 1: blocks[0][1] += blocks[-1][1] blocks = blocks[0:-1] - print "max block: %s" % max(blocks, key=lambda a: a[1]) - print "sum block lens: %d" % sum(b[1] for b in blocks) - print "mean block len: %f" % (1.0 * sum(b[1] for b in blocks) / len(blocks)) + print "max block: {}".format(max(blocks, key=lambda a: a[1])) + print "sum block lens: {}".format(sum(b[1] for b in blocks)) + print "mean block len: {}".format((1.0 * sum(b[1] for b in blocks) / len(blocks))) d = d["debug_list_next"] diff --git a/tools/meson-build.sh b/tools/meson-build.sh new file mode 100755 index 0000000000..302749d8ed --- /dev/null +++ b/tools/meson-build.sh @@ -0,0 +1,10 @@ +#!/bin/sh +set -eux + +src="$1" +dst="$2" +target="$3" +options="$4" + +[ -d "$dst" ] || meson "$src" "$dst" $options +ninja -C "$dst" "$target" diff --git a/tools/meson-check-api-docs.sh b/tools/meson-check-api-docs.sh new file mode 100755 index 0000000000..5bc808c1e4 --- /dev/null +++ b/tools/meson-check-api-docs.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -eu + +for symbol in `nm -g --defined-only "$@" | grep " T " | cut -d" " -f3 | sort -u` ; do + if test -f ${MESON_BUILD_ROOT}/man/$symbol.3 ; then + echo "✓ Symbol $symbol() is documented." + else + printf " \x1b[1;31mSymbol $symbol() lacks documentation.\x1b[0m\n" + fi +done diff --git a/tools/meson-check-compilation.sh b/tools/meson-check-compilation.sh index d3b2a312fd..ce39e1684b 100755 --- a/tools/meson-check-compilation.sh +++ b/tools/meson-check-compilation.sh @@ -1,3 +1,4 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu "$@" '-' -o/dev/null </dev/null diff --git a/tools/meson-check-help.sh b/tools/meson-check-help.sh index 4210491a98..69157105f2 100755 --- a/tools/meson-check-help.sh +++ b/tools/meson-check-help.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu export SYSTEMD_LOG_LEVEL=info diff --git a/tools/meson-git-contrib.sh b/tools/meson-git-contrib.sh index c543b3a5fa..514daa0949 100755 --- a/tools/meson-git-contrib.sh +++ b/tools/meson-git-contrib.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu git shortlog -s `git describe --abbrev=0`.. | \ cut -c8- | \ diff --git a/tools/meson-hwdb-update.sh b/tools/meson-hwdb-update.sh index e9a78c647f..275d54cd17 100755 --- a/tools/meson-hwdb-update.sh +++ b/tools/meson-hwdb-update.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu cd "$1" diff --git a/tools/meson-make-symlink.sh b/tools/meson-make-symlink.sh index 47a5e70ae5..501cd43d47 100755 --- a/tools/meson-make-symlink.sh +++ b/tools/meson-make-symlink.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu # this is needed mostly because $DESTDIR is provided as a variable, # and we need to create the target directory... diff --git a/travis-ci/.dockerignore b/travis-ci/.dockerignore new file mode 100644 index 0000000000..039215886d --- /dev/null +++ b/travis-ci/.dockerignore @@ -0,0 +1,30 @@ +*.a +*.cache +*.gch +*.log +*.o +*.plist +*.py[co] +*.stamp +*.swp +*.trs +*~ +.config.args +.deps/ +/*.gcda +/*.gcno +/GPATH +/GRTAGS +/GSYMS +/GTAGS +/TAGS +/ID +/build* +/coverage/ +/install-tree +/mkosi.builddir/ +/tags +image.raw +image.raw.cache-pre-dev +image.raw.cache-pre-inst +__pycache__/ diff --git a/travis-ci/Dockerfile b/travis-ci/Dockerfile new file mode 100644 index 0000000000..9554fcfc21 --- /dev/null +++ b/travis-ci/Dockerfile @@ -0,0 +1,38 @@ +## Create Dockerfile that builds container suitable for systemd build +## This container runs as non-root user by deafult + +# Use the latest stable version of fedora +FROM fedora:latest + +# Demand the specification of non-root username +ARG DOCKER_USER +ARG DOCKER_USER_UID +ARG DOCKER_USER_GID + +# Copy the requirements into the container at /tmp +COPY requirements.txt /tmp/ + +# Install the requirements +# RUN dnf -y update FIXME +RUN dnf -y install $(cat '/tmp/requirements.txt') +# clean step to prevent cache and metadata corruption +RUN dnf clean all +RUN dnf -y builddep systemd + +# Add non-root user and chown the project dir +RUN groupadd -g $DOCKER_USER_GID $DOCKER_USER +RUN useradd --create-home --shell /bin/bash -u $DOCKER_USER_UID -g $DOCKER_USER_GID -G wheel $DOCKER_USER +ENV HOME /home/$DOCKER_USER +ENV PROJECTDIR $HOME/systemd + +# Copy content to the project directory +COPY . $PROJECTDIR + +# Greant user all permissions to the project dir +RUN chown -R $DOCKER_USER $PROJECTDIR + +# Switch to noroot user by default +USER $DOCKER_USER + +# Update workdir to user home dir +WORKDIR $PROJECTDIR diff --git a/travis-ci/requirements.txt b/travis-ci/requirements.txt new file mode 100644 index 0000000000..f2dbae4b38 --- /dev/null +++ b/travis-ci/requirements.txt @@ -0,0 +1,3 @@ +dnf-plugins-core +meson +ninja-build diff --git a/travis-ci/scripts/build-docker-image.sh b/travis-ci/scripts/build-docker-image.sh new file mode 100755 index 0000000000..5d4333a95b --- /dev/null +++ b/travis-ci/scripts/build-docker-image.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Check environment +[ -z "$DOCKER_REPOSITORY" ] && echo "ERROR: DOCKER_REPOSITORY must be set" && exit 1 +[ -z "$TRAVIS_COMMIT" ] && echo "ERROR: TRAVIS_COMMIT must be set" && exit 1 + +# Build docker image +echo -e "\n\033[33;1mBuilding docker image: $DOCKER_REPOSITORY:$TRAVIS_COMMIT.\033[0m" + +docker build \ +--build-arg DOCKER_USER=$USER \ +--build-arg DOCKER_USER_UID=`id -u` \ +--build-arg DOCKER_USER_GID=`id -g` \ +--force-rm -t ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} --pull=true . diff --git a/travis-ci/tools/get-coverity.sh b/travis-ci/tools/get-coverity.sh new file mode 100755 index 0000000000..d364b541e2 --- /dev/null +++ b/travis-ci/tools/get-coverity.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# Download and extract coverity tool + +# Environment check +[ -z "$COVERITY_SCAN_TOKEN" ] && echo 'ERROR: COVERITY_SCAN_TOKEN must be set' && exit 1 + +# Use default values if not set +PLATFORM=$(uname) + +TOOL_BASE=${TOOL_BASE:="/tmp/coverity-scan-analysis"} +TOOL_ARCHIVE=${TOOL_ARCHIVE:="/tmp/cov-analysis-${PLATFORM}.tgz"} + +TOOL_URL="https://scan.coverity.com/download/${PLATFORM}" + +# Make sure wget is installed +sudo apt-get update && sudo apt-get -y install wget + +# Get coverity tool +if [ ! -d $TOOL_BASE ]; then + # Download Coverity Scan Analysis Tool + if [ ! -e $TOOL_ARCHIVE ]; then + echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m" + wget -nv -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN" + fi + + # Extract Coverity Scan Analysis Tool + echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m" + mkdir -p $TOOL_BASE + pushd $TOOL_BASE + tar xzf $TOOL_ARCHIVE + popd +fi + +echo -e "\033[33;1mCoverity Scan Analysis Tool can be found at $TOOL_BASE ...\033[0m" diff --git a/travis-ci/tools/get-docker-remote.sh b/travis-ci/tools/get-docker-remote.sh new file mode 100755 index 0000000000..55bc29e7b1 --- /dev/null +++ b/travis-ci/tools/get-docker-remote.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Download and install docker-remote +# Sets up venv folder +# Notes: run with sudo command + +# Make sure python3 is installed and install git and virtual environment +sudo apt-get update && sudo apt-get -y install python3 python3-pip git +sudo apt-get install -y $(apt-cache search venv | cut -d' ' -f 1) + +# Get the tool from github and install it +git clone https://github.com/CermakM/docker-remote.git + +# We need to setup virtual environment here to solve disable_warning issue +python3 -m venv venv +source venv/bin/activate + +pushd docker-remote +pip install . +popd diff --git a/units/debug-shell.service.in b/units/debug-shell.service.in index 2d48faa105..1127e68b63 100644 --- a/units/debug-shell.service.in +++ b/units/debug-shell.service.in @@ -10,6 +10,7 @@ [Unit] Description=Early root shell on @DEBUGTTY@ FOR DEBUGGING ONLY Documentation=man:sushell(8) +Documentation=man:systemd-debug-generator(8) DefaultDependencies=no IgnoreOnIsolate=yes ConditionPathExists=@DEBUGTTY@ diff --git a/units/meson-add-wants.sh b/units/meson-add-wants.sh index dfd287e172..70f7172ae9 100755 --- a/units/meson-add-wants.sh +++ b/units/meson-add-wants.sh @@ -1,4 +1,5 @@ -#!/bin/sh -eu +#!/bin/sh +set -eu unitdir="$1" target="$2" diff --git a/units/rc-local.service.in b/units/rc-local.service.in index 5dbd62aecb..78ce69e0ae 100644 --- a/units/rc-local.service.in +++ b/units/rc-local.service.in @@ -11,6 +11,7 @@ # systemd-rc-local-generator if @RC_LOCAL_SCRIPT_PATH_START@ is executable. [Unit] Description=@RC_LOCAL_SCRIPT_PATH_START@ Compatibility +Documentation=man:systemd-rc-local-generator(8) ConditionFileIsExecutable=@RC_LOCAL_SCRIPT_PATH_START@ After=network.target diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in index 8059aa7b62..c4c7f1feef 100644 --- a/units/systemd-resolved.service.in +++ b/units/systemd-resolved.service.in @@ -13,8 +13,10 @@ Documentation=man:systemd-resolved.service(8) Documentation=https://www.freedesktop.org/wiki/Software/systemd/resolved Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients -After=systemd-networkd.service network.target -Before=network-online.target nss-lookup.target +DefaultDependencies=no +After=systemd-sysusers.service systemd-networkd.service +Before=network.target nss-lookup.target shutdown.target +Conflicts=shutdown.target Wants=nss-lookup.target [Service] diff --git a/xorg/50-systemd-user.sh b/xorg/50-systemd-user.sh index 4d49767228..5588185c50 100755 --- a/xorg/50-systemd-user.sh +++ b/xorg/50-systemd-user.sh @@ -2,6 +2,6 @@ systemctl --user import-environment DISPLAY XAUTHORITY -if which dbus-update-activation-environment >/dev/null 2>&1; then +if command -v dbus-update-activation-environment >/dev/null 2>&1; then dbus-update-activation-environment DISPLAY XAUTHORITY fi |